@tempad-dev/mcp 0.3.1 → 0.3.3
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 +2 -2
- package/dist/cli.js +32 -1
- package/dist/cli.js.map +3 -3
- package/dist/hub.js +66 -46
- package/dist/hub.js.map +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"mcpServers": {
|
|
8
8
|
"TemPad Dev": {
|
|
9
9
|
"command": "npx",
|
|
10
|
-
"args": ["@tempad-dev/mcp"]
|
|
10
|
+
"args": ["-y", "@tempad-dev/mcp@latest"]
|
|
11
11
|
}
|
|
12
12
|
}
|
|
13
13
|
}
|
|
@@ -17,7 +17,7 @@ Quick setup helpers:
|
|
|
17
17
|
|
|
18
18
|
- VS Code / Cursor / TRAE: use the deep links in TemPad Dev (Preferences → MCP server).
|
|
19
19
|
- Windsurf: copy the JSON snippet from the same panel.
|
|
20
|
-
- CLI: `claude mcp add --transport stdio "TemPad Dev" -- npx -y @tempad-dev/mcp` or `codex mcp add "TemPad Dev" -- npx -y @tempad-dev/mcp`.
|
|
20
|
+
- CLI: `claude mcp add --transport stdio "TemPad Dev" -- npx -y @tempad-dev/mcp@latest` or `codex mcp add "TemPad Dev" -- npx -y @tempad-dev/mcp@latest`.
|
|
21
21
|
|
|
22
22
|
Supported tools/resources:
|
|
23
23
|
|
package/dist/cli.js
CHANGED
|
@@ -12,9 +12,40 @@ import { closeSync, mkdirSync, openSync } from "node:fs";
|
|
|
12
12
|
import { tmpdir } from "node:os";
|
|
13
13
|
import { join } from "node:path";
|
|
14
14
|
import pino from "pino";
|
|
15
|
+
|
|
16
|
+
// package.json
|
|
17
|
+
var package_default = {
|
|
18
|
+
name: "@tempad-dev/mcp",
|
|
19
|
+
description: "MCP server for TemPad Dev.",
|
|
20
|
+
version: "0.3.3",
|
|
21
|
+
type: "module",
|
|
22
|
+
main: "dist/cli.js",
|
|
23
|
+
bin: "dist/cli.js",
|
|
24
|
+
files: [
|
|
25
|
+
"dist/**/*",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
28
|
+
scripts: {
|
|
29
|
+
build: "tsc -p ./tsconfig.json --noEmit && node ./scripts/build.mjs",
|
|
30
|
+
prepublishOnly: "npm run build"
|
|
31
|
+
},
|
|
32
|
+
dependencies: {
|
|
33
|
+
"@modelcontextprotocol/sdk": "^1.22.0",
|
|
34
|
+
nanoid: "^5.1.6",
|
|
35
|
+
pino: "^9.14.0",
|
|
36
|
+
"pino-pretty": "^11.2.2",
|
|
37
|
+
"proper-lockfile": "^4.1.2",
|
|
38
|
+
ws: "^8.18.3",
|
|
39
|
+
zod: "^4.1.12"
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// src/shared.ts
|
|
15
44
|
function ensureDir(dirPath) {
|
|
16
45
|
mkdirSync(dirPath, { recursive: true, mode: 448 });
|
|
17
46
|
}
|
|
47
|
+
var pkg = package_default;
|
|
48
|
+
var PACKAGE_VERSION = typeof pkg.version === "string" ? pkg.version : "0.0.0";
|
|
18
49
|
function resolveRuntimeDir() {
|
|
19
50
|
if (process.env.TEMPAD_MCP_RUNTIME_DIR) return process.env.TEMPAD_MCP_RUNTIME_DIR;
|
|
20
51
|
return join(tmpdir(), "tempad-dev", "run");
|
|
@@ -183,7 +214,7 @@ async function tryBecomeLeaderAndStartHub() {
|
|
|
183
214
|
}
|
|
184
215
|
}
|
|
185
216
|
async function main() {
|
|
186
|
-
log.info("TemPad MCP Client starting...");
|
|
217
|
+
log.info({ version: PACKAGE_VERSION }, "TemPad MCP Client starting...");
|
|
187
218
|
while (true) {
|
|
188
219
|
try {
|
|
189
220
|
const socket = await connectHub().catch(() => {
|
package/dist/cli.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/cli.ts", "../src/shared.ts"],
|
|
4
|
-
"sourcesContent": ["#!/usr/bin/env node\n\nimport type { ChildProcess } from 'node:child_process'\nimport type { Socket } from 'node:net'\n\nimport { spawn } from 'node:child_process'\nimport { connect } from 'node:net'\nimport { join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport lockfile from 'proper-lockfile'\n\nimport { log, LOCK_PATH, RUNTIME_DIR, SOCK_PATH, ensureDir } from './shared'\n\nlet activeSocket: Socket | null = null\nlet shuttingDown = false\n\nfunction closeActiveSocket() {\n if (!activeSocket) return\n try {\n activeSocket.end()\n } catch {\n // ignore\n }\n try {\n activeSocket.destroy()\n } catch {\n // ignore\n }\n activeSocket = null\n}\n\nfunction shutdownCli(reason: string) {\n if (shuttingDown) return\n shuttingDown = true\n log.info(`${reason} Shutting down CLI.`)\n closeActiveSocket()\n process.exit(0)\n}\n\nprocess.on('SIGINT', () => shutdownCli('SIGINT received.'))\nprocess.on('SIGTERM', () => shutdownCli('SIGTERM received.'))\n\nconst HUB_STARTUP_TIMEOUT = 5000\nconst CONNECT_RETRY_DELAY = 200\nconst FAILED_RESTART_DELAY = 5000\nconst HERE = fileURLToPath(new URL('.', import.meta.url))\nconst HUB_ENTRY = join(HERE, 'hub.js')\n\nensureDir(RUNTIME_DIR)\n\nfunction bridge(socket: Socket): Promise<void> {\n return new Promise((resolve) => {\n log.info('Bridge established with Hub. Forwarding I/O.')\n activeSocket = socket\n\n const onStdinEnd = () => {\n shutdownCli('Consumer stream ended.')\n }\n process.stdin.once('end', onStdinEnd)\n\n const onSocketClose = () => {\n log.warn('Connection to Hub lost. Attempting to reconnect...')\n activeSocket = null\n process.stdin.removeListener('end', onStdinEnd)\n process.stdin.unpipe(socket)\n socket.unpipe(process.stdout)\n socket.removeAllListeners()\n resolve()\n }\n socket.once('close', onSocketClose)\n socket.on('error', (err) => log.warn({ err }, 'Socket error occurred.'))\n\n // The `{ end: false }` option prevents stdin from closing the socket.\n process.stdin.pipe(socket, { end: false }).pipe(process.stdout)\n })\n}\n\nfunction connectHub(): Promise<Socket> {\n return new Promise((resolve, reject) => {\n const socket = connect(SOCK_PATH)\n socket.on('connect', () => {\n socket.removeAllListeners('error')\n resolve(socket)\n })\n socket.on('error', reject)\n })\n}\n\nasync function connectWithRetry(timeout: number): Promise<Socket> {\n const startTime = Date.now()\n let delay = CONNECT_RETRY_DELAY\n while (Date.now() - startTime < timeout) {\n try {\n return await connectHub()\n } catch (err: unknown) {\n if (\n err &&\n typeof err === 'object' &&\n 'code' in err &&\n (err.code === 'ENOENT' || err.code === 'ECONNREFUSED')\n ) {\n const remainingTime = timeout - (Date.now() - startTime)\n const waitTime = Math.min(delay, remainingTime)\n if (waitTime <= 0) break\n await new Promise((r) => setTimeout(r, waitTime))\n delay = Math.min(delay * 1.5, 1000)\n } else {\n throw err\n }\n }\n }\n throw new Error(`Failed to connect to Hub within ${timeout}ms.`)\n}\n\nfunction startHub(): ChildProcess {\n log.info('Spawning new Hub process...')\n return spawn(process.execPath, [HUB_ENTRY], {\n detached: true,\n stdio: 'ignore'\n })\n}\n\nasync function tryBecomeLeaderAndStartHub(): Promise<Socket> {\n let releaseLock: (() => Promise<void>) | null = null\n try {\n releaseLock = await lockfile.lock(LOCK_PATH, {\n retries: { retries: 5, factor: 1.2, minTimeout: 50 },\n stale: 15000\n })\n } catch {\n log.info('Another process is starting the Hub. Waiting...')\n return connectWithRetry(HUB_STARTUP_TIMEOUT)\n }\n\n log.info('Acquired lock. Starting Hub as the leader...')\n let child: ChildProcess | null = null\n try {\n try {\n return await connectHub()\n } catch {\n // If the Hub is not running, we proceed to start it.\n log.info('Hub not running. Proceeding to start it...')\n }\n child = startHub()\n child.on('error', (err) => log.error({ err }, 'Hub child process error.'))\n const socket = await connectWithRetry(HUB_STARTUP_TIMEOUT)\n child.unref()\n return socket\n } catch (err: unknown) {\n log.error({ err }, 'Failed to start or connect to the Hub.')\n if (child && !child.killed) {\n log.warn(`Killing stale Hub process (PID: ${child.pid})...`)\n child.kill('SIGTERM')\n }\n throw err\n } finally {\n if (releaseLock) await releaseLock()\n }\n}\n\nasync function main() {\n log.info('TemPad MCP Client starting...')\n\n while (true) {\n try {\n const socket = await connectHub().catch(() => {\n log.info('Hub not running. Initiating startup sequence...')\n return tryBecomeLeaderAndStartHub()\n })\n await bridge(socket)\n log.info('Bridge disconnected. Restarting connection process...')\n } catch (err: unknown) {\n log.error(\n { err },\n `Connection attempt failed. Retrying in ${FAILED_RESTART_DELAY / 1000}s...`\n )\n await new Promise((r) => setTimeout(r, FAILED_RESTART_DELAY))\n }\n }\n}\n\nmain()\n", "import { closeSync, mkdirSync, openSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport pino from 'pino'\n\nexport function ensureDir(dirPath: string): void {\n mkdirSync(dirPath, { recursive: true, mode: 0o700 })\n}\n\nfunction resolveRuntimeDir(): string {\n if (process.env.TEMPAD_MCP_RUNTIME_DIR) return process.env.TEMPAD_MCP_RUNTIME_DIR\n return join(tmpdir(), 'tempad-dev', 'run')\n}\n\nfunction resolveLogDir(): string {\n if (process.env.TEMPAD_MCP_LOG_DIR) return process.env.TEMPAD_MCP_LOG_DIR\n return join(tmpdir(), 'tempad-dev', 'log')\n}\n\nfunction resolveAssetDir(): string {\n if (process.env.TEMPAD_MCP_ASSET_DIR) return process.env.TEMPAD_MCP_ASSET_DIR\n return join(tmpdir(), 'tempad-dev', 'assets')\n}\n\nexport const RUNTIME_DIR = resolveRuntimeDir()\nexport const LOG_DIR = resolveLogDir()\nexport const ASSET_DIR = resolveAssetDir()\n\nensureDir(RUNTIME_DIR)\nensureDir(LOG_DIR)\nensureDir(ASSET_DIR)\n\nexport function ensureFile(filePath: string): void {\n const fd = openSync(filePath, 'a')\n closeSync(fd)\n}\n\nexport const LOCK_PATH = join(RUNTIME_DIR, 'mcp.lock')\nensureFile(LOCK_PATH)\n\nconst timestamp = new Date().toISOString().replaceAll(':', '-').replaceAll('.', '-')\nconst pid = process.pid\nconst LOG_FILE = join(LOG_DIR, `mcp-${timestamp}-${pid}.log`)\n\nconst prettyTransport = pino.transport({\n target: 'pino-pretty',\n options: {\n translateTime: 'SYS:HH:MM:ss',\n destination: LOG_FILE\n }\n})\n\nexport const log = pino(\n {\n level: process.env.DEBUG ? 'debug' : 'info',\n msgPrefix: '[tempad-dev/mcp] '\n },\n prettyTransport\n)\n\nexport const SOCK_PATH =\n process.platform === 'win32' ? '\\\\\\\\.\\\\pipe\\\\tempad-mcp' : join(RUNTIME_DIR, 'mcp.sock')\n"],
|
|
5
|
-
"mappings": ";;;AAKA,SAAS,aAAa;AACtB,SAAS,eAAe;AACxB,SAAS,QAAAA,aAAY;AACrB,SAAS,qBAAqB;AAC9B,OAAO,cAAc;;;ACTrB,SAAS,WAAW,WAAW,gBAAgB;AAC/C,SAAS,cAAc;AACvB,SAAS,YAAY;AACrB,OAAO,UAAU;
|
|
3
|
+
"sources": ["../src/cli.ts", "../src/shared.ts", "../package.json"],
|
|
4
|
+
"sourcesContent": ["#!/usr/bin/env node\n\nimport type { ChildProcess } from 'node:child_process'\nimport type { Socket } from 'node:net'\n\nimport { spawn } from 'node:child_process'\nimport { connect } from 'node:net'\nimport { join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\nimport lockfile from 'proper-lockfile'\n\nimport { PACKAGE_VERSION, log, LOCK_PATH, RUNTIME_DIR, SOCK_PATH, ensureDir } from './shared'\n\nlet activeSocket: Socket | null = null\nlet shuttingDown = false\n\nfunction closeActiveSocket() {\n if (!activeSocket) return\n try {\n activeSocket.end()\n } catch {\n // ignore\n }\n try {\n activeSocket.destroy()\n } catch {\n // ignore\n }\n activeSocket = null\n}\n\nfunction shutdownCli(reason: string) {\n if (shuttingDown) return\n shuttingDown = true\n log.info(`${reason} Shutting down CLI.`)\n closeActiveSocket()\n process.exit(0)\n}\n\nprocess.on('SIGINT', () => shutdownCli('SIGINT received.'))\nprocess.on('SIGTERM', () => shutdownCli('SIGTERM received.'))\n\nconst HUB_STARTUP_TIMEOUT = 5000\nconst CONNECT_RETRY_DELAY = 200\nconst FAILED_RESTART_DELAY = 5000\nconst HERE = fileURLToPath(new URL('.', import.meta.url))\nconst HUB_ENTRY = join(HERE, 'hub.js')\n\nensureDir(RUNTIME_DIR)\n\nfunction bridge(socket: Socket): Promise<void> {\n return new Promise((resolve) => {\n log.info('Bridge established with Hub. Forwarding I/O.')\n activeSocket = socket\n\n const onStdinEnd = () => {\n shutdownCli('Consumer stream ended.')\n }\n process.stdin.once('end', onStdinEnd)\n\n const onSocketClose = () => {\n log.warn('Connection to Hub lost. Attempting to reconnect...')\n activeSocket = null\n process.stdin.removeListener('end', onStdinEnd)\n process.stdin.unpipe(socket)\n socket.unpipe(process.stdout)\n socket.removeAllListeners()\n resolve()\n }\n socket.once('close', onSocketClose)\n socket.on('error', (err) => log.warn({ err }, 'Socket error occurred.'))\n\n // The `{ end: false }` option prevents stdin from closing the socket.\n process.stdin.pipe(socket, { end: false }).pipe(process.stdout)\n })\n}\n\nfunction connectHub(): Promise<Socket> {\n return new Promise((resolve, reject) => {\n const socket = connect(SOCK_PATH)\n socket.on('connect', () => {\n socket.removeAllListeners('error')\n resolve(socket)\n })\n socket.on('error', reject)\n })\n}\n\nasync function connectWithRetry(timeout: number): Promise<Socket> {\n const startTime = Date.now()\n let delay = CONNECT_RETRY_DELAY\n while (Date.now() - startTime < timeout) {\n try {\n return await connectHub()\n } catch (err: unknown) {\n if (\n err &&\n typeof err === 'object' &&\n 'code' in err &&\n (err.code === 'ENOENT' || err.code === 'ECONNREFUSED')\n ) {\n const remainingTime = timeout - (Date.now() - startTime)\n const waitTime = Math.min(delay, remainingTime)\n if (waitTime <= 0) break\n await new Promise((r) => setTimeout(r, waitTime))\n delay = Math.min(delay * 1.5, 1000)\n } else {\n throw err\n }\n }\n }\n throw new Error(`Failed to connect to Hub within ${timeout}ms.`)\n}\n\nfunction startHub(): ChildProcess {\n log.info('Spawning new Hub process...')\n return spawn(process.execPath, [HUB_ENTRY], {\n detached: true,\n stdio: 'ignore'\n })\n}\n\nasync function tryBecomeLeaderAndStartHub(): Promise<Socket> {\n let releaseLock: (() => Promise<void>) | null = null\n try {\n releaseLock = await lockfile.lock(LOCK_PATH, {\n retries: { retries: 5, factor: 1.2, minTimeout: 50 },\n stale: 15000\n })\n } catch {\n log.info('Another process is starting the Hub. Waiting...')\n return connectWithRetry(HUB_STARTUP_TIMEOUT)\n }\n\n log.info('Acquired lock. Starting Hub as the leader...')\n let child: ChildProcess | null = null\n try {\n try {\n return await connectHub()\n } catch {\n // If the Hub is not running, we proceed to start it.\n log.info('Hub not running. Proceeding to start it...')\n }\n child = startHub()\n child.on('error', (err) => log.error({ err }, 'Hub child process error.'))\n const socket = await connectWithRetry(HUB_STARTUP_TIMEOUT)\n child.unref()\n return socket\n } catch (err: unknown) {\n log.error({ err }, 'Failed to start or connect to the Hub.')\n if (child && !child.killed) {\n log.warn(`Killing stale Hub process (PID: ${child.pid})...`)\n child.kill('SIGTERM')\n }\n throw err\n } finally {\n if (releaseLock) await releaseLock()\n }\n}\n\nasync function main() {\n log.info({ version: PACKAGE_VERSION }, 'TemPad MCP Client starting...')\n\n while (true) {\n try {\n const socket = await connectHub().catch(() => {\n log.info('Hub not running. Initiating startup sequence...')\n return tryBecomeLeaderAndStartHub()\n })\n await bridge(socket)\n log.info('Bridge disconnected. Restarting connection process...')\n } catch (err: unknown) {\n log.error(\n { err },\n `Connection attempt failed. Retrying in ${FAILED_RESTART_DELAY / 1000}s...`\n )\n await new Promise((r) => setTimeout(r, FAILED_RESTART_DELAY))\n }\n }\n}\n\nmain()\n", "import { closeSync, mkdirSync, openSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport pino from 'pino'\n\nimport packageJson from '../package.json' assert { type: 'json' }\n\nexport function ensureDir(dirPath: string): void {\n mkdirSync(dirPath, { recursive: true, mode: 0o700 })\n}\n\nconst pkg = packageJson as { version?: unknown }\nexport const PACKAGE_VERSION = typeof pkg.version === 'string' ? pkg.version : '0.0.0'\n\nfunction resolveRuntimeDir(): string {\n if (process.env.TEMPAD_MCP_RUNTIME_DIR) return process.env.TEMPAD_MCP_RUNTIME_DIR\n return join(tmpdir(), 'tempad-dev', 'run')\n}\n\nfunction resolveLogDir(): string {\n if (process.env.TEMPAD_MCP_LOG_DIR) return process.env.TEMPAD_MCP_LOG_DIR\n return join(tmpdir(), 'tempad-dev', 'log')\n}\n\nfunction resolveAssetDir(): string {\n if (process.env.TEMPAD_MCP_ASSET_DIR) return process.env.TEMPAD_MCP_ASSET_DIR\n return join(tmpdir(), 'tempad-dev', 'assets')\n}\n\nexport const RUNTIME_DIR = resolveRuntimeDir()\nexport const LOG_DIR = resolveLogDir()\nexport const ASSET_DIR = resolveAssetDir()\n\nensureDir(RUNTIME_DIR)\nensureDir(LOG_DIR)\nensureDir(ASSET_DIR)\n\nexport function ensureFile(filePath: string): void {\n const fd = openSync(filePath, 'a')\n closeSync(fd)\n}\n\nexport const LOCK_PATH = join(RUNTIME_DIR, 'mcp.lock')\nensureFile(LOCK_PATH)\n\nconst timestamp = new Date().toISOString().replaceAll(':', '-').replaceAll('.', '-')\nconst pid = process.pid\nconst LOG_FILE = join(LOG_DIR, `mcp-${timestamp}-${pid}.log`)\n\nconst prettyTransport = pino.transport({\n target: 'pino-pretty',\n options: {\n translateTime: 'SYS:HH:MM:ss',\n destination: LOG_FILE\n }\n})\n\nexport const log = pino(\n {\n level: process.env.DEBUG ? 'debug' : 'info',\n msgPrefix: '[tempad-dev/mcp] '\n },\n prettyTransport\n)\n\nexport const SOCK_PATH =\n process.platform === 'win32' ? '\\\\\\\\.\\\\pipe\\\\tempad-mcp' : join(RUNTIME_DIR, 'mcp.sock')\n", "{\n \"name\": \"@tempad-dev/mcp\",\n \"description\": \"MCP server for TemPad Dev.\",\n \"version\": \"0.3.3\",\n \"type\": \"module\",\n \"main\": \"dist/cli.js\",\n \"bin\": \"dist/cli.js\",\n \"files\": [\n \"dist/**/*\",\n \"README.md\"\n ],\n \"scripts\": {\n \"build\": \"tsc -p ./tsconfig.json --noEmit && node ./scripts/build.mjs\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"^1.22.0\",\n \"nanoid\": \"^5.1.6\",\n \"pino\": \"^9.14.0\",\n \"pino-pretty\": \"^11.2.2\",\n \"proper-lockfile\": \"^4.1.2\",\n \"ws\": \"^8.18.3\",\n \"zod\": \"^4.1.12\"\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["join", "join"]
|
|
7
7
|
}
|
package/dist/hub.js
CHANGED
|
@@ -62,9 +62,40 @@ import { closeSync, mkdirSync, openSync } from "node:fs";
|
|
|
62
62
|
import { tmpdir } from "node:os";
|
|
63
63
|
import { join } from "node:path";
|
|
64
64
|
import pino from "pino";
|
|
65
|
+
|
|
66
|
+
// package.json
|
|
67
|
+
var package_default = {
|
|
68
|
+
name: "@tempad-dev/mcp",
|
|
69
|
+
description: "MCP server for TemPad Dev.",
|
|
70
|
+
version: "0.3.3",
|
|
71
|
+
type: "module",
|
|
72
|
+
main: "dist/cli.js",
|
|
73
|
+
bin: "dist/cli.js",
|
|
74
|
+
files: [
|
|
75
|
+
"dist/**/*",
|
|
76
|
+
"README.md"
|
|
77
|
+
],
|
|
78
|
+
scripts: {
|
|
79
|
+
build: "tsc -p ./tsconfig.json --noEmit && node ./scripts/build.mjs",
|
|
80
|
+
prepublishOnly: "npm run build"
|
|
81
|
+
},
|
|
82
|
+
dependencies: {
|
|
83
|
+
"@modelcontextprotocol/sdk": "^1.22.0",
|
|
84
|
+
nanoid: "^5.1.6",
|
|
85
|
+
pino: "^9.14.0",
|
|
86
|
+
"pino-pretty": "^11.2.2",
|
|
87
|
+
"proper-lockfile": "^4.1.2",
|
|
88
|
+
ws: "^8.18.3",
|
|
89
|
+
zod: "^4.1.12"
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
// src/shared.ts
|
|
65
94
|
function ensureDir(dirPath) {
|
|
66
95
|
mkdirSync(dirPath, { recursive: true, mode: 448 });
|
|
67
96
|
}
|
|
97
|
+
var pkg = package_default;
|
|
98
|
+
var PACKAGE_VERSION = typeof pkg.version === "string" ? pkg.version : "0.0.0";
|
|
68
99
|
function resolveRuntimeDir() {
|
|
69
100
|
if (process.env.TEMPAD_MCP_RUNTIME_DIR) return process.env.TEMPAD_MCP_RUNTIME_DIR;
|
|
70
101
|
return join(tmpdir(), "tempad-dev", "run");
|
|
@@ -594,46 +625,28 @@ function cleanupAll() {
|
|
|
594
625
|
// src/tools.ts
|
|
595
626
|
import { z as z2 } from "zod";
|
|
596
627
|
|
|
597
|
-
// src/instructions.
|
|
598
|
-
var
|
|
599
|
-
## MCP Server Instructions (Design to Code)
|
|
600
|
-
|
|
601
|
-
You are connected to a Figma design file via the MCP server. Help convert design elements into code, preserving design intent and fitting the user\u2019s codebase conventions.
|
|
602
|
-
|
|
603
|
-
### P0 (must)
|
|
604
|
-
|
|
605
|
-
- Do not output \`data-hint*\` attributes. They are guidance only.
|
|
606
|
-
- For SVG/vector assets: use the exact provided asset (preserve \`path\` data and \`viewBox\`). Never redraw or approximate vectors.
|
|
607
|
-
|
|
608
|
-
### P1 (policy)
|
|
609
|
-
|
|
610
|
-
- Prefer calling \`get_structure\` early to understand hierarchy and layout intent.
|
|
611
|
-
- Treat \`get_code\` as the implementation baseline; refine it to match the current project\u2019s conventions.
|
|
612
|
-
- Use \`get_screenshot\` only when structure and hints cannot resolve major ambiguities, or to sanity-check the final result.
|
|
613
|
-
|
|
614
|
-
### Layout uncertainty (\`data-hint-auto-layout\`)
|
|
615
|
-
|
|
616
|
-
- If \`data-hint-auto-layout\` is \`none\` or \`inferred\`, treat layout as uncertain.
|
|
617
|
-
- Use \`get_structure\` geometry (positions, sizes, gaps, alignment, bounds) to choose layout. Prefer flex/grid when patterns support it; use absolute only when necessary.
|
|
618
|
-
|
|
619
|
-
### Component intent (\`data-hint-component\`)
|
|
620
|
-
|
|
621
|
-
- If \`data-hint-component\` suggests a reusable component/variant and repetition supports it, factor it into a component API (props/variants). Do not preserve the hint string in output.
|
|
622
|
-
|
|
623
|
-
### Assets and tokens
|
|
624
|
-
|
|
625
|
-
- If \`get_code\` references assets or tokens, handle them according to the current project\u2019s conventions (local asset paths, existing token/variable systems, theming rules).
|
|
626
|
-
`.trim();
|
|
628
|
+
// src/instructions.md
|
|
629
|
+
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\u2019s 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\u2019s 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\u2019s 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\u2019s 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";
|
|
627
630
|
|
|
628
631
|
// src/tools.ts
|
|
629
632
|
var GetCodeParametersSchema = z2.object({
|
|
630
|
-
nodeId: z2.string().describe(
|
|
631
|
-
|
|
632
|
-
|
|
633
|
+
nodeId: z2.string().describe(
|
|
634
|
+
"Optional target node id; omit to use the current single selection when pulling the baseline snapshot."
|
|
635
|
+
).optional(),
|
|
636
|
+
preferredLang: z2.enum(["jsx", "vue"]).describe(
|
|
637
|
+
"Preferred output language to bias the snapshot; otherwise uses the design\u2019s hint/detected language, then falls back to JSX."
|
|
638
|
+
).optional(),
|
|
639
|
+
resolveTokens: z2.boolean().describe(
|
|
640
|
+
"Inline token values instead of references for quick renders; default false returns token metadata so you can map into your theming system."
|
|
641
|
+
).optional()
|
|
633
642
|
});
|
|
634
643
|
var GetTokenDefsParametersSchema = z2.object({
|
|
635
|
-
names: z2.array(z2.string().regex(/^--[a-zA-Z0-9-_]+$/)).min(1).describe(
|
|
636
|
-
|
|
644
|
+
names: z2.array(z2.string().regex(/^--[a-zA-Z0-9-_]+$/)).min(1).describe(
|
|
645
|
+
"Canonical token names (CSS variable form) from get_code.usedTokens or your own list to resolve, e.g., --color-primary."
|
|
646
|
+
),
|
|
647
|
+
includeAllModes: z2.boolean().describe(
|
|
648
|
+
"Include all token modes (light/dark/etc.) instead of just the active one to mirror responsive tokens; default false."
|
|
649
|
+
).optional()
|
|
637
650
|
});
|
|
638
651
|
var AssetDescriptorSchema = z2.object({
|
|
639
652
|
hash: z2.string().min(1),
|
|
@@ -645,16 +658,22 @@ var AssetDescriptorSchema = z2.object({
|
|
|
645
658
|
height: z2.number().int().positive().optional()
|
|
646
659
|
});
|
|
647
660
|
var GetScreenshotParametersSchema = z2.object({
|
|
648
|
-
nodeId: z2.string().describe(
|
|
661
|
+
nodeId: z2.string().describe(
|
|
662
|
+
"Optional node id to screenshot; defaults to the current single selection. Useful when layout/overlap is uncertain (auto-layout none/inferred)."
|
|
663
|
+
).optional()
|
|
649
664
|
});
|
|
650
665
|
var GetStructureParametersSchema = z2.object({
|
|
651
|
-
nodeId: z2.string().describe(
|
|
666
|
+
nodeId: z2.string().describe(
|
|
667
|
+
"Optional node id to outline; defaults to the current single selection. Useful when auto-layout hints are none/inferred or you need explicit geometry for refactors."
|
|
668
|
+
).optional(),
|
|
652
669
|
options: z2.object({
|
|
653
670
|
depth: z2.number().int().positive().describe("Limit traversal depth; defaults to full tree (subject to safety caps).").optional()
|
|
654
671
|
}).optional()
|
|
655
672
|
});
|
|
656
673
|
var GetAssetsParametersSchema = z2.object({
|
|
657
|
-
hashes: z2.array(z2.string().regex(MCP_HASH_PATTERN)).min(1).describe(
|
|
674
|
+
hashes: z2.array(z2.string().regex(MCP_HASH_PATTERN)).min(1).describe(
|
|
675
|
+
"Asset hashes returned from get_code (or other tools) to download/resolve exact bytes for rasterized images or SVGs before routing through your asset pipeline."
|
|
676
|
+
)
|
|
658
677
|
});
|
|
659
678
|
var GetAssetsResultSchema = z2.object({
|
|
660
679
|
assets: z2.array(AssetDescriptorSchema),
|
|
@@ -669,34 +688,34 @@ function hubTool(definition) {
|
|
|
669
688
|
var TOOL_DEFS = [
|
|
670
689
|
extTool({
|
|
671
690
|
name: "get_code",
|
|
672
|
-
description: "Get a high-fidelity code snapshot for a nodeId
|
|
691
|
+
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.",
|
|
673
692
|
parameters: GetCodeParametersSchema,
|
|
674
693
|
target: "extension",
|
|
675
694
|
format: createCodeToolResponse
|
|
676
695
|
}),
|
|
677
696
|
extTool({
|
|
678
697
|
name: "get_token_defs",
|
|
679
|
-
description: "Resolve canonical token names to values (including modes) for tokens referenced by
|
|
698
|
+
description: "Resolve canonical token names to values (including modes) for tokens referenced by get_code. Use this to map into your design token/theming system, including responsive tokens.",
|
|
680
699
|
parameters: GetTokenDefsParametersSchema,
|
|
681
700
|
target: "extension",
|
|
682
701
|
exposed: false
|
|
683
702
|
}),
|
|
684
703
|
extTool({
|
|
685
704
|
name: "get_screenshot",
|
|
686
|
-
description: "Capture a rendered screenshot for a nodeId
|
|
705
|
+
description: "Capture a rendered screenshot for a nodeId/current selection for visual verification. Useful for confirming layering/overlap/masks/shadows/translucency when auto-layout hints are none/inferred.",
|
|
687
706
|
parameters: GetScreenshotParametersSchema,
|
|
688
707
|
target: "extension",
|
|
689
708
|
format: createScreenshotToolResponse
|
|
690
709
|
}),
|
|
691
710
|
extTool({
|
|
692
711
|
name: "get_structure",
|
|
693
|
-
description: "Get a structural + geometry outline for a nodeId
|
|
712
|
+
description: "Get a structural + geometry outline for a nodeId/current selection to understand hierarchy and layout intent. Use when auto-layout hints are none/inferred or you need explicit bounds for refactors/component extraction.",
|
|
694
713
|
parameters: GetStructureParametersSchema,
|
|
695
714
|
target: "extension"
|
|
696
715
|
}),
|
|
697
716
|
hubTool({
|
|
698
717
|
name: "get_assets",
|
|
699
|
-
description: "Resolve asset hashes to downloadable URLs/URIs for assets referenced by
|
|
718
|
+
description: "Resolve asset hashes to downloadable URLs/URIs for assets referenced by get_code, preserving vectors exactly. Pull bytes before routing through your asset/icon pipeline.",
|
|
700
719
|
parameters: GetAssetsParametersSchema,
|
|
701
720
|
target: "hub",
|
|
702
721
|
outputSchema: GetAssetsResultSchema,
|
|
@@ -725,7 +744,7 @@ function createCodeToolResponse(payload) {
|
|
|
725
744
|
}
|
|
726
745
|
const summary = [];
|
|
727
746
|
const codeSize = Buffer.byteLength(payload.code, "utf8");
|
|
728
|
-
summary.push(`Generated
|
|
747
|
+
summary.push(`Generated \`${payload.lang}\` snippet (${formatBytes(codeSize)}).`);
|
|
729
748
|
if (payload.message) {
|
|
730
749
|
summary.push(payload.message);
|
|
731
750
|
}
|
|
@@ -822,13 +841,14 @@ function coercePayloadToToolResponse(payload) {
|
|
|
822
841
|
// src/hub.ts
|
|
823
842
|
var SHUTDOWN_TIMEOUT = 2e3;
|
|
824
843
|
var { wsPortCandidates, toolTimeoutMs, maxPayloadBytes, autoActivateGraceMs } = getMcpServerConfig();
|
|
844
|
+
log.info({ version: PACKAGE_VERSION }, "TemPad MCP Hub starting...");
|
|
825
845
|
var extensions = [];
|
|
826
846
|
var consumerCount = 0;
|
|
827
847
|
var autoActivateTimer = null;
|
|
828
848
|
var selectedWsPort = 0;
|
|
829
849
|
var mcp = new McpServer(
|
|
830
|
-
{ name: "tempad-dev-mcp", version:
|
|
831
|
-
|
|
850
|
+
{ name: "tempad-dev-mcp", version: PACKAGE_VERSION },
|
|
851
|
+
instructions_default ? { instructions: instructions_default } : void 0
|
|
832
852
|
);
|
|
833
853
|
function enrichToolDefinition(tool) {
|
|
834
854
|
if (tool.target === "extension") {
|
package/dist/hub.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/hub.ts", "../../mcp/shared/constants.ts", "../src/asset-http-server.ts", "../src/config.ts", "../src/shared.ts", "../src/asset-store.ts", "../src/protocol.ts", "../src/request.ts", "../src/tools.ts", "../src/instructions.
|
|
4
|
-
"sourcesContent": ["import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { RawData } from 'ws'\nimport type { ZodType } from 'zod'\n\nimport { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { nanoid } from 'nanoid'\nimport { existsSync, rmSync, chmodSync, readFileSync, statSync } from 'node:fs'\nimport { createServer } from 'node:net'\nimport { WebSocketServer } from 'ws'\n\nimport type {\n AssetDescriptor,\n GetAssetsParametersInput,\n GetAssetsResult,\n ToolResultMap,\n ToolName\n} from './tools'\nimport type { AssetRecord, ExtensionConnection } from './types'\n\nimport {\n MCP_ASSET_RESOURCE_NAME,\n MCP_ASSET_URI_PREFIX,\n MCP_ASSET_URI_TEMPLATE\n} from '../../mcp/shared/constants'\nimport { createAssetHttpServer } from './asset-http-server'\nimport { createAssetStore } from './asset-store'\nimport { getMcpServerConfig } from './config'\nimport {\n MessageFromExtensionSchema,\n RegisteredMessage,\n StateMessage,\n ToolCallMessage,\n ToolResultMessage\n} from './protocol'\nimport { register, resolve, reject, cleanupForExtension, cleanupAll } from './request'\nimport { log, RUNTIME_DIR, SOCK_PATH, ensureDir } from './shared'\nimport {\n GetAssetsResultSchema,\n TOOL_DEFS,\n MCP_INSTRUCTIONS,\n coercePayloadToToolResponse,\n createToolErrorResponse\n} from './tools'\n\nconst SHUTDOWN_TIMEOUT = 2000\nconst { wsPortCandidates, toolTimeoutMs, maxPayloadBytes, autoActivateGraceMs } =\n getMcpServerConfig()\n\nconst extensions: ExtensionConnection[] = []\nlet consumerCount = 0\ntype TimeoutHandle = ReturnType<typeof setTimeout>\nlet autoActivateTimer: TimeoutHandle | null = null\nlet selectedWsPort = 0\n\nconst mcp = new McpServer(\n { name: 'tempad-dev-mcp', version: '0.1.0' },\n MCP_INSTRUCTIONS ? { instructions: MCP_INSTRUCTIONS } : undefined\n)\ntype McpInputSchema = Parameters<typeof mcp.registerTool>[1]['inputSchema']\ntype McpOutputSchema = Parameters<typeof mcp.registerTool>[1]['outputSchema']\ntype ToolResponse = CallToolResult\ntype SchemaOutput<Schema extends ZodType> = Schema['_output']\ntype ToolMetadataEntry = (typeof TOOL_DEFS)[number]\ntype ExtensionToolMetadata = Extract<ToolMetadataEntry, { target: 'extension' }>\ntype HubToolMetadata = Extract<ToolMetadataEntry, { target: 'hub' }>\n\ntype HubToolWithHandler<T extends HubToolMetadata = HubToolMetadata> = T & {\n handler: (args: SchemaOutput<T['parameters']>) => Promise<ToolResponse>\n}\n\ntype RegisteredToolDefinition = ExtensionToolMetadata | HubToolWithHandler\n\nfunction enrichToolDefinition(tool: ToolMetadataEntry): RegisteredToolDefinition {\n if (tool.target === 'extension') {\n return tool\n }\n\n switch (tool.name) {\n case 'get_assets':\n return {\n ...tool,\n handler: handleGetAssets\n } satisfies HubToolWithHandler\n default:\n throw new Error('No handler configured for hub tool.')\n }\n}\n\nconst TOOL_DEFINITIONS: ReadonlyArray<RegisteredToolDefinition> = TOOL_DEFS.map((tool) =>\n enrichToolDefinition(tool)\n)\n\ntype RegisteredTool = (typeof TOOL_DEFINITIONS)[number]\ntype ExtensionTool = Extract<RegisteredTool, { target: 'extension' }>\ntype HubOnlyTool = Extract<RegisteredTool, { target: 'hub' }>\n\nfunction hasFormatter(tool: RegisteredToolDefinition): tool is ExtensionTool & {\n format: (payload: unknown) => ToolResponse\n} {\n return tool.target === 'extension' && 'format' in tool\n}\n\ntype ToolDefinitionByName = {\n [T in RegisteredToolDefinition as T['name']]: T\n}\n\nconst TOOL_BY_NAME: ToolDefinitionByName = Object.fromEntries(\n TOOL_DEFINITIONS.map((tool) => [tool.name, tool] as const)\n) as ToolDefinitionByName\n\nfunction getToolDefinition<Name extends ToolName>(name: Name): ToolDefinitionByName[Name] {\n return TOOL_BY_NAME[name]\n}\n\nconst assetStore = createAssetStore()\nconst assetHttpServer = createAssetHttpServer(assetStore)\nawait assetHttpServer.start()\nregisterAssetResources()\n\nfunction registerAssetResources(): void {\n const template = new ResourceTemplate(MCP_ASSET_URI_TEMPLATE, {\n list: async () => ({\n resources: assetStore\n .list()\n .filter((record) => existsSync(record.filePath))\n .map((record) => ({\n uri: buildAssetResourceUri(record.hash),\n name: formatAssetResourceName(record.hash),\n description: `${record.mimeType} (${formatBytes(record.size)})`,\n mimeType: record.mimeType\n }))\n })\n })\n\n mcp.registerResource(\n MCP_ASSET_RESOURCE_NAME,\n template,\n {\n description: 'Binary assets captured by the TemPad Dev hub.'\n },\n async (_uri, variables) => {\n const hash = typeof variables.hash === 'string' ? variables.hash : ''\n return readAssetResource(hash)\n }\n )\n}\n\nasync function readAssetResource(hash: string) {\n if (!hash) {\n throw new Error('Missing asset hash in resource URI.')\n }\n const record = assetStore.get(hash)\n if (!record) {\n throw new Error(`Asset ${hash} not found.`)\n }\n\n if (!existsSync(record.filePath)) {\n assetStore.remove(hash, { removeFile: false })\n throw new Error(`Asset ${hash} file is missing.`)\n }\n\n const stat = statSync(record.filePath)\n // Base64 encoding increases size by ~33% (4 bytes for every 3 bytes)\n const estimatedSize = Math.ceil(stat.size / 3) * 4\n if (estimatedSize > maxPayloadBytes) {\n throw new Error(\n `Asset ${hash} is too large (${formatBytes(stat.size)}, encoded: ${formatBytes(estimatedSize)}) to read via MCP protocol. Use HTTP download.`\n )\n }\n\n assetStore.touch(hash)\n const buffer = readFileSync(record.filePath)\n const resourceUri = buildAssetResourceUri(hash)\n\n if (isTextualMime(record.mimeType)) {\n return {\n contents: [\n {\n uri: resourceUri,\n mimeType: record.mimeType,\n text: buffer.toString('utf8')\n }\n ]\n }\n }\n\n return {\n contents: [\n {\n uri: resourceUri,\n mimeType: record.mimeType,\n blob: buffer.toString('base64')\n }\n ]\n }\n}\n\nfunction isTextualMime(mimeType: string): boolean {\n return mimeType === 'image/svg+xml' || mimeType.startsWith('text/')\n}\n\nfunction buildAssetResourceUri(hash: string): string {\n return `${MCP_ASSET_URI_PREFIX}${hash}`\n}\n\nfunction formatAssetResourceName(hash: string): string {\n return `asset:${hash.slice(0, 8)}`\n}\n\nfunction buildAssetDescriptor(record: AssetRecord): AssetDescriptor {\n return {\n hash: record.hash,\n url: `${assetHttpServer.getBaseUrl()}/assets/${record.hash}`,\n mimeType: record.mimeType,\n size: record.size,\n resourceUri: buildAssetResourceUri(record.hash),\n width: record.metadata?.width,\n height: record.metadata?.height\n }\n}\n\nfunction createAssetResourceLinkBlock(asset: AssetDescriptor) {\n return {\n type: 'resource_link' as const,\n name: formatAssetResourceName(asset.hash),\n uri: asset.resourceUri,\n mimeType: asset.mimeType,\n description: `${describeAsset(asset)} - Download: ${asset.url}`\n }\n}\n\nfunction describeAsset(asset: AssetDescriptor): string {\n return `${asset.mimeType} (${formatBytes(asset.size)})`\n}\n\nfunction registerTools(): void {\n const registered: string[] = []\n for (const tool of TOOL_DEFINITIONS) {\n if ('exposed' in tool && tool.exposed === false) continue\n registerTool(tool)\n registered.push(tool.name)\n }\n log.info({ tools: registered }, 'Registered tools.')\n}\n\nregisterTools()\nfunction registerTool(tool: RegisteredTool): void {\n if (tool.target === 'extension') {\n registerProxiedTool(tool)\n } else {\n registerLocalTool(tool)\n }\n}\n\nfunction registerProxiedTool<T extends ExtensionTool>(tool: T): void {\n type Name = T['name']\n type Result = ToolResultMap[Name]\n\n const schema = tool.parameters\n mcp.registerTool(\n tool.name,\n {\n description: tool.description,\n inputSchema: schema as unknown as McpInputSchema\n },\n async (args: unknown) => {\n try {\n const parsedArgs = schema.parse(args)\n const activeExt = extensions.find((e) => e.active)\n if (!activeExt) throw new Error('No active TemPad Dev extension available.')\n\n const { promise, requestId } = register<Result>(activeExt.id, toolTimeoutMs)\n\n const message: ToolCallMessage = {\n type: 'toolCall',\n id: requestId,\n payload: {\n name: tool.name,\n args: parsedArgs\n }\n }\n activeExt.ws.send(JSON.stringify(message))\n log.info({ tool: tool.name, req: requestId, extId: activeExt.id }, 'Forwarded tool call.')\n\n const payload = await promise\n return createToolResponse(tool.name, payload)\n } catch (error) {\n log.error({ tool: tool.name, error }, 'Tool invocation failed before reaching extension.')\n return createToolErrorResponse(tool.name, error)\n }\n }\n )\n}\n\nfunction registerLocalTool(tool: HubOnlyTool): void {\n const schema = tool.parameters\n const handler = tool.handler\n\n const registrationOptions: {\n description: string\n inputSchema: McpInputSchema\n outputSchema?: McpOutputSchema\n } = {\n description: tool.description,\n inputSchema: schema as unknown as McpInputSchema\n }\n\n if (tool.outputSchema) {\n registrationOptions.outputSchema = tool.outputSchema as unknown as McpOutputSchema\n }\n\n mcp.registerTool(tool.name, registrationOptions, async (args: unknown) => {\n try {\n const parsed = schema.parse(args)\n return await handler(parsed)\n } catch (error) {\n log.error({ tool: tool.name, error }, 'Local tool invocation failed.')\n return createToolErrorResponse(tool.name, error)\n }\n })\n}\n\nfunction createToolResponse<Name extends ToolName>(\n toolName: Name,\n payload: ToolResultMap[Name]\n): ToolResponse {\n const definition = getToolDefinition(toolName)\n if (definition && hasFormatter(definition)) {\n try {\n const formatter = definition.format as (input: ToolResultMap[Name]) => ToolResponse\n return formatter(payload)\n } catch (error) {\n log.warn({ tool: toolName, error }, 'Failed to format tool result; returning raw payload.')\n return coercePayloadToToolResponse(payload)\n }\n }\n\n return coercePayloadToToolResponse(payload)\n}\n\nasync function handleGetAssets({ hashes }: GetAssetsParametersInput): Promise<ToolResponse> {\n if (hashes.length > 100) {\n throw new Error('Too many hashes requested. Limit is 100.')\n }\n const unique = Array.from(new Set(hashes))\n const records = assetStore.getMany(unique).filter((record) => {\n if (existsSync(record.filePath)) return true\n assetStore.remove(record.hash, { removeFile: false })\n return false\n })\n const found = new Set(records.map((record) => record.hash))\n const payload: GetAssetsResult = GetAssetsResultSchema.parse({\n assets: records.map((record) => buildAssetDescriptor(record)),\n missing: unique.filter((hash) => !found.has(hash))\n })\n\n const summary: string[] = []\n summary.push(\n payload.assets.length\n ? `Resolved ${payload.assets.length} asset${payload.assets.length === 1 ? '' : 's'}.`\n : 'No assets were resolved for the requested hashes.'\n )\n if (payload.missing.length) {\n summary.push(`Missing: ${payload.missing.join(', ')}`)\n }\n summary.push(\n 'Use resources/read with each resourceUri or fetch the fallback URL to download bytes.'\n )\n\n const content = [\n {\n type: 'text' as const,\n text: summary.join('\\n')\n },\n ...payload.assets.map((asset) => createAssetResourceLinkBlock(asset))\n ]\n\n return {\n content,\n structuredContent: payload\n }\n}\n\nfunction getActiveId(): string | null {\n return extensions.find((e) => e.active)?.id ?? null\n}\n\nfunction setActive(targetId: string | null): void {\n extensions.forEach((e) => {\n e.active = targetId !== null && e.id === targetId\n })\n}\n\nfunction clearAutoActivateTimer(): void {\n if (autoActivateTimer) {\n clearTimeout(autoActivateTimer)\n autoActivateTimer = null\n }\n}\n\nfunction scheduleAutoActivate(): void {\n clearAutoActivateTimer()\n\n if (extensions.length !== 1 || getActiveId()) {\n return\n }\n\n const target = extensions[0]\n autoActivateTimer = setTimeout(() => {\n autoActivateTimer = null\n if (extensions.length === 1 && !getActiveId()) {\n setActive(target.id)\n log.info({ id: target.id }, 'Auto-activated sole extension after grace period.')\n broadcastState()\n }\n }, autoActivateGraceMs)\n}\n\nfunction unrefTimer(timer: TimeoutHandle): void {\n if (typeof timer === 'object' && timer !== null) {\n const handle = timer as NodeJS.Timeout\n if (typeof handle.unref === 'function') {\n handle.unref()\n }\n }\n}\n\nfunction broadcastState(): void {\n const activeId = getActiveId()\n const message: StateMessage = {\n type: 'state',\n activeId,\n count: extensions.length,\n port: selectedWsPort,\n assetServerUrl: assetHttpServer.getBaseUrl()\n }\n extensions.forEach((ext) => ext.ws.send(JSON.stringify(message)))\n log.debug({ activeId, count: extensions.length }, 'Broadcasted state.')\n}\n\nfunction rawDataToBuffer(raw: RawData): Buffer {\n if (typeof raw === 'string') return Buffer.from(raw)\n if (Buffer.isBuffer(raw)) return raw\n if (raw instanceof ArrayBuffer) return Buffer.from(raw)\n return Buffer.concat(raw)\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n\nfunction shutdown(): void {\n log.info('Hub is shutting down...')\n assetStore.flush()\n assetHttpServer.stop()\n netServer.close(() => log.info('Net server closed.'))\n wss?.close(() => log.info('WebSocket server closed.'))\n cleanupAll()\n const timer = setTimeout(() => {\n log.warn('Shutdown timed out. Forcing exit.')\n process.exit(1)\n }, SHUTDOWN_TIMEOUT)\n unrefTimer(timer)\n}\n\ntry {\n ensureDir(RUNTIME_DIR)\n if (process.platform !== 'win32' && existsSync(SOCK_PATH)) {\n log.warn({ sock: SOCK_PATH }, 'Removing stale socket file.')\n rmSync(SOCK_PATH)\n }\n} catch (error: unknown) {\n log.error({ err: error }, 'Failed to initialize runtime environment.')\n process.exit(1)\n}\n\nconst netServer = createServer((sock) => {\n consumerCount++\n log.info(`Consumer connected. Total: ${consumerCount}`)\n const transport = new StdioServerTransport(sock, sock)\n mcp.connect(transport).catch((err) => {\n log.error({ err }, 'Failed to attach MCP transport.')\n transport.close().catch((closeErr) => log.warn({ err: closeErr }, 'Transport close failed.'))\n sock.destroy()\n })\n sock.on('error', (err) => {\n log.warn({ err }, 'Consumer socket error.')\n transport.close().catch((closeErr) => log.warn({ err: closeErr }, 'Transport close failed.'))\n })\n sock.on('close', async () => {\n await transport.close()\n consumerCount--\n log.info(`Consumer disconnected. Remaining: ${consumerCount}`)\n if (consumerCount === 0) {\n log.info('Last consumer disconnected. Shutting down.')\n shutdown()\n }\n })\n})\nnetServer.on('error', (err) => {\n log.error({ err }, 'Net server error.')\n process.exit(1)\n})\nnetServer.listen(SOCK_PATH, () => {\n try {\n if (process.platform !== 'win32') chmodSync(SOCK_PATH, 0o600)\n } catch (err) {\n log.error({ err }, 'Failed to set socket permissions. Shutting down.')\n process.exit(1)\n }\n log.info({ sock: SOCK_PATH }, 'Hub socket ready.')\n})\n\nasync function startWebSocketServer(): Promise<{ wss: WebSocketServer; port: number }> {\n for (const candidate of wsPortCandidates) {\n const server = new WebSocketServer({\n host: '127.0.0.1',\n port: candidate,\n maxPayload: maxPayloadBytes\n })\n\n try {\n await new Promise<void>((resolve, reject) => {\n const onError = (err: NodeJS.ErrnoException) => {\n server.off('listening', onListening)\n reject(err)\n }\n const onListening = () => {\n server.off('error', onError)\n resolve()\n }\n server.once('error', onError)\n server.once('listening', onListening)\n })\n return { wss: server, port: candidate }\n } catch (err) {\n server.close()\n const errno = err as NodeJS.ErrnoException\n if (errno.code === 'EADDRINUSE') {\n log.warn({ port: candidate }, 'WebSocket port in use, trying next candidate.')\n continue\n }\n log.error({ err: errno, port: candidate }, 'Failed to start WebSocket server.')\n process.exit(1)\n }\n }\n\n log.error(\n { candidates: wsPortCandidates },\n 'Unable to start WebSocket server on any candidate port.'\n )\n process.exit(1)\n}\n\nconst { wss, port } = await startWebSocketServer()\nselectedWsPort = port\n\n// Add an error handler to prevent crashes from port conflicts, etc.\nwss.on('error', (err) => {\n log.error({ err }, 'WebSocket server critical error. Exiting.')\n process.exit(1)\n})\n\nwss.on('connection', (ws) => {\n const ext: ExtensionConnection = { id: nanoid(), ws, active: false }\n extensions.push(ext)\n log.info({ id: ext.id }, `Extension connected. Total: ${extensions.length}`)\n\n const message: RegisteredMessage = { type: 'registered', id: ext.id }\n ws.send(JSON.stringify(message))\n broadcastState()\n scheduleAutoActivate()\n\n ws.on('message', (raw: RawData, isBinary: boolean) => {\n if (isBinary) {\n log.warn({ extId: ext.id }, 'Unexpected binary message received.')\n return\n }\n\n const messageBuffer = rawDataToBuffer(raw)\n\n let parsedJson: unknown\n try {\n parsedJson = JSON.parse(messageBuffer.toString('utf-8'))\n } catch (e: unknown) {\n log.warn({ err: e, extId: ext.id }, 'Failed to parse message.')\n return\n }\n\n const parseResult = MessageFromExtensionSchema.safeParse(parsedJson)\n if (!parseResult.success) {\n log.warn({ error: parseResult.error.flatten(), extId: ext.id }, 'Invalid message shape.')\n return\n }\n const msg = parseResult.data\n\n switch (msg.type) {\n case 'activate': {\n setActive(ext.id)\n log.info({ id: ext.id }, 'Extension activated.')\n broadcastState()\n scheduleAutoActivate()\n break\n }\n case 'toolResult': {\n const { id, payload, error } = msg as ToolResultMessage\n if (error) {\n reject(id, error instanceof Error ? error : new Error(String(error)))\n } else {\n resolve(id, payload)\n }\n break\n }\n }\n })\n\n ws.on('close', () => {\n const index = extensions.findIndex((e) => e.id === ext.id)\n if (index > -1) extensions.splice(index, 1)\n\n log.info({ id: ext.id }, `Extension disconnected. Remaining: ${extensions.length}`)\n cleanupForExtension(ext.id)\n\n if (ext.active) {\n log.warn({ id: ext.id }, 'Active extension disconnected.')\n setActive(null)\n }\n\n broadcastState()\n scheduleAutoActivate()\n })\n})\n\nlog.info({ port: selectedWsPort }, 'WebSocket server ready.')\n\nprocess.on('SIGINT', shutdown)\nprocess.on('SIGTERM', shutdown)\n", "export const MCP_PORT_CANDIDATES = [6220, 7431, 8127]\n\n// Upper bound for MCP message payloads in bytes.\nexport const MCP_MAX_PAYLOAD_BYTES = 4 * 1024 * 1024\n\n// Default tool timeout used by the MCP hub (ms).\nexport const MCP_TOOL_TIMEOUT_MS = 15000\n\n// Grace period before auto-activating the sole extension (ms).\nexport const MCP_AUTO_ACTIVATE_GRACE_MS = 1500\n\n// Maximum allowed size for uploaded assets (bytes).\nexport const MCP_MAX_ASSET_BYTES = 8 * 1024 * 1024\n\nexport const MCP_ASSET_RESOURCE_NAME = 'tempad-assets'\nexport const MCP_ASSET_URI_PREFIX = 'asset://tempad/'\nexport const MCP_ASSET_URI_TEMPLATE = `${MCP_ASSET_URI_PREFIX}{hash}`\n\nexport const MCP_HASH_PATTERN = /^[a-f0-9]{64}$/i\n", "import { nanoid } from 'nanoid'\nimport { createHash } from 'node:crypto'\nimport {\n createReadStream,\n createWriteStream,\n existsSync,\n renameSync,\n statSync,\n unlinkSync\n} from 'node:fs'\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http'\nimport { join } from 'node:path'\nimport { pipeline, Transform } from 'node:stream'\nimport { URL } from 'node:url'\n\nimport type { AssetStore } from './asset-store'\n\nimport { MCP_HASH_PATTERN } from '../../mcp/shared/constants'\nimport { getMcpServerConfig } from './config'\nimport { ASSET_DIR, log } from './shared'\n\nconst LOOPBACK_HOST = '127.0.0.1'\nconst { maxAssetSizeBytes } = getMcpServerConfig()\n\nexport interface AssetHttpServer {\n start(): Promise<void>\n stop(): void\n getBaseUrl(): string\n}\n\nexport function createAssetHttpServer(store: AssetStore): AssetHttpServer {\n const server = createServer(handleRequest)\n let port: number | null = null\n\n async function start(): Promise<void> {\n if (port !== null) return\n await new Promise<void>((resolve, reject) => {\n const onError = (error: Error) => {\n server.off('listening', onListening)\n reject(error)\n }\n const onListening = () => {\n server.off('error', onError)\n const address = server.address()\n if (address && typeof address === 'object') {\n port = address.port\n resolve()\n } else {\n reject(new Error('Failed to determine HTTP server port.'))\n }\n }\n server.once('error', onError)\n server.once('listening', onListening)\n server.listen(0, LOOPBACK_HOST)\n })\n log.info({ port }, 'Asset HTTP server ready.')\n }\n\n function stop(): void {\n if (port === null) return\n server.close()\n port = null\n }\n\n function getBaseUrl(): string {\n if (port === null) throw new Error('Asset HTTP server is not running.')\n return `http://${LOOPBACK_HOST}:${port}`\n }\n\n function handleRequest(req: IncomingMessage, res: ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Asset-Width, X-Asset-Height')\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204)\n res.end()\n return\n }\n\n if (!req.url) {\n res.writeHead(400)\n res.end('Missing URL')\n return\n }\n\n const url = new URL(req.url, getBaseUrl())\n const segments = url.pathname.split('/').filter(Boolean)\n if (segments.length !== 2 || segments[0] !== 'assets') {\n res.writeHead(404)\n res.end('Not Found')\n return\n }\n\n const hash = segments[1]\n\n if (req.method === 'POST') {\n handleUpload(req, res, hash)\n return\n }\n\n if (req.method === 'GET') {\n handleDownload(req, res, hash)\n return\n }\n\n res.writeHead(405)\n res.end('Method Not Allowed')\n }\n\n function handleDownload(req: IncomingMessage, res: ServerResponse, hash: string): void {\n const record = store.get(hash)\n if (!record) {\n res.writeHead(404)\n res.end('Not Found')\n return\n }\n\n let stat\n try {\n stat = statSync(record.filePath)\n } catch (error) {\n const err = error as NodeJS.ErrnoException\n if (err.code === 'ENOENT') {\n store.remove(hash, { removeFile: false })\n res.writeHead(404)\n res.end('Not Found')\n } else {\n log.error({ error, hash }, 'Failed to stat asset file.')\n res.writeHead(500)\n res.end('Internal Server Error')\n }\n return\n }\n\n res.writeHead(200, {\n 'Content-Type': record.mimeType,\n 'Content-Length': stat.size.toString(),\n 'Cache-Control': 'public, max-age=31536000, immutable'\n })\n\n const stream = createReadStream(record.filePath)\n stream.on('error', (error) => {\n log.warn({ error, hash }, 'Failed to stream asset file.')\n if (!res.headersSent) {\n res.writeHead(500)\n }\n res.end('Internal Server Error')\n })\n stream.on('open', () => {\n store.touch(hash)\n })\n stream.pipe(res)\n }\n\n function handleUpload(req: IncomingMessage, res: ServerResponse, hash: string): void {\n if (!MCP_HASH_PATTERN.test(hash)) {\n res.writeHead(400)\n res.end('Invalid Hash Format')\n return\n }\n\n const mimeType = req.headers['content-type'] || 'application/octet-stream'\n const filePath = join(ASSET_DIR, hash)\n\n const width = parseInt(req.headers['x-asset-width'] as string, 10)\n const height = parseInt(req.headers['x-asset-height'] as string, 10)\n const metadata =\n !isNaN(width) && !isNaN(height) && width > 0 && height > 0 ? { width, height } : undefined\n\n // If asset already exists and file is present, skip write\n if (store.has(hash) && existsSync(filePath)) {\n // Drain request to ensure connection is clean\n req.resume()\n\n const existing = store.get(hash)!\n let changed = false\n if (metadata) {\n existing.metadata = metadata\n changed = true\n }\n if (existing.mimeType !== mimeType) {\n existing.mimeType = mimeType\n changed = true\n }\n if (changed) {\n store.upsert(existing)\n }\n store.touch(hash)\n res.writeHead(200)\n res.end('OK')\n return\n }\n\n const tmpPath = `${filePath}.tmp.${nanoid()}`\n const writeStream = createWriteStream(tmpPath)\n const hasher = createHash('sha256')\n let size = 0\n\n const cleanup = () => {\n if (existsSync(tmpPath)) {\n try {\n unlinkSync(tmpPath)\n } catch (e) {\n log.warn({ error: e, tmpPath }, 'Failed to cleanup temp file.')\n }\n }\n }\n\n const monitor = new Transform({\n transform(chunk, encoding, callback) {\n size += chunk.length\n if (size > maxAssetSizeBytes) {\n callback(new Error('PayloadTooLarge'))\n return\n }\n hasher.update(chunk)\n callback(null, chunk)\n }\n })\n\n pipeline(req, monitor, writeStream, (err) => {\n if (err) {\n cleanup()\n if (err.message === 'PayloadTooLarge') {\n res.writeHead(413)\n res.end('Payload Too Large')\n } else if (err.code === 'ERR_STREAM_PREMATURE_CLOSE') {\n log.warn({ hash }, 'Upload request closed prematurely.')\n } else {\n log.error({ error: err, hash }, 'Upload pipeline failed.')\n if (!res.headersSent) {\n res.writeHead(500)\n res.end('Internal Server Error')\n }\n }\n return\n }\n\n const computedHash = hasher.digest('hex')\n if (computedHash !== hash) {\n cleanup()\n res.writeHead(400)\n res.end('Hash Mismatch')\n return\n }\n\n try {\n renameSync(tmpPath, filePath)\n } catch (error) {\n log.error({ error, hash }, 'Failed to rename temp file to asset.')\n cleanup()\n res.writeHead(500)\n res.end('Internal Server Error')\n return\n }\n\n store.upsert({\n hash,\n filePath,\n mimeType,\n size,\n metadata\n })\n log.info({ hash, size }, 'Stored uploaded asset via HTTP.')\n res.writeHead(201)\n res.end('Created')\n })\n }\n\n return {\n start,\n stop,\n getBaseUrl\n }\n}\n", "import {\n MCP_AUTO_ACTIVATE_GRACE_MS,\n MCP_MAX_ASSET_BYTES,\n MCP_MAX_PAYLOAD_BYTES,\n MCP_PORT_CANDIDATES,\n MCP_TOOL_TIMEOUT_MS\n} from '../../mcp/shared/constants'\n\nfunction parsePositiveInt(envValue: string | undefined, fallback: number): number {\n const parsed = envValue ? Number.parseInt(envValue, 10) : Number.NaN\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback\n}\n\nfunction resolveToolTimeoutMs(): number {\n return parsePositiveInt(process.env.TEMPAD_MCP_TOOL_TIMEOUT, MCP_TOOL_TIMEOUT_MS)\n}\n\nfunction resolveAutoActivateGraceMs(): number {\n return parsePositiveInt(process.env.TEMPAD_MCP_AUTO_ACTIVATE_GRACE, MCP_AUTO_ACTIVATE_GRACE_MS)\n}\n\nfunction resolveMaxAssetSizeBytes(): number {\n return parsePositiveInt(process.env.TEMPAD_MCP_MAX_ASSET_BYTES, MCP_MAX_ASSET_BYTES)\n}\n\nexport function getMcpServerConfig() {\n return {\n wsPortCandidates: [...MCP_PORT_CANDIDATES],\n toolTimeoutMs: resolveToolTimeoutMs(),\n maxPayloadBytes: MCP_MAX_PAYLOAD_BYTES,\n autoActivateGraceMs: resolveAutoActivateGraceMs(),\n maxAssetSizeBytes: resolveMaxAssetSizeBytes()\n }\n}\n", "import { closeSync, mkdirSync, openSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport pino from 'pino'\n\nexport function ensureDir(dirPath: string): void {\n mkdirSync(dirPath, { recursive: true, mode: 0o700 })\n}\n\nfunction resolveRuntimeDir(): string {\n if (process.env.TEMPAD_MCP_RUNTIME_DIR) return process.env.TEMPAD_MCP_RUNTIME_DIR\n return join(tmpdir(), 'tempad-dev', 'run')\n}\n\nfunction resolveLogDir(): string {\n if (process.env.TEMPAD_MCP_LOG_DIR) return process.env.TEMPAD_MCP_LOG_DIR\n return join(tmpdir(), 'tempad-dev', 'log')\n}\n\nfunction resolveAssetDir(): string {\n if (process.env.TEMPAD_MCP_ASSET_DIR) return process.env.TEMPAD_MCP_ASSET_DIR\n return join(tmpdir(), 'tempad-dev', 'assets')\n}\n\nexport const RUNTIME_DIR = resolveRuntimeDir()\nexport const LOG_DIR = resolveLogDir()\nexport const ASSET_DIR = resolveAssetDir()\n\nensureDir(RUNTIME_DIR)\nensureDir(LOG_DIR)\nensureDir(ASSET_DIR)\n\nexport function ensureFile(filePath: string): void {\n const fd = openSync(filePath, 'a')\n closeSync(fd)\n}\n\nexport const LOCK_PATH = join(RUNTIME_DIR, 'mcp.lock')\nensureFile(LOCK_PATH)\n\nconst timestamp = new Date().toISOString().replaceAll(':', '-').replaceAll('.', '-')\nconst pid = process.pid\nconst LOG_FILE = join(LOG_DIR, `mcp-${timestamp}-${pid}.log`)\n\nconst prettyTransport = pino.transport({\n target: 'pino-pretty',\n options: {\n translateTime: 'SYS:HH:MM:ss',\n destination: LOG_FILE\n }\n})\n\nexport const log = pino(\n {\n level: process.env.DEBUG ? 'debug' : 'info',\n msgPrefix: '[tempad-dev/mcp] '\n },\n prettyTransport\n)\n\nexport const SOCK_PATH =\n process.platform === 'win32' ? '\\\\\\\\.\\\\pipe\\\\tempad-mcp' : join(RUNTIME_DIR, 'mcp.sock')\n", "import { existsSync, readFileSync, rmSync, writeFileSync, readdirSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\n\nimport type { AssetRecord } from './types'\n\nimport { ASSET_DIR, ensureDir, ensureFile, log } from './shared'\n\nconst INDEX_FILENAME = 'assets.json'\nconst DEFAULT_INDEX_PATH = join(ASSET_DIR, INDEX_FILENAME)\n\nexport interface AssetStoreOptions {\n indexPath?: string\n}\n\nexport interface AssetStore {\n list(): AssetRecord[]\n has(hash: string): boolean\n get(hash: string): AssetRecord | undefined\n getMany(hashes: string[]): AssetRecord[]\n upsert(\n input: Omit<AssetRecord, 'uploadedAt' | 'lastAccess'> &\n Partial<Pick<AssetRecord, 'uploadedAt' | 'lastAccess'>>\n ): AssetRecord\n touch(hash: string): AssetRecord | undefined\n remove(hash: string, opts?: { removeFile?: boolean }): void\n reconcile(): void\n flush(): void\n}\n\nfunction readIndex(indexPath: string): AssetRecord[] {\n if (!existsSync(indexPath)) return []\n try {\n const raw = readFileSync(indexPath, 'utf8').trim()\n if (!raw) return []\n const parsed = JSON.parse(raw)\n return Array.isArray(parsed) ? (parsed as AssetRecord[]) : []\n } catch (error) {\n log.warn({ error, indexPath }, 'Failed to read asset catalog; starting fresh.')\n return []\n }\n}\n\nfunction writeIndex(indexPath: string, values: AssetRecord[]): void {\n const payload = JSON.stringify(values, null, 2)\n writeFileSync(indexPath, payload, 'utf8')\n}\n\nexport function createAssetStore(options: AssetStoreOptions = {}): AssetStore {\n ensureDir(ASSET_DIR)\n const indexPath = options.indexPath ?? DEFAULT_INDEX_PATH\n ensureFile(indexPath)\n const records = new Map<string, AssetRecord>()\n let persistTimer: NodeJS.Timeout | null = null\n\n function loadExisting(): void {\n const list = readIndex(indexPath)\n for (const record of list) {\n if (record?.hash && record?.filePath) {\n records.set(record.hash, record)\n }\n }\n }\n\n function persist(): void {\n if (persistTimer) return\n persistTimer = setTimeout(() => {\n persistTimer = null\n writeIndex(indexPath, [...records.values()])\n }, 5000)\n if (typeof persistTimer.unref === 'function') {\n persistTimer.unref()\n }\n }\n\n function flush(): void {\n if (persistTimer) {\n clearTimeout(persistTimer)\n persistTimer = null\n }\n writeIndex(indexPath, [...records.values()])\n }\n\n function list(): AssetRecord[] {\n return [...records.values()]\n }\n\n function has(hash: string): boolean {\n return records.has(hash)\n }\n\n function get(hash: string): AssetRecord | undefined {\n return records.get(hash)\n }\n\n function getMany(hashes: string[]): AssetRecord[] {\n return hashes\n .map((hash) => records.get(hash))\n .filter((record): record is AssetRecord => !!record)\n }\n\n function upsert(\n input: Omit<AssetRecord, 'uploadedAt' | 'lastAccess'> &\n Partial<Pick<AssetRecord, 'uploadedAt' | 'lastAccess'>>\n ): AssetRecord {\n const now = Date.now()\n const record: AssetRecord = {\n ...input,\n uploadedAt: input.uploadedAt ?? now,\n lastAccess: input.lastAccess ?? now\n }\n records.set(record.hash, record)\n persist()\n return record\n }\n\n function touch(hash: string): AssetRecord | undefined {\n const existing = records.get(hash)\n if (!existing) return undefined\n existing.lastAccess = Date.now()\n persist()\n return existing\n }\n\n function remove(hash: string, { removeFile = true } = {}): void {\n const record = records.get(hash)\n if (!record) return\n records.delete(hash)\n persist()\n\n if (removeFile) {\n try {\n rmSync(record.filePath, { force: true })\n } catch (error) {\n log.warn({ hash, error }, 'Failed to remove asset file on delete.')\n }\n }\n }\n\n function reconcile(): void {\n let changed = false\n for (const [hash, record] of records) {\n if (!existsSync(record.filePath)) {\n records.delete(hash)\n changed = true\n }\n }\n\n try {\n const files = readdirSync(ASSET_DIR)\n const now = Date.now()\n for (const file of files) {\n if (file === INDEX_FILENAME) continue\n\n // Cleanup stale tmp files (> 1 hour)\n if (file.includes('.tmp.')) {\n try {\n const filePath = join(ASSET_DIR, file)\n const stat = statSync(filePath)\n if (now - stat.mtimeMs > 3600 * 1000) {\n rmSync(filePath, { force: true })\n log.info({ file }, 'Cleaned up stale temp file.')\n }\n } catch (e) {\n // Ignore errors during cleanup\n log.debug({ error: e, file }, 'Failed to cleanup stale temp file.')\n }\n continue\n }\n\n if (!/^[a-f0-9]{64}$/i.test(file)) continue\n\n if (!records.has(file)) {\n const filePath = join(ASSET_DIR, file)\n try {\n const stat = statSync(filePath)\n records.set(file, {\n hash: file,\n filePath,\n mimeType: 'application/octet-stream',\n size: stat.size,\n uploadedAt: stat.birthtimeMs,\n lastAccess: stat.atimeMs\n })\n changed = true\n log.info({ hash: file }, 'Recovered orphan asset file.')\n } catch (e) {\n log.warn({ error: e, file }, 'Failed to stat orphan file.')\n }\n }\n }\n } catch (error) {\n log.warn({ error }, 'Failed to scan asset directory for orphans.')\n }\n\n if (changed) flush()\n }\n\n loadExisting()\n reconcile()\n\n return {\n list,\n has,\n get,\n getMany,\n upsert,\n touch,\n remove,\n reconcile,\n flush\n }\n}\n", "import { z } from 'zod'\n\n// Messages from hub to extension\nexport const RegisteredMessageSchema = z.object({\n type: z.literal('registered'),\n id: z.string()\n})\n\nexport const StateMessageSchema = z.object({\n type: z.literal('state'),\n activeId: z.string().nullable(),\n count: z.number().nonnegative(),\n port: z.number().positive(),\n assetServerUrl: z.string().url()\n})\n\nexport const ToolCallPayloadSchema = z.object({\n name: z.string(),\n args: z.unknown()\n})\n\nexport const ToolCallMessageSchema = z.object({\n type: z.literal('toolCall'),\n id: z.string(),\n payload: ToolCallPayloadSchema\n})\n\nexport const MessageToExtensionSchema = z.discriminatedUnion('type', [\n RegisteredMessageSchema,\n StateMessageSchema,\n ToolCallMessageSchema\n])\n\n// Messages from extension to hub\nexport const ActivateMessageSchema = z.object({\n type: z.literal('activate')\n})\n\nexport const ToolResultMessageSchema = z.object({\n type: z.literal('toolResult'),\n id: z.string(),\n payload: z.unknown().optional(),\n error: z.unknown().optional()\n})\n\nexport const MessageFromExtensionSchema = z.discriminatedUnion('type', [\n ActivateMessageSchema,\n ToolResultMessageSchema\n])\n\nexport type RegisteredMessage = z.infer<typeof RegisteredMessageSchema>\nexport type StateMessage = z.infer<typeof StateMessageSchema>\nexport type ToolCallPayload = z.infer<typeof ToolCallPayloadSchema>\nexport type ToolCallMessage = z.infer<typeof ToolCallMessageSchema>\nexport type MessageToExtension = z.infer<typeof MessageToExtensionSchema>\nexport type ActivateMessage = z.infer<typeof ActivateMessageSchema>\nexport type ToolResultMessage = z.infer<typeof ToolResultMessageSchema>\nexport type MessageFromExtension = z.infer<typeof MessageFromExtensionSchema>\n\nexport function parseMessageToExtension(data: string): MessageToExtension | null {\n let parsed: unknown\n try {\n parsed = JSON.parse(data)\n } catch {\n return null\n }\n const result = MessageToExtensionSchema.safeParse(parsed)\n return result.success ? result.data : null\n}\n\nexport function parseMessageFromExtension(data: string): MessageFromExtension | null {\n let parsed: unknown\n try {\n parsed = JSON.parse(data)\n } catch {\n return null\n }\n const result = MessageFromExtensionSchema.safeParse(parsed)\n return result.success ? result.data : null\n}\n", "import { nanoid } from 'nanoid'\n\nimport type { PendingToolCall } from './types'\n\nimport { log } from './shared'\n\nconst pendingCalls = new Map<string, PendingToolCall>()\n\nexport function register<T>(\n extensionId: string,\n timeout: number\n): { promise: Promise<T>; requestId: string } {\n const requestId = nanoid()\n const promise = new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n pendingCalls.delete(requestId)\n reject(new Error(`Extension did not respond within ${timeout / 1000}s.`))\n }, timeout)\n\n pendingCalls.set(requestId, {\n resolve: resolve as (value: unknown) => void,\n reject,\n timer,\n extensionId\n })\n })\n return { promise, requestId }\n}\n\nexport function resolve(requestId: string, payload: unknown): void {\n const call = pendingCalls.get(requestId)\n if (call) {\n const { timer, resolve: finish } = call\n clearTimeout(timer)\n finish(payload)\n pendingCalls.delete(requestId)\n } else {\n log.warn({ reqId: requestId }, 'Received result for unknown/timed-out call.')\n }\n}\n\nexport function reject(requestId: string, error: Error): void {\n const call = pendingCalls.get(requestId)\n if (call) {\n const { timer, reject: fail } = call\n clearTimeout(timer)\n fail(error)\n pendingCalls.delete(requestId)\n } else {\n log.warn({ reqId: requestId }, 'Received error for unknown/timed-out call.')\n }\n}\n\nexport function cleanupForExtension(extensionId: string): void {\n for (const [reqId, call] of pendingCalls.entries()) {\n const { timer, reject: fail, extensionId: extId } = call\n if (extId === extensionId) {\n clearTimeout(timer)\n fail(new Error('Extension disconnected before providing a result.'))\n pendingCalls.delete(reqId)\n log.warn({ reqId, extId: extensionId }, 'Rejected pending call from disconnected extension.')\n }\n }\n}\n\nexport function cleanupAll(): void {\n pendingCalls.forEach((call, reqId) => {\n const { timer, reject: fail } = call\n clearTimeout(timer)\n fail(new Error('Hub is shutting down.'))\n log.debug({ reqId }, 'Rejected pending tool call due to shutdown.')\n })\n pendingCalls.clear()\n}\n", "import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { ZodType } from 'zod'\n\nimport { z } from 'zod'\n\nimport type { AssetDescriptor } from '../../mcp/shared/types'\n\nimport { MCP_HASH_PATTERN } from '../../mcp/shared/constants'\n\nexport type { AssetDescriptor }\n\n// get_code\nexport const GetCodeParametersSchema = z.object({\n nodeId: z\n .string()\n .describe('Optional node id to target; defaults to the current single selection.')\n .optional(),\n preferredLang: z\n .enum(['jsx', 'vue'])\n .describe('Preferred output language; otherwise uses the design\u2019s hint/detected language, then JSX.')\n .optional(),\n resolveTokens: z\n .boolean()\n .describe('Resolve token references to concrete values; default false returns token metadata.')\n .optional()\n})\n\nexport type GetCodeParametersInput = z.input<typeof GetCodeParametersSchema>\nexport type GetCodeResult = {\n code: string\n lang: 'vue' | 'jsx'\n message?: string\n usedTokens?: GetTokenDefsResult['tokens']\n assets: AssetDescriptor[]\n codegen: {\n preset: string\n config: {\n cssUnit: 'px' | 'rem'\n rootFontSize: number\n scale: number\n }\n }\n}\n\n// get_token_defs\nexport const GetTokenDefsParametersSchema = z.object({\n names: z\n .array(z.string().regex(/^--[a-zA-Z0-9-_]+$/))\n .min(1)\n .describe('Canonical token names (CSS variable form) to resolve, e.g., --color-primary.'),\n includeAllModes: z\n .boolean()\n .describe('Include all token modes instead of just the active one; default false.')\n .optional()\n})\n\nexport type GetTokenDefsParametersInput = z.input<typeof GetTokenDefsParametersSchema>\nexport type GetTokenDefsResult = {\n tokens: Array<{\n name: string\n value: string | Record<string, unknown> | null\n current: {\n modeId: string\n value?: string | Record<string, unknown>\n aliasTo?: string\n resolved: string | Record<string, unknown> | null\n aliasChain?: string[]\n }\n modes?: Array<{\n modeId: string\n value?: string | Record<string, unknown>\n aliasTo?: string\n resolved: string | Record<string, unknown> | null\n }>\n collection?: {\n id?: string\n name?: string\n activeModeId?: string\n defaultModeId?: string\n }\n kind: 'color' | 'spacing' | 'typography' | 'effect' | 'other'\n }>\n}\n\nexport const AssetDescriptorSchema = z.object({\n hash: z.string().min(1),\n url: z.string().url(),\n mimeType: z.string().min(1),\n size: z.number().int().nonnegative(),\n resourceUri: z.string().regex(/^asset:\\/\\/tempad\\/[a-f0-9]{64}$/i),\n width: z.number().int().positive().optional(),\n height: z.number().int().positive().optional()\n})\n\n// get_screenshot\nexport const GetScreenshotParametersSchema = z.object({\n nodeId: z\n .string()\n .describe('Optional node id to screenshot; defaults to the current single selection.')\n .optional()\n})\n\nexport type GetScreenshotParametersInput = z.input<typeof GetScreenshotParametersSchema>\nexport type GetScreenshotResult = {\n format: 'png'\n width: number\n height: number\n scale: number\n bytes: number\n asset: AssetDescriptor\n}\n\n// get_structure\nexport const GetStructureParametersSchema = z.object({\n nodeId: z\n .string()\n .describe('Optional node id to outline; defaults to the current single selection.')\n .optional(),\n options: z\n .object({\n depth: z\n .number()\n .int()\n .positive()\n .describe('Limit traversal depth; defaults to full tree (subject to safety caps).')\n .optional()\n })\n .optional()\n})\n\nexport type GetStructureParametersInput = z.input<typeof GetStructureParametersSchema>\nexport type OutlineNode = {\n id: string\n name: string\n type: string\n x: number\n y: number\n width: number\n height: number\n children?: OutlineNode[]\n}\nexport type GetStructureResult = {\n roots: OutlineNode[]\n}\n\n// get_assets (hub only)\nexport const GetAssetsParametersSchema = z.object({\n hashes: z\n .array(z.string().regex(MCP_HASH_PATTERN))\n .min(1)\n .describe('Asset hashes returned from other tools to download/resolve.')\n})\n\nexport const GetAssetsResultSchema = z.object({\n assets: z.array(AssetDescriptorSchema),\n missing: z.array(z.string().min(1))\n})\n\nexport type GetAssetsParametersInput = z.input<typeof GetAssetsParametersSchema>\nexport type GetAssetsResult = z.infer<typeof GetAssetsResultSchema>\n\nexport type ToolResultMap = {\n get_code: GetCodeResult\n get_token_defs: GetTokenDefsResult\n get_screenshot: GetScreenshotResult\n get_structure: GetStructureResult\n get_assets: GetAssetsResult\n}\n\nexport type ToolName = keyof ToolResultMap\n\nexport { MCP_INSTRUCTIONS } from './instructions'\n\ntype BaseToolMetadata<Name extends ToolName, Schema extends ZodType> = {\n name: Name\n description: string\n parameters: Schema\n exposed?: boolean\n format?: (payload: ToolResultMap[Name]) => CallToolResult\n}\n\ntype ExtensionToolMetadata<Name extends ToolName, Schema extends ZodType> = BaseToolMetadata<\n Name,\n Schema\n> & {\n target: 'extension'\n}\n\ntype HubToolMetadata<Name extends ToolName, Schema extends ZodType> = BaseToolMetadata<\n Name,\n Schema\n> & {\n target: 'hub'\n outputSchema?: ZodType\n}\n\nfunction extTool<Name extends ToolName, Schema extends ZodType>(\n definition: ExtensionToolMetadata<Name, Schema>\n): ExtensionToolMetadata<Name, Schema> {\n return definition\n}\n\nfunction hubTool<Name extends ToolName, Schema extends ZodType>(\n definition: HubToolMetadata<Name, Schema>\n): HubToolMetadata<Name, Schema> {\n return definition\n}\n\nexport const TOOL_DEFS = [\n extTool({\n name: 'get_code',\n description:\n 'Get a high-fidelity code snapshot for a nodeId (or current selection), including assets/usedTokens and `codegen` preset/config.',\n parameters: GetCodeParametersSchema,\n target: 'extension',\n format: createCodeToolResponse\n }),\n extTool({\n name: 'get_token_defs',\n description:\n 'Resolve canonical token names to values (including modes) for tokens referenced by `get_code`.',\n parameters: GetTokenDefsParametersSchema,\n target: 'extension',\n exposed: false\n }),\n extTool({\n name: 'get_screenshot',\n description:\n 'Capture a rendered screenshot for a nodeId (or current selection) for visual verification.',\n parameters: GetScreenshotParametersSchema,\n target: 'extension',\n format: createScreenshotToolResponse\n }),\n extTool({\n name: 'get_structure',\n description:\n 'Get a structural + geometry outline for a nodeId (or current selection) to understand hierarchy and layout intent.',\n parameters: GetStructureParametersSchema,\n target: 'extension'\n }),\n hubTool({\n name: 'get_assets',\n description:\n 'Resolve asset hashes to downloadable URLs/URIs for assets referenced by `get_code`.',\n parameters: GetAssetsParametersSchema,\n target: 'hub',\n outputSchema: GetAssetsResultSchema,\n exposed: false\n })\n] as const\n\nfunction createToolErrorResponse(toolName: string, error: unknown): CallToolResult {\n const message =\n error instanceof Error\n ? error.message || 'Unknown error occurred.'\n : typeof error === 'string'\n ? error\n : 'Unknown error occurred.'\n return {\n content: [\n {\n type: 'text' as const,\n text: `Tool \"${toolName}\" failed: ${message}`\n }\n ]\n }\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n\nexport function createCodeToolResponse(payload: ToolResultMap['get_code']): CallToolResult {\n if (!isCodeResult(payload)) {\n throw new Error('Invalid get_code payload received from extension.')\n }\n\n const summary: string[] = []\n const codeSize = Buffer.byteLength(payload.code, 'utf8')\n summary.push(`Generated ${payload.lang.toUpperCase()} snippet (${formatBytes(codeSize)}).`)\n if (payload.message) {\n summary.push(payload.message)\n }\n summary.push(\n payload.assets.length\n ? `Assets attached: ${payload.assets.length}. Fetch bytes via resources/read using resourceUri.`\n : 'No binary assets were attached to this response.'\n )\n if (payload.usedTokens?.length) {\n summary.push(`Token references included: ${payload.usedTokens.length}.`)\n }\n summary.push('Read structuredContent for the full code string and asset metadata.')\n\n const assetLinks =\n payload.assets.length > 0\n ? payload.assets.map((asset) => createAssetResourceLinkBlock(asset))\n : []\n\n return {\n content: [\n {\n type: 'text' as const,\n text: summary.join('\\n')\n },\n ...assetLinks\n ],\n structuredContent: payload\n }\n}\n\nexport function createScreenshotToolResponse(\n payload: ToolResultMap['get_screenshot']\n): CallToolResult {\n if (!isScreenshotResult(payload)) {\n throw new Error('Invalid get_screenshot payload received from extension.')\n }\n\n const descriptionBlock = {\n type: 'text' as const,\n text: describeScreenshot(payload)\n }\n\n return {\n content: [\n descriptionBlock,\n {\n type: 'text' as const,\n text: ``\n },\n createResourceLinkBlock(payload.asset, payload)\n ],\n structuredContent: payload\n }\n}\n\nfunction createResourceLinkBlock(asset: AssetDescriptor, result: GetScreenshotResult) {\n return {\n type: 'resource_link' as const,\n name: 'Screenshot',\n uri: asset.resourceUri,\n mimeType: asset.mimeType,\n description: `Screenshot ${result.width}x${result.height} @${result.scale}x - Download: ${asset.url}`\n }\n}\n\nfunction describeScreenshot(result: GetScreenshotResult): string {\n return `Screenshot ${result.width}x${result.height} @${result.scale}x (${formatBytes(result.bytes)})`\n}\n\nfunction isScreenshotResult(payload: unknown): payload is GetScreenshotResult {\n if (typeof payload !== 'object' || !payload) return false\n const candidate = payload as Partial<GetScreenshotResult & Record<string, unknown>>\n return (\n typeof candidate.asset === 'object' &&\n candidate.asset !== null &&\n typeof candidate.width === 'number' &&\n typeof candidate.height === 'number' &&\n typeof candidate.scale === 'number' &&\n typeof candidate.bytes === 'number' &&\n typeof candidate.format === 'string'\n )\n}\n\nfunction isCodeResult(payload: unknown): payload is ToolResultMap['get_code'] {\n if (typeof payload !== 'object' || !payload) return false\n const candidate = payload as Partial<ToolResultMap['get_code'] & Record<string, unknown>>\n return (\n typeof candidate.code === 'string' &&\n typeof candidate.lang === 'string' &&\n Array.isArray(candidate.assets)\n )\n}\n\nfunction createAssetResourceLinkBlock(asset: AssetDescriptor) {\n return {\n type: 'resource_link' as const,\n name: formatAssetResourceName(asset.hash),\n uri: asset.resourceUri,\n mimeType: asset.mimeType,\n description: `${describeAsset(asset)} - Download: ${asset.url}`\n }\n}\n\nfunction describeAsset(asset: AssetDescriptor): string {\n return `${asset.mimeType} (${formatBytes(asset.size)})`\n}\n\nfunction formatAssetResourceName(hash: string): string {\n return `asset:${hash.slice(0, 8)}`\n}\n\nexport function coercePayloadToToolResponse(payload: unknown): CallToolResult {\n if (\n payload &&\n typeof payload === 'object' &&\n Array.isArray((payload as CallToolResult).content)\n ) {\n return payload as CallToolResult\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: typeof payload === 'string' ? payload : JSON.stringify(payload, null, 2)\n }\n ]\n }\n}\n\nexport { createToolErrorResponse }\n", "export const MCP_INSTRUCTIONS = `\n## MCP Server Instructions (Design to Code)\n\nYou are connected to a Figma design file via the MCP server. Help convert design elements into code, preserving design intent and fitting the user\u2019s codebase conventions.\n\n### P0 (must)\n\n- Do not output \\`data-hint*\\` attributes. They are guidance only.\n- For SVG/vector assets: use the exact provided asset (preserve \\`path\\` data and \\`viewBox\\`). Never redraw or approximate vectors.\n\n### P1 (policy)\n\n- Prefer calling \\`get_structure\\` early to understand hierarchy and layout intent.\n- Treat \\`get_code\\` as the implementation baseline; refine it to match the current project\u2019s conventions.\n- Use \\`get_screenshot\\` only when structure and hints cannot resolve major ambiguities, or to sanity-check the final result.\n\n### Layout uncertainty (\\`data-hint-auto-layout\\`)\n\n- If \\`data-hint-auto-layout\\` is \\`none\\` or \\`inferred\\`, treat layout as uncertain.\n- Use \\`get_structure\\` geometry (positions, sizes, gaps, alignment, bounds) to choose layout. Prefer flex/grid when patterns support it; use absolute only when necessary.\n\n### Component intent (\\`data-hint-component\\`)\n\n- If \\`data-hint-component\\` suggests a reusable component/variant and repetition supports it, factor it into a component API (props/variants). Do not preserve the hint string in output.\n\n### Assets and tokens\n\n- If \\`get_code\\` references assets or tokens, handle them according to the current project\u2019s conventions (local asset paths, existing token/variable systems, theming rules).\n`.trim()\n"],
|
|
5
|
-
"mappings": "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",
|
|
3
|
+
"sources": ["../src/hub.ts", "../../mcp/shared/constants.ts", "../src/asset-http-server.ts", "../src/config.ts", "../src/shared.ts", "../package.json", "../src/asset-store.ts", "../src/protocol.ts", "../src/request.ts", "../src/tools.ts", "../src/instructions.md"],
|
|
4
|
+
"sourcesContent": ["import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { RawData } from 'ws'\nimport type { ZodType } from 'zod'\n\nimport { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { nanoid } from 'nanoid'\nimport { existsSync, rmSync, chmodSync, readFileSync, statSync } from 'node:fs'\nimport { createServer } from 'node:net'\nimport { WebSocketServer } from 'ws'\n\nimport type {\n AssetDescriptor,\n GetAssetsParametersInput,\n GetAssetsResult,\n ToolResultMap,\n ToolName\n} from './tools'\nimport type { AssetRecord, ExtensionConnection } from './types'\n\nimport {\n MCP_ASSET_RESOURCE_NAME,\n MCP_ASSET_URI_PREFIX,\n MCP_ASSET_URI_TEMPLATE\n} from '../../mcp/shared/constants'\nimport { createAssetHttpServer } from './asset-http-server'\nimport { createAssetStore } from './asset-store'\nimport { getMcpServerConfig } from './config'\nimport {\n MessageFromExtensionSchema,\n RegisteredMessage,\n StateMessage,\n ToolCallMessage,\n ToolResultMessage\n} from './protocol'\nimport { register, resolve, reject, cleanupForExtension, cleanupAll } from './request'\nimport { PACKAGE_VERSION, log, RUNTIME_DIR, SOCK_PATH, ensureDir } from './shared'\nimport {\n GetAssetsResultSchema,\n TOOL_DEFS,\n MCP_INSTRUCTIONS,\n coercePayloadToToolResponse,\n createToolErrorResponse\n} from './tools'\n\nconst SHUTDOWN_TIMEOUT = 2000\nconst { wsPortCandidates, toolTimeoutMs, maxPayloadBytes, autoActivateGraceMs } =\n getMcpServerConfig()\n\nlog.info({ version: PACKAGE_VERSION }, 'TemPad MCP Hub starting...')\n\nconst extensions: ExtensionConnection[] = []\nlet consumerCount = 0\ntype TimeoutHandle = ReturnType<typeof setTimeout>\nlet autoActivateTimer: TimeoutHandle | null = null\nlet selectedWsPort = 0\n\nconst mcp = new McpServer(\n { name: 'tempad-dev-mcp', version: PACKAGE_VERSION },\n MCP_INSTRUCTIONS ? { instructions: MCP_INSTRUCTIONS } : undefined\n)\ntype McpInputSchema = Parameters<typeof mcp.registerTool>[1]['inputSchema']\ntype McpOutputSchema = Parameters<typeof mcp.registerTool>[1]['outputSchema']\ntype ToolResponse = CallToolResult\ntype SchemaOutput<Schema extends ZodType> = Schema['_output']\ntype ToolMetadataEntry = (typeof TOOL_DEFS)[number]\ntype ExtensionToolMetadata = Extract<ToolMetadataEntry, { target: 'extension' }>\ntype HubToolMetadata = Extract<ToolMetadataEntry, { target: 'hub' }>\n\ntype HubToolWithHandler<T extends HubToolMetadata = HubToolMetadata> = T & {\n handler: (args: SchemaOutput<T['parameters']>) => Promise<ToolResponse>\n}\n\ntype RegisteredToolDefinition = ExtensionToolMetadata | HubToolWithHandler\n\nfunction enrichToolDefinition(tool: ToolMetadataEntry): RegisteredToolDefinition {\n if (tool.target === 'extension') {\n return tool\n }\n\n switch (tool.name) {\n case 'get_assets':\n return {\n ...tool,\n handler: handleGetAssets\n } satisfies HubToolWithHandler\n default:\n throw new Error('No handler configured for hub tool.')\n }\n}\n\nconst TOOL_DEFINITIONS: ReadonlyArray<RegisteredToolDefinition> = TOOL_DEFS.map((tool) =>\n enrichToolDefinition(tool)\n)\n\ntype RegisteredTool = (typeof TOOL_DEFINITIONS)[number]\ntype ExtensionTool = Extract<RegisteredTool, { target: 'extension' }>\ntype HubOnlyTool = Extract<RegisteredTool, { target: 'hub' }>\n\nfunction hasFormatter(tool: RegisteredToolDefinition): tool is ExtensionTool & {\n format: (payload: unknown) => ToolResponse\n} {\n return tool.target === 'extension' && 'format' in tool\n}\n\ntype ToolDefinitionByName = {\n [T in RegisteredToolDefinition as T['name']]: T\n}\n\nconst TOOL_BY_NAME: ToolDefinitionByName = Object.fromEntries(\n TOOL_DEFINITIONS.map((tool) => [tool.name, tool] as const)\n) as ToolDefinitionByName\n\nfunction getToolDefinition<Name extends ToolName>(name: Name): ToolDefinitionByName[Name] {\n return TOOL_BY_NAME[name]\n}\n\nconst assetStore = createAssetStore()\nconst assetHttpServer = createAssetHttpServer(assetStore)\nawait assetHttpServer.start()\nregisterAssetResources()\n\nfunction registerAssetResources(): void {\n const template = new ResourceTemplate(MCP_ASSET_URI_TEMPLATE, {\n list: async () => ({\n resources: assetStore\n .list()\n .filter((record) => existsSync(record.filePath))\n .map((record) => ({\n uri: buildAssetResourceUri(record.hash),\n name: formatAssetResourceName(record.hash),\n description: `${record.mimeType} (${formatBytes(record.size)})`,\n mimeType: record.mimeType\n }))\n })\n })\n\n mcp.registerResource(\n MCP_ASSET_RESOURCE_NAME,\n template,\n {\n description: 'Binary assets captured by the TemPad Dev hub.'\n },\n async (_uri, variables) => {\n const hash = typeof variables.hash === 'string' ? variables.hash : ''\n return readAssetResource(hash)\n }\n )\n}\n\nasync function readAssetResource(hash: string) {\n if (!hash) {\n throw new Error('Missing asset hash in resource URI.')\n }\n const record = assetStore.get(hash)\n if (!record) {\n throw new Error(`Asset ${hash} not found.`)\n }\n\n if (!existsSync(record.filePath)) {\n assetStore.remove(hash, { removeFile: false })\n throw new Error(`Asset ${hash} file is missing.`)\n }\n\n const stat = statSync(record.filePath)\n // Base64 encoding increases size by ~33% (4 bytes for every 3 bytes)\n const estimatedSize = Math.ceil(stat.size / 3) * 4\n if (estimatedSize > maxPayloadBytes) {\n throw new Error(\n `Asset ${hash} is too large (${formatBytes(stat.size)}, encoded: ${formatBytes(estimatedSize)}) to read via MCP protocol. Use HTTP download.`\n )\n }\n\n assetStore.touch(hash)\n const buffer = readFileSync(record.filePath)\n const resourceUri = buildAssetResourceUri(hash)\n\n if (isTextualMime(record.mimeType)) {\n return {\n contents: [\n {\n uri: resourceUri,\n mimeType: record.mimeType,\n text: buffer.toString('utf8')\n }\n ]\n }\n }\n\n return {\n contents: [\n {\n uri: resourceUri,\n mimeType: record.mimeType,\n blob: buffer.toString('base64')\n }\n ]\n }\n}\n\nfunction isTextualMime(mimeType: string): boolean {\n return mimeType === 'image/svg+xml' || mimeType.startsWith('text/')\n}\n\nfunction buildAssetResourceUri(hash: string): string {\n return `${MCP_ASSET_URI_PREFIX}${hash}`\n}\n\nfunction formatAssetResourceName(hash: string): string {\n return `asset:${hash.slice(0, 8)}`\n}\n\nfunction buildAssetDescriptor(record: AssetRecord): AssetDescriptor {\n return {\n hash: record.hash,\n url: `${assetHttpServer.getBaseUrl()}/assets/${record.hash}`,\n mimeType: record.mimeType,\n size: record.size,\n resourceUri: buildAssetResourceUri(record.hash),\n width: record.metadata?.width,\n height: record.metadata?.height\n }\n}\n\nfunction createAssetResourceLinkBlock(asset: AssetDescriptor) {\n return {\n type: 'resource_link' as const,\n name: formatAssetResourceName(asset.hash),\n uri: asset.resourceUri,\n mimeType: asset.mimeType,\n description: `${describeAsset(asset)} - Download: ${asset.url}`\n }\n}\n\nfunction describeAsset(asset: AssetDescriptor): string {\n return `${asset.mimeType} (${formatBytes(asset.size)})`\n}\n\nfunction registerTools(): void {\n const registered: string[] = []\n for (const tool of TOOL_DEFINITIONS) {\n if ('exposed' in tool && tool.exposed === false) continue\n registerTool(tool)\n registered.push(tool.name)\n }\n log.info({ tools: registered }, 'Registered tools.')\n}\n\nregisterTools()\nfunction registerTool(tool: RegisteredTool): void {\n if (tool.target === 'extension') {\n registerProxiedTool(tool)\n } else {\n registerLocalTool(tool)\n }\n}\n\nfunction registerProxiedTool<T extends ExtensionTool>(tool: T): void {\n type Name = T['name']\n type Result = ToolResultMap[Name]\n\n const schema = tool.parameters\n mcp.registerTool(\n tool.name,\n {\n description: tool.description,\n inputSchema: schema as unknown as McpInputSchema\n },\n async (args: unknown) => {\n try {\n const parsedArgs = schema.parse(args)\n const activeExt = extensions.find((e) => e.active)\n if (!activeExt) throw new Error('No active TemPad Dev extension available.')\n\n const { promise, requestId } = register<Result>(activeExt.id, toolTimeoutMs)\n\n const message: ToolCallMessage = {\n type: 'toolCall',\n id: requestId,\n payload: {\n name: tool.name,\n args: parsedArgs\n }\n }\n activeExt.ws.send(JSON.stringify(message))\n log.info({ tool: tool.name, req: requestId, extId: activeExt.id }, 'Forwarded tool call.')\n\n const payload = await promise\n return createToolResponse(tool.name, payload)\n } catch (error) {\n log.error({ tool: tool.name, error }, 'Tool invocation failed before reaching extension.')\n return createToolErrorResponse(tool.name, error)\n }\n }\n )\n}\n\nfunction registerLocalTool(tool: HubOnlyTool): void {\n const schema = tool.parameters\n const handler = tool.handler\n\n const registrationOptions: {\n description: string\n inputSchema: McpInputSchema\n outputSchema?: McpOutputSchema\n } = {\n description: tool.description,\n inputSchema: schema as unknown as McpInputSchema\n }\n\n if (tool.outputSchema) {\n registrationOptions.outputSchema = tool.outputSchema as unknown as McpOutputSchema\n }\n\n mcp.registerTool(tool.name, registrationOptions, async (args: unknown) => {\n try {\n const parsed = schema.parse(args)\n return await handler(parsed)\n } catch (error) {\n log.error({ tool: tool.name, error }, 'Local tool invocation failed.')\n return createToolErrorResponse(tool.name, error)\n }\n })\n}\n\nfunction createToolResponse<Name extends ToolName>(\n toolName: Name,\n payload: ToolResultMap[Name]\n): ToolResponse {\n const definition = getToolDefinition(toolName)\n if (definition && hasFormatter(definition)) {\n try {\n const formatter = definition.format as (input: ToolResultMap[Name]) => ToolResponse\n return formatter(payload)\n } catch (error) {\n log.warn({ tool: toolName, error }, 'Failed to format tool result; returning raw payload.')\n return coercePayloadToToolResponse(payload)\n }\n }\n\n return coercePayloadToToolResponse(payload)\n}\n\nasync function handleGetAssets({ hashes }: GetAssetsParametersInput): Promise<ToolResponse> {\n if (hashes.length > 100) {\n throw new Error('Too many hashes requested. Limit is 100.')\n }\n const unique = Array.from(new Set(hashes))\n const records = assetStore.getMany(unique).filter((record) => {\n if (existsSync(record.filePath)) return true\n assetStore.remove(record.hash, { removeFile: false })\n return false\n })\n const found = new Set(records.map((record) => record.hash))\n const payload: GetAssetsResult = GetAssetsResultSchema.parse({\n assets: records.map((record) => buildAssetDescriptor(record)),\n missing: unique.filter((hash) => !found.has(hash))\n })\n\n const summary: string[] = []\n summary.push(\n payload.assets.length\n ? `Resolved ${payload.assets.length} asset${payload.assets.length === 1 ? '' : 's'}.`\n : 'No assets were resolved for the requested hashes.'\n )\n if (payload.missing.length) {\n summary.push(`Missing: ${payload.missing.join(', ')}`)\n }\n summary.push(\n 'Use resources/read with each resourceUri or fetch the fallback URL to download bytes.'\n )\n\n const content = [\n {\n type: 'text' as const,\n text: summary.join('\\n')\n },\n ...payload.assets.map((asset) => createAssetResourceLinkBlock(asset))\n ]\n\n return {\n content,\n structuredContent: payload\n }\n}\n\nfunction getActiveId(): string | null {\n return extensions.find((e) => e.active)?.id ?? null\n}\n\nfunction setActive(targetId: string | null): void {\n extensions.forEach((e) => {\n e.active = targetId !== null && e.id === targetId\n })\n}\n\nfunction clearAutoActivateTimer(): void {\n if (autoActivateTimer) {\n clearTimeout(autoActivateTimer)\n autoActivateTimer = null\n }\n}\n\nfunction scheduleAutoActivate(): void {\n clearAutoActivateTimer()\n\n if (extensions.length !== 1 || getActiveId()) {\n return\n }\n\n const target = extensions[0]\n autoActivateTimer = setTimeout(() => {\n autoActivateTimer = null\n if (extensions.length === 1 && !getActiveId()) {\n setActive(target.id)\n log.info({ id: target.id }, 'Auto-activated sole extension after grace period.')\n broadcastState()\n }\n }, autoActivateGraceMs)\n}\n\nfunction unrefTimer(timer: TimeoutHandle): void {\n if (typeof timer === 'object' && timer !== null) {\n const handle = timer as NodeJS.Timeout\n if (typeof handle.unref === 'function') {\n handle.unref()\n }\n }\n}\n\nfunction broadcastState(): void {\n const activeId = getActiveId()\n const message: StateMessage = {\n type: 'state',\n activeId,\n count: extensions.length,\n port: selectedWsPort,\n assetServerUrl: assetHttpServer.getBaseUrl()\n }\n extensions.forEach((ext) => ext.ws.send(JSON.stringify(message)))\n log.debug({ activeId, count: extensions.length }, 'Broadcasted state.')\n}\n\nfunction rawDataToBuffer(raw: RawData): Buffer {\n if (typeof raw === 'string') return Buffer.from(raw)\n if (Buffer.isBuffer(raw)) return raw\n if (raw instanceof ArrayBuffer) return Buffer.from(raw)\n return Buffer.concat(raw)\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n\nfunction shutdown(): void {\n log.info('Hub is shutting down...')\n assetStore.flush()\n assetHttpServer.stop()\n netServer.close(() => log.info('Net server closed.'))\n wss?.close(() => log.info('WebSocket server closed.'))\n cleanupAll()\n const timer = setTimeout(() => {\n log.warn('Shutdown timed out. Forcing exit.')\n process.exit(1)\n }, SHUTDOWN_TIMEOUT)\n unrefTimer(timer)\n}\n\ntry {\n ensureDir(RUNTIME_DIR)\n if (process.platform !== 'win32' && existsSync(SOCK_PATH)) {\n log.warn({ sock: SOCK_PATH }, 'Removing stale socket file.')\n rmSync(SOCK_PATH)\n }\n} catch (error: unknown) {\n log.error({ err: error }, 'Failed to initialize runtime environment.')\n process.exit(1)\n}\n\nconst netServer = createServer((sock) => {\n consumerCount++\n log.info(`Consumer connected. Total: ${consumerCount}`)\n const transport = new StdioServerTransport(sock, sock)\n mcp.connect(transport).catch((err) => {\n log.error({ err }, 'Failed to attach MCP transport.')\n transport.close().catch((closeErr) => log.warn({ err: closeErr }, 'Transport close failed.'))\n sock.destroy()\n })\n sock.on('error', (err) => {\n log.warn({ err }, 'Consumer socket error.')\n transport.close().catch((closeErr) => log.warn({ err: closeErr }, 'Transport close failed.'))\n })\n sock.on('close', async () => {\n await transport.close()\n consumerCount--\n log.info(`Consumer disconnected. Remaining: ${consumerCount}`)\n if (consumerCount === 0) {\n log.info('Last consumer disconnected. Shutting down.')\n shutdown()\n }\n })\n})\nnetServer.on('error', (err) => {\n log.error({ err }, 'Net server error.')\n process.exit(1)\n})\nnetServer.listen(SOCK_PATH, () => {\n try {\n if (process.platform !== 'win32') chmodSync(SOCK_PATH, 0o600)\n } catch (err) {\n log.error({ err }, 'Failed to set socket permissions. Shutting down.')\n process.exit(1)\n }\n log.info({ sock: SOCK_PATH }, 'Hub socket ready.')\n})\n\nasync function startWebSocketServer(): Promise<{ wss: WebSocketServer; port: number }> {\n for (const candidate of wsPortCandidates) {\n const server = new WebSocketServer({\n host: '127.0.0.1',\n port: candidate,\n maxPayload: maxPayloadBytes\n })\n\n try {\n await new Promise<void>((resolve, reject) => {\n const onError = (err: NodeJS.ErrnoException) => {\n server.off('listening', onListening)\n reject(err)\n }\n const onListening = () => {\n server.off('error', onError)\n resolve()\n }\n server.once('error', onError)\n server.once('listening', onListening)\n })\n return { wss: server, port: candidate }\n } catch (err) {\n server.close()\n const errno = err as NodeJS.ErrnoException\n if (errno.code === 'EADDRINUSE') {\n log.warn({ port: candidate }, 'WebSocket port in use, trying next candidate.')\n continue\n }\n log.error({ err: errno, port: candidate }, 'Failed to start WebSocket server.')\n process.exit(1)\n }\n }\n\n log.error(\n { candidates: wsPortCandidates },\n 'Unable to start WebSocket server on any candidate port.'\n )\n process.exit(1)\n}\n\nconst { wss, port } = await startWebSocketServer()\nselectedWsPort = port\n\n// Add an error handler to prevent crashes from port conflicts, etc.\nwss.on('error', (err) => {\n log.error({ err }, 'WebSocket server critical error. Exiting.')\n process.exit(1)\n})\n\nwss.on('connection', (ws) => {\n const ext: ExtensionConnection = { id: nanoid(), ws, active: false }\n extensions.push(ext)\n log.info({ id: ext.id }, `Extension connected. Total: ${extensions.length}`)\n\n const message: RegisteredMessage = { type: 'registered', id: ext.id }\n ws.send(JSON.stringify(message))\n broadcastState()\n scheduleAutoActivate()\n\n ws.on('message', (raw: RawData, isBinary: boolean) => {\n if (isBinary) {\n log.warn({ extId: ext.id }, 'Unexpected binary message received.')\n return\n }\n\n const messageBuffer = rawDataToBuffer(raw)\n\n let parsedJson: unknown\n try {\n parsedJson = JSON.parse(messageBuffer.toString('utf-8'))\n } catch (e: unknown) {\n log.warn({ err: e, extId: ext.id }, 'Failed to parse message.')\n return\n }\n\n const parseResult = MessageFromExtensionSchema.safeParse(parsedJson)\n if (!parseResult.success) {\n log.warn({ error: parseResult.error.flatten(), extId: ext.id }, 'Invalid message shape.')\n return\n }\n const msg = parseResult.data\n\n switch (msg.type) {\n case 'activate': {\n setActive(ext.id)\n log.info({ id: ext.id }, 'Extension activated.')\n broadcastState()\n scheduleAutoActivate()\n break\n }\n case 'toolResult': {\n const { id, payload, error } = msg as ToolResultMessage\n if (error) {\n reject(id, error instanceof Error ? error : new Error(String(error)))\n } else {\n resolve(id, payload)\n }\n break\n }\n }\n })\n\n ws.on('close', () => {\n const index = extensions.findIndex((e) => e.id === ext.id)\n if (index > -1) extensions.splice(index, 1)\n\n log.info({ id: ext.id }, `Extension disconnected. Remaining: ${extensions.length}`)\n cleanupForExtension(ext.id)\n\n if (ext.active) {\n log.warn({ id: ext.id }, 'Active extension disconnected.')\n setActive(null)\n }\n\n broadcastState()\n scheduleAutoActivate()\n })\n})\n\nlog.info({ port: selectedWsPort }, 'WebSocket server ready.')\n\nprocess.on('SIGINT', shutdown)\nprocess.on('SIGTERM', shutdown)\n", "export const MCP_PORT_CANDIDATES = [6220, 7431, 8127]\n\n// Upper bound for MCP message payloads in bytes.\nexport const MCP_MAX_PAYLOAD_BYTES = 4 * 1024 * 1024\n\n// Default tool timeout used by the MCP hub (ms).\nexport const MCP_TOOL_TIMEOUT_MS = 15000\n\n// Grace period before auto-activating the sole extension (ms).\nexport const MCP_AUTO_ACTIVATE_GRACE_MS = 1500\n\n// Maximum allowed size for uploaded assets (bytes).\nexport const MCP_MAX_ASSET_BYTES = 8 * 1024 * 1024\n\nexport const MCP_ASSET_RESOURCE_NAME = 'tempad-assets'\nexport const MCP_ASSET_URI_PREFIX = 'asset://tempad/'\nexport const MCP_ASSET_URI_TEMPLATE = `${MCP_ASSET_URI_PREFIX}{hash}`\n\nexport const MCP_HASH_PATTERN = /^[a-f0-9]{64}$/i\n", "import { nanoid } from 'nanoid'\nimport { createHash } from 'node:crypto'\nimport {\n createReadStream,\n createWriteStream,\n existsSync,\n renameSync,\n statSync,\n unlinkSync\n} from 'node:fs'\nimport { createServer, type IncomingMessage, type ServerResponse } from 'node:http'\nimport { join } from 'node:path'\nimport { pipeline, Transform } from 'node:stream'\nimport { URL } from 'node:url'\n\nimport type { AssetStore } from './asset-store'\n\nimport { MCP_HASH_PATTERN } from '../../mcp/shared/constants'\nimport { getMcpServerConfig } from './config'\nimport { ASSET_DIR, log } from './shared'\n\nconst LOOPBACK_HOST = '127.0.0.1'\nconst { maxAssetSizeBytes } = getMcpServerConfig()\n\nexport interface AssetHttpServer {\n start(): Promise<void>\n stop(): void\n getBaseUrl(): string\n}\n\nexport function createAssetHttpServer(store: AssetStore): AssetHttpServer {\n const server = createServer(handleRequest)\n let port: number | null = null\n\n async function start(): Promise<void> {\n if (port !== null) return\n await new Promise<void>((resolve, reject) => {\n const onError = (error: Error) => {\n server.off('listening', onListening)\n reject(error)\n }\n const onListening = () => {\n server.off('error', onError)\n const address = server.address()\n if (address && typeof address === 'object') {\n port = address.port\n resolve()\n } else {\n reject(new Error('Failed to determine HTTP server port.'))\n }\n }\n server.once('error', onError)\n server.once('listening', onListening)\n server.listen(0, LOOPBACK_HOST)\n })\n log.info({ port }, 'Asset HTTP server ready.')\n }\n\n function stop(): void {\n if (port === null) return\n server.close()\n port = null\n }\n\n function getBaseUrl(): string {\n if (port === null) throw new Error('Asset HTTP server is not running.')\n return `http://${LOOPBACK_HOST}:${port}`\n }\n\n function handleRequest(req: IncomingMessage, res: ServerResponse): void {\n res.setHeader('Access-Control-Allow-Origin', '*')\n res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')\n res.setHeader('Access-Control-Allow-Headers', 'Content-Type, X-Asset-Width, X-Asset-Height')\n\n if (req.method === 'OPTIONS') {\n res.writeHead(204)\n res.end()\n return\n }\n\n if (!req.url) {\n res.writeHead(400)\n res.end('Missing URL')\n return\n }\n\n const url = new URL(req.url, getBaseUrl())\n const segments = url.pathname.split('/').filter(Boolean)\n if (segments.length !== 2 || segments[0] !== 'assets') {\n res.writeHead(404)\n res.end('Not Found')\n return\n }\n\n const hash = segments[1]\n\n if (req.method === 'POST') {\n handleUpload(req, res, hash)\n return\n }\n\n if (req.method === 'GET') {\n handleDownload(req, res, hash)\n return\n }\n\n res.writeHead(405)\n res.end('Method Not Allowed')\n }\n\n function handleDownload(req: IncomingMessage, res: ServerResponse, hash: string): void {\n const record = store.get(hash)\n if (!record) {\n res.writeHead(404)\n res.end('Not Found')\n return\n }\n\n let stat\n try {\n stat = statSync(record.filePath)\n } catch (error) {\n const err = error as NodeJS.ErrnoException\n if (err.code === 'ENOENT') {\n store.remove(hash, { removeFile: false })\n res.writeHead(404)\n res.end('Not Found')\n } else {\n log.error({ error, hash }, 'Failed to stat asset file.')\n res.writeHead(500)\n res.end('Internal Server Error')\n }\n return\n }\n\n res.writeHead(200, {\n 'Content-Type': record.mimeType,\n 'Content-Length': stat.size.toString(),\n 'Cache-Control': 'public, max-age=31536000, immutable'\n })\n\n const stream = createReadStream(record.filePath)\n stream.on('error', (error) => {\n log.warn({ error, hash }, 'Failed to stream asset file.')\n if (!res.headersSent) {\n res.writeHead(500)\n }\n res.end('Internal Server Error')\n })\n stream.on('open', () => {\n store.touch(hash)\n })\n stream.pipe(res)\n }\n\n function handleUpload(req: IncomingMessage, res: ServerResponse, hash: string): void {\n if (!MCP_HASH_PATTERN.test(hash)) {\n res.writeHead(400)\n res.end('Invalid Hash Format')\n return\n }\n\n const mimeType = req.headers['content-type'] || 'application/octet-stream'\n const filePath = join(ASSET_DIR, hash)\n\n const width = parseInt(req.headers['x-asset-width'] as string, 10)\n const height = parseInt(req.headers['x-asset-height'] as string, 10)\n const metadata =\n !isNaN(width) && !isNaN(height) && width > 0 && height > 0 ? { width, height } : undefined\n\n // If asset already exists and file is present, skip write\n if (store.has(hash) && existsSync(filePath)) {\n // Drain request to ensure connection is clean\n req.resume()\n\n const existing = store.get(hash)!\n let changed = false\n if (metadata) {\n existing.metadata = metadata\n changed = true\n }\n if (existing.mimeType !== mimeType) {\n existing.mimeType = mimeType\n changed = true\n }\n if (changed) {\n store.upsert(existing)\n }\n store.touch(hash)\n res.writeHead(200)\n res.end('OK')\n return\n }\n\n const tmpPath = `${filePath}.tmp.${nanoid()}`\n const writeStream = createWriteStream(tmpPath)\n const hasher = createHash('sha256')\n let size = 0\n\n const cleanup = () => {\n if (existsSync(tmpPath)) {\n try {\n unlinkSync(tmpPath)\n } catch (e) {\n log.warn({ error: e, tmpPath }, 'Failed to cleanup temp file.')\n }\n }\n }\n\n const monitor = new Transform({\n transform(chunk, encoding, callback) {\n size += chunk.length\n if (size > maxAssetSizeBytes) {\n callback(new Error('PayloadTooLarge'))\n return\n }\n hasher.update(chunk)\n callback(null, chunk)\n }\n })\n\n pipeline(req, monitor, writeStream, (err) => {\n if (err) {\n cleanup()\n if (err.message === 'PayloadTooLarge') {\n res.writeHead(413)\n res.end('Payload Too Large')\n } else if (err.code === 'ERR_STREAM_PREMATURE_CLOSE') {\n log.warn({ hash }, 'Upload request closed prematurely.')\n } else {\n log.error({ error: err, hash }, 'Upload pipeline failed.')\n if (!res.headersSent) {\n res.writeHead(500)\n res.end('Internal Server Error')\n }\n }\n return\n }\n\n const computedHash = hasher.digest('hex')\n if (computedHash !== hash) {\n cleanup()\n res.writeHead(400)\n res.end('Hash Mismatch')\n return\n }\n\n try {\n renameSync(tmpPath, filePath)\n } catch (error) {\n log.error({ error, hash }, 'Failed to rename temp file to asset.')\n cleanup()\n res.writeHead(500)\n res.end('Internal Server Error')\n return\n }\n\n store.upsert({\n hash,\n filePath,\n mimeType,\n size,\n metadata\n })\n log.info({ hash, size }, 'Stored uploaded asset via HTTP.')\n res.writeHead(201)\n res.end('Created')\n })\n }\n\n return {\n start,\n stop,\n getBaseUrl\n }\n}\n", "import {\n MCP_AUTO_ACTIVATE_GRACE_MS,\n MCP_MAX_ASSET_BYTES,\n MCP_MAX_PAYLOAD_BYTES,\n MCP_PORT_CANDIDATES,\n MCP_TOOL_TIMEOUT_MS\n} from '../../mcp/shared/constants'\n\nfunction parsePositiveInt(envValue: string | undefined, fallback: number): number {\n const parsed = envValue ? Number.parseInt(envValue, 10) : Number.NaN\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback\n}\n\nfunction resolveToolTimeoutMs(): number {\n return parsePositiveInt(process.env.TEMPAD_MCP_TOOL_TIMEOUT, MCP_TOOL_TIMEOUT_MS)\n}\n\nfunction resolveAutoActivateGraceMs(): number {\n return parsePositiveInt(process.env.TEMPAD_MCP_AUTO_ACTIVATE_GRACE, MCP_AUTO_ACTIVATE_GRACE_MS)\n}\n\nfunction resolveMaxAssetSizeBytes(): number {\n return parsePositiveInt(process.env.TEMPAD_MCP_MAX_ASSET_BYTES, MCP_MAX_ASSET_BYTES)\n}\n\nexport function getMcpServerConfig() {\n return {\n wsPortCandidates: [...MCP_PORT_CANDIDATES],\n toolTimeoutMs: resolveToolTimeoutMs(),\n maxPayloadBytes: MCP_MAX_PAYLOAD_BYTES,\n autoActivateGraceMs: resolveAutoActivateGraceMs(),\n maxAssetSizeBytes: resolveMaxAssetSizeBytes()\n }\n}\n", "import { closeSync, mkdirSync, openSync } from 'node:fs'\nimport { tmpdir } from 'node:os'\nimport { join } from 'node:path'\nimport pino from 'pino'\n\nimport packageJson from '../package.json' assert { type: 'json' }\n\nexport function ensureDir(dirPath: string): void {\n mkdirSync(dirPath, { recursive: true, mode: 0o700 })\n}\n\nconst pkg = packageJson as { version?: unknown }\nexport const PACKAGE_VERSION = typeof pkg.version === 'string' ? pkg.version : '0.0.0'\n\nfunction resolveRuntimeDir(): string {\n if (process.env.TEMPAD_MCP_RUNTIME_DIR) return process.env.TEMPAD_MCP_RUNTIME_DIR\n return join(tmpdir(), 'tempad-dev', 'run')\n}\n\nfunction resolveLogDir(): string {\n if (process.env.TEMPAD_MCP_LOG_DIR) return process.env.TEMPAD_MCP_LOG_DIR\n return join(tmpdir(), 'tempad-dev', 'log')\n}\n\nfunction resolveAssetDir(): string {\n if (process.env.TEMPAD_MCP_ASSET_DIR) return process.env.TEMPAD_MCP_ASSET_DIR\n return join(tmpdir(), 'tempad-dev', 'assets')\n}\n\nexport const RUNTIME_DIR = resolveRuntimeDir()\nexport const LOG_DIR = resolveLogDir()\nexport const ASSET_DIR = resolveAssetDir()\n\nensureDir(RUNTIME_DIR)\nensureDir(LOG_DIR)\nensureDir(ASSET_DIR)\n\nexport function ensureFile(filePath: string): void {\n const fd = openSync(filePath, 'a')\n closeSync(fd)\n}\n\nexport const LOCK_PATH = join(RUNTIME_DIR, 'mcp.lock')\nensureFile(LOCK_PATH)\n\nconst timestamp = new Date().toISOString().replaceAll(':', '-').replaceAll('.', '-')\nconst pid = process.pid\nconst LOG_FILE = join(LOG_DIR, `mcp-${timestamp}-${pid}.log`)\n\nconst prettyTransport = pino.transport({\n target: 'pino-pretty',\n options: {\n translateTime: 'SYS:HH:MM:ss',\n destination: LOG_FILE\n }\n})\n\nexport const log = pino(\n {\n level: process.env.DEBUG ? 'debug' : 'info',\n msgPrefix: '[tempad-dev/mcp] '\n },\n prettyTransport\n)\n\nexport const SOCK_PATH =\n process.platform === 'win32' ? '\\\\\\\\.\\\\pipe\\\\tempad-mcp' : join(RUNTIME_DIR, 'mcp.sock')\n", "{\n \"name\": \"@tempad-dev/mcp\",\n \"description\": \"MCP server for TemPad Dev.\",\n \"version\": \"0.3.3\",\n \"type\": \"module\",\n \"main\": \"dist/cli.js\",\n \"bin\": \"dist/cli.js\",\n \"files\": [\n \"dist/**/*\",\n \"README.md\"\n ],\n \"scripts\": {\n \"build\": \"tsc -p ./tsconfig.json --noEmit && node ./scripts/build.mjs\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"dependencies\": {\n \"@modelcontextprotocol/sdk\": \"^1.22.0\",\n \"nanoid\": \"^5.1.6\",\n \"pino\": \"^9.14.0\",\n \"pino-pretty\": \"^11.2.2\",\n \"proper-lockfile\": \"^4.1.2\",\n \"ws\": \"^8.18.3\",\n \"zod\": \"^4.1.12\"\n }\n}\n", "import { existsSync, readFileSync, rmSync, writeFileSync, readdirSync, statSync } from 'node:fs'\nimport { join } from 'node:path'\n\nimport type { AssetRecord } from './types'\n\nimport { ASSET_DIR, ensureDir, ensureFile, log } from './shared'\n\nconst INDEX_FILENAME = 'assets.json'\nconst DEFAULT_INDEX_PATH = join(ASSET_DIR, INDEX_FILENAME)\n\nexport interface AssetStoreOptions {\n indexPath?: string\n}\n\nexport interface AssetStore {\n list(): AssetRecord[]\n has(hash: string): boolean\n get(hash: string): AssetRecord | undefined\n getMany(hashes: string[]): AssetRecord[]\n upsert(\n input: Omit<AssetRecord, 'uploadedAt' | 'lastAccess'> &\n Partial<Pick<AssetRecord, 'uploadedAt' | 'lastAccess'>>\n ): AssetRecord\n touch(hash: string): AssetRecord | undefined\n remove(hash: string, opts?: { removeFile?: boolean }): void\n reconcile(): void\n flush(): void\n}\n\nfunction readIndex(indexPath: string): AssetRecord[] {\n if (!existsSync(indexPath)) return []\n try {\n const raw = readFileSync(indexPath, 'utf8').trim()\n if (!raw) return []\n const parsed = JSON.parse(raw)\n return Array.isArray(parsed) ? (parsed as AssetRecord[]) : []\n } catch (error) {\n log.warn({ error, indexPath }, 'Failed to read asset catalog; starting fresh.')\n return []\n }\n}\n\nfunction writeIndex(indexPath: string, values: AssetRecord[]): void {\n const payload = JSON.stringify(values, null, 2)\n writeFileSync(indexPath, payload, 'utf8')\n}\n\nexport function createAssetStore(options: AssetStoreOptions = {}): AssetStore {\n ensureDir(ASSET_DIR)\n const indexPath = options.indexPath ?? DEFAULT_INDEX_PATH\n ensureFile(indexPath)\n const records = new Map<string, AssetRecord>()\n let persistTimer: NodeJS.Timeout | null = null\n\n function loadExisting(): void {\n const list = readIndex(indexPath)\n for (const record of list) {\n if (record?.hash && record?.filePath) {\n records.set(record.hash, record)\n }\n }\n }\n\n function persist(): void {\n if (persistTimer) return\n persistTimer = setTimeout(() => {\n persistTimer = null\n writeIndex(indexPath, [...records.values()])\n }, 5000)\n if (typeof persistTimer.unref === 'function') {\n persistTimer.unref()\n }\n }\n\n function flush(): void {\n if (persistTimer) {\n clearTimeout(persistTimer)\n persistTimer = null\n }\n writeIndex(indexPath, [...records.values()])\n }\n\n function list(): AssetRecord[] {\n return [...records.values()]\n }\n\n function has(hash: string): boolean {\n return records.has(hash)\n }\n\n function get(hash: string): AssetRecord | undefined {\n return records.get(hash)\n }\n\n function getMany(hashes: string[]): AssetRecord[] {\n return hashes\n .map((hash) => records.get(hash))\n .filter((record): record is AssetRecord => !!record)\n }\n\n function upsert(\n input: Omit<AssetRecord, 'uploadedAt' | 'lastAccess'> &\n Partial<Pick<AssetRecord, 'uploadedAt' | 'lastAccess'>>\n ): AssetRecord {\n const now = Date.now()\n const record: AssetRecord = {\n ...input,\n uploadedAt: input.uploadedAt ?? now,\n lastAccess: input.lastAccess ?? now\n }\n records.set(record.hash, record)\n persist()\n return record\n }\n\n function touch(hash: string): AssetRecord | undefined {\n const existing = records.get(hash)\n if (!existing) return undefined\n existing.lastAccess = Date.now()\n persist()\n return existing\n }\n\n function remove(hash: string, { removeFile = true } = {}): void {\n const record = records.get(hash)\n if (!record) return\n records.delete(hash)\n persist()\n\n if (removeFile) {\n try {\n rmSync(record.filePath, { force: true })\n } catch (error) {\n log.warn({ hash, error }, 'Failed to remove asset file on delete.')\n }\n }\n }\n\n function reconcile(): void {\n let changed = false\n for (const [hash, record] of records) {\n if (!existsSync(record.filePath)) {\n records.delete(hash)\n changed = true\n }\n }\n\n try {\n const files = readdirSync(ASSET_DIR)\n const now = Date.now()\n for (const file of files) {\n if (file === INDEX_FILENAME) continue\n\n // Cleanup stale tmp files (> 1 hour)\n if (file.includes('.tmp.')) {\n try {\n const filePath = join(ASSET_DIR, file)\n const stat = statSync(filePath)\n if (now - stat.mtimeMs > 3600 * 1000) {\n rmSync(filePath, { force: true })\n log.info({ file }, 'Cleaned up stale temp file.')\n }\n } catch (e) {\n // Ignore errors during cleanup\n log.debug({ error: e, file }, 'Failed to cleanup stale temp file.')\n }\n continue\n }\n\n if (!/^[a-f0-9]{64}$/i.test(file)) continue\n\n if (!records.has(file)) {\n const filePath = join(ASSET_DIR, file)\n try {\n const stat = statSync(filePath)\n records.set(file, {\n hash: file,\n filePath,\n mimeType: 'application/octet-stream',\n size: stat.size,\n uploadedAt: stat.birthtimeMs,\n lastAccess: stat.atimeMs\n })\n changed = true\n log.info({ hash: file }, 'Recovered orphan asset file.')\n } catch (e) {\n log.warn({ error: e, file }, 'Failed to stat orphan file.')\n }\n }\n }\n } catch (error) {\n log.warn({ error }, 'Failed to scan asset directory for orphans.')\n }\n\n if (changed) flush()\n }\n\n loadExisting()\n reconcile()\n\n return {\n list,\n has,\n get,\n getMany,\n upsert,\n touch,\n remove,\n reconcile,\n flush\n }\n}\n", "import { z } from 'zod'\n\n// Messages from hub to extension\nexport const RegisteredMessageSchema = z.object({\n type: z.literal('registered'),\n id: z.string()\n})\n\nexport const StateMessageSchema = z.object({\n type: z.literal('state'),\n activeId: z.string().nullable(),\n count: z.number().nonnegative(),\n port: z.number().positive(),\n assetServerUrl: z.string().url()\n})\n\nexport const ToolCallPayloadSchema = z.object({\n name: z.string(),\n args: z.unknown()\n})\n\nexport const ToolCallMessageSchema = z.object({\n type: z.literal('toolCall'),\n id: z.string(),\n payload: ToolCallPayloadSchema\n})\n\nexport const MessageToExtensionSchema = z.discriminatedUnion('type', [\n RegisteredMessageSchema,\n StateMessageSchema,\n ToolCallMessageSchema\n])\n\n// Messages from extension to hub\nexport const ActivateMessageSchema = z.object({\n type: z.literal('activate')\n})\n\nexport const ToolResultMessageSchema = z.object({\n type: z.literal('toolResult'),\n id: z.string(),\n payload: z.unknown().optional(),\n error: z.unknown().optional()\n})\n\nexport const MessageFromExtensionSchema = z.discriminatedUnion('type', [\n ActivateMessageSchema,\n ToolResultMessageSchema\n])\n\nexport type RegisteredMessage = z.infer<typeof RegisteredMessageSchema>\nexport type StateMessage = z.infer<typeof StateMessageSchema>\nexport type ToolCallPayload = z.infer<typeof ToolCallPayloadSchema>\nexport type ToolCallMessage = z.infer<typeof ToolCallMessageSchema>\nexport type MessageToExtension = z.infer<typeof MessageToExtensionSchema>\nexport type ActivateMessage = z.infer<typeof ActivateMessageSchema>\nexport type ToolResultMessage = z.infer<typeof ToolResultMessageSchema>\nexport type MessageFromExtension = z.infer<typeof MessageFromExtensionSchema>\n\nexport function parseMessageToExtension(data: string): MessageToExtension | null {\n let parsed: unknown\n try {\n parsed = JSON.parse(data)\n } catch {\n return null\n }\n const result = MessageToExtensionSchema.safeParse(parsed)\n return result.success ? result.data : null\n}\n\nexport function parseMessageFromExtension(data: string): MessageFromExtension | null {\n let parsed: unknown\n try {\n parsed = JSON.parse(data)\n } catch {\n return null\n }\n const result = MessageFromExtensionSchema.safeParse(parsed)\n return result.success ? result.data : null\n}\n", "import { nanoid } from 'nanoid'\n\nimport type { PendingToolCall } from './types'\n\nimport { log } from './shared'\n\nconst pendingCalls = new Map<string, PendingToolCall>()\n\nexport function register<T>(\n extensionId: string,\n timeout: number\n): { promise: Promise<T>; requestId: string } {\n const requestId = nanoid()\n const promise = new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n pendingCalls.delete(requestId)\n reject(new Error(`Extension did not respond within ${timeout / 1000}s.`))\n }, timeout)\n\n pendingCalls.set(requestId, {\n resolve: resolve as (value: unknown) => void,\n reject,\n timer,\n extensionId\n })\n })\n return { promise, requestId }\n}\n\nexport function resolve(requestId: string, payload: unknown): void {\n const call = pendingCalls.get(requestId)\n if (call) {\n const { timer, resolve: finish } = call\n clearTimeout(timer)\n finish(payload)\n pendingCalls.delete(requestId)\n } else {\n log.warn({ reqId: requestId }, 'Received result for unknown/timed-out call.')\n }\n}\n\nexport function reject(requestId: string, error: Error): void {\n const call = pendingCalls.get(requestId)\n if (call) {\n const { timer, reject: fail } = call\n clearTimeout(timer)\n fail(error)\n pendingCalls.delete(requestId)\n } else {\n log.warn({ reqId: requestId }, 'Received error for unknown/timed-out call.')\n }\n}\n\nexport function cleanupForExtension(extensionId: string): void {\n for (const [reqId, call] of pendingCalls.entries()) {\n const { timer, reject: fail, extensionId: extId } = call\n if (extId === extensionId) {\n clearTimeout(timer)\n fail(new Error('Extension disconnected before providing a result.'))\n pendingCalls.delete(reqId)\n log.warn({ reqId, extId: extensionId }, 'Rejected pending call from disconnected extension.')\n }\n }\n}\n\nexport function cleanupAll(): void {\n pendingCalls.forEach((call, reqId) => {\n const { timer, reject: fail } = call\n clearTimeout(timer)\n fail(new Error('Hub is shutting down.'))\n log.debug({ reqId }, 'Rejected pending tool call due to shutdown.')\n })\n pendingCalls.clear()\n}\n", "import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js'\nimport type { ZodType } from 'zod'\n\nimport { z } from 'zod'\n\nimport type { AssetDescriptor } from '../../mcp/shared/types'\n\nimport { MCP_HASH_PATTERN } from '../../mcp/shared/constants'\n\nexport type { AssetDescriptor }\n\n// get_code\nexport const GetCodeParametersSchema = z.object({\n nodeId: z\n .string()\n .describe(\n 'Optional target node id; omit to use the current single selection when pulling the baseline snapshot.'\n )\n .optional(),\n preferredLang: z\n .enum(['jsx', 'vue'])\n .describe(\n 'Preferred output language to bias the snapshot; otherwise uses the design\u2019s hint/detected language, then falls back to JSX.'\n )\n .optional(),\n resolveTokens: z\n .boolean()\n .describe(\n 'Inline token values instead of references for quick renders; default false returns token metadata so you can map into your theming system.'\n )\n .optional()\n})\n\nexport type GetCodeParametersInput = z.input<typeof GetCodeParametersSchema>\nexport type GetCodeResult = {\n code: string\n lang: 'vue' | 'jsx'\n message?: string\n usedTokens?: GetTokenDefsResult['tokens']\n assets: AssetDescriptor[]\n codegen: {\n preset: string\n config: {\n cssUnit: 'px' | 'rem'\n rootFontSize: number\n scale: number\n }\n }\n}\n\n// get_token_defs\nexport const GetTokenDefsParametersSchema = z.object({\n names: z\n .array(z.string().regex(/^--[a-zA-Z0-9-_]+$/))\n .min(1)\n .describe(\n 'Canonical token names (CSS variable form) from get_code.usedTokens or your own list to resolve, e.g., --color-primary.'\n ),\n includeAllModes: z\n .boolean()\n .describe(\n 'Include all token modes (light/dark/etc.) instead of just the active one to mirror responsive tokens; default false.'\n )\n .optional()\n})\n\nexport type GetTokenDefsParametersInput = z.input<typeof GetTokenDefsParametersSchema>\nexport type GetTokenDefsResult = {\n tokens: Array<{\n name: string\n value: string | Record<string, unknown> | null\n current: {\n modeId: string\n value?: string | Record<string, unknown>\n aliasTo?: string\n resolved: string | Record<string, unknown> | null\n aliasChain?: string[]\n }\n modes?: Array<{\n modeId: string\n value?: string | Record<string, unknown>\n aliasTo?: string\n resolved: string | Record<string, unknown> | null\n }>\n collection?: {\n id?: string\n name?: string\n activeModeId?: string\n defaultModeId?: string\n }\n kind: 'color' | 'spacing' | 'typography' | 'effect' | 'other'\n }>\n}\n\nexport const AssetDescriptorSchema = z.object({\n hash: z.string().min(1),\n url: z.string().url(),\n mimeType: z.string().min(1),\n size: z.number().int().nonnegative(),\n resourceUri: z.string().regex(/^asset:\\/\\/tempad\\/[a-f0-9]{64}$/i),\n width: z.number().int().positive().optional(),\n height: z.number().int().positive().optional()\n})\n\n// get_screenshot\nexport const GetScreenshotParametersSchema = z.object({\n nodeId: z\n .string()\n .describe(\n 'Optional node id to screenshot; defaults to the current single selection. Useful when layout/overlap is uncertain (auto-layout none/inferred).'\n )\n .optional()\n})\n\nexport type GetScreenshotParametersInput = z.input<typeof GetScreenshotParametersSchema>\nexport type GetScreenshotResult = {\n format: 'png'\n width: number\n height: number\n scale: number\n bytes: number\n asset: AssetDescriptor\n}\n\n// get_structure\nexport const GetStructureParametersSchema = z.object({\n nodeId: z\n .string()\n .describe(\n 'Optional node id to outline; defaults to the current single selection. Useful when auto-layout hints are none/inferred or you need explicit geometry for refactors.'\n )\n .optional(),\n options: z\n .object({\n depth: z\n .number()\n .int()\n .positive()\n .describe('Limit traversal depth; defaults to full tree (subject to safety caps).')\n .optional()\n })\n .optional()\n})\n\nexport type GetStructureParametersInput = z.input<typeof GetStructureParametersSchema>\nexport type OutlineNode = {\n id: string\n name: string\n type: string\n x: number\n y: number\n width: number\n height: number\n children?: OutlineNode[]\n}\nexport type GetStructureResult = {\n roots: OutlineNode[]\n}\n\n// get_assets (hub only)\nexport const GetAssetsParametersSchema = z.object({\n hashes: z\n .array(z.string().regex(MCP_HASH_PATTERN))\n .min(1)\n .describe(\n 'Asset hashes returned from get_code (or other tools) to download/resolve exact bytes for rasterized images or SVGs before routing through your asset pipeline.'\n )\n})\n\nexport const GetAssetsResultSchema = z.object({\n assets: z.array(AssetDescriptorSchema),\n missing: z.array(z.string().min(1))\n})\n\nexport type GetAssetsParametersInput = z.input<typeof GetAssetsParametersSchema>\nexport type GetAssetsResult = z.infer<typeof GetAssetsResultSchema>\n\nexport type ToolResultMap = {\n get_code: GetCodeResult\n get_token_defs: GetTokenDefsResult\n get_screenshot: GetScreenshotResult\n get_structure: GetStructureResult\n get_assets: GetAssetsResult\n}\n\nexport type ToolName = keyof ToolResultMap\n\nexport { default as MCP_INSTRUCTIONS } from './instructions.md'\n\ntype BaseToolMetadata<Name extends ToolName, Schema extends ZodType> = {\n name: Name\n description: string\n parameters: Schema\n exposed?: boolean\n format?: (payload: ToolResultMap[Name]) => CallToolResult\n}\n\ntype ExtensionToolMetadata<Name extends ToolName, Schema extends ZodType> = BaseToolMetadata<\n Name,\n Schema\n> & {\n target: 'extension'\n}\n\ntype HubToolMetadata<Name extends ToolName, Schema extends ZodType> = BaseToolMetadata<\n Name,\n Schema\n> & {\n target: 'hub'\n outputSchema?: ZodType\n}\n\nfunction extTool<Name extends ToolName, Schema extends ZodType>(\n definition: ExtensionToolMetadata<Name, Schema>\n): ExtensionToolMetadata<Name, Schema> {\n return definition\n}\n\nfunction hubTool<Name extends ToolName, Schema extends ZodType>(\n definition: HubToolMetadata<Name, Schema>\n): HubToolMetadata<Name, Schema> {\n return definition\n}\n\nexport const TOOL_DEFS = [\n extTool({\n name: 'get_code',\n description:\n '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.',\n parameters: GetCodeParametersSchema,\n target: 'extension',\n format: createCodeToolResponse\n }),\n extTool({\n name: 'get_token_defs',\n description:\n 'Resolve canonical token names to values (including modes) for tokens referenced by get_code. Use this to map into your design token/theming system, including responsive tokens.',\n parameters: GetTokenDefsParametersSchema,\n target: 'extension',\n exposed: false\n }),\n extTool({\n name: 'get_screenshot',\n description:\n 'Capture a rendered screenshot for a nodeId/current selection for visual verification. Useful for confirming layering/overlap/masks/shadows/translucency when auto-layout hints are none/inferred.',\n parameters: GetScreenshotParametersSchema,\n target: 'extension',\n format: createScreenshotToolResponse\n }),\n extTool({\n name: 'get_structure',\n description:\n 'Get a structural + geometry outline for a nodeId/current selection to understand hierarchy and layout intent. Use when auto-layout hints are none/inferred or you need explicit bounds for refactors/component extraction.',\n parameters: GetStructureParametersSchema,\n target: 'extension'\n }),\n hubTool({\n name: 'get_assets',\n description:\n 'Resolve asset hashes to downloadable URLs/URIs for assets referenced by get_code, preserving vectors exactly. Pull bytes before routing through your asset/icon pipeline.',\n parameters: GetAssetsParametersSchema,\n target: 'hub',\n outputSchema: GetAssetsResultSchema,\n exposed: false\n })\n] as const\n\nfunction createToolErrorResponse(toolName: string, error: unknown): CallToolResult {\n const message =\n error instanceof Error\n ? error.message || 'Unknown error occurred.'\n : typeof error === 'string'\n ? error\n : 'Unknown error occurred.'\n return {\n content: [\n {\n type: 'text' as const,\n text: `Tool \"${toolName}\" failed: ${message}`\n }\n ]\n }\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`\n return `${(bytes / (1024 * 1024)).toFixed(1)} MB`\n}\n\nexport function createCodeToolResponse(payload: ToolResultMap['get_code']): CallToolResult {\n if (!isCodeResult(payload)) {\n throw new Error('Invalid get_code payload received from extension.')\n }\n\n const summary: string[] = []\n const codeSize = Buffer.byteLength(payload.code, 'utf8')\n summary.push(`Generated \\`${payload.lang}\\` snippet (${formatBytes(codeSize)}).`)\n if (payload.message) {\n summary.push(payload.message)\n }\n summary.push(\n payload.assets.length\n ? `Assets attached: ${payload.assets.length}. Fetch bytes via resources/read using resourceUri.`\n : 'No binary assets were attached to this response.'\n )\n if (payload.usedTokens?.length) {\n summary.push(`Token references included: ${payload.usedTokens.length}.`)\n }\n summary.push('Read structuredContent for the full code string and asset metadata.')\n\n const assetLinks =\n payload.assets.length > 0\n ? payload.assets.map((asset) => createAssetResourceLinkBlock(asset))\n : []\n\n return {\n content: [\n {\n type: 'text' as const,\n text: summary.join('\\n')\n },\n ...assetLinks\n ],\n structuredContent: payload\n }\n}\n\nexport function createScreenshotToolResponse(\n payload: ToolResultMap['get_screenshot']\n): CallToolResult {\n if (!isScreenshotResult(payload)) {\n throw new Error('Invalid get_screenshot payload received from extension.')\n }\n\n const descriptionBlock = {\n type: 'text' as const,\n text: describeScreenshot(payload)\n }\n\n return {\n content: [\n descriptionBlock,\n {\n type: 'text' as const,\n text: ``\n },\n createResourceLinkBlock(payload.asset, payload)\n ],\n structuredContent: payload\n }\n}\n\nfunction createResourceLinkBlock(asset: AssetDescriptor, result: GetScreenshotResult) {\n return {\n type: 'resource_link' as const,\n name: 'Screenshot',\n uri: asset.resourceUri,\n mimeType: asset.mimeType,\n description: `Screenshot ${result.width}x${result.height} @${result.scale}x - Download: ${asset.url}`\n }\n}\n\nfunction describeScreenshot(result: GetScreenshotResult): string {\n return `Screenshot ${result.width}x${result.height} @${result.scale}x (${formatBytes(result.bytes)})`\n}\n\nfunction isScreenshotResult(payload: unknown): payload is GetScreenshotResult {\n if (typeof payload !== 'object' || !payload) return false\n const candidate = payload as Partial<GetScreenshotResult & Record<string, unknown>>\n return (\n typeof candidate.asset === 'object' &&\n candidate.asset !== null &&\n typeof candidate.width === 'number' &&\n typeof candidate.height === 'number' &&\n typeof candidate.scale === 'number' &&\n typeof candidate.bytes === 'number' &&\n typeof candidate.format === 'string'\n )\n}\n\nfunction isCodeResult(payload: unknown): payload is ToolResultMap['get_code'] {\n if (typeof payload !== 'object' || !payload) return false\n const candidate = payload as Partial<ToolResultMap['get_code'] & Record<string, unknown>>\n return (\n typeof candidate.code === 'string' &&\n typeof candidate.lang === 'string' &&\n Array.isArray(candidate.assets)\n )\n}\n\nfunction createAssetResourceLinkBlock(asset: AssetDescriptor) {\n return {\n type: 'resource_link' as const,\n name: formatAssetResourceName(asset.hash),\n uri: asset.resourceUri,\n mimeType: asset.mimeType,\n description: `${describeAsset(asset)} - Download: ${asset.url}`\n }\n}\n\nfunction describeAsset(asset: AssetDescriptor): string {\n return `${asset.mimeType} (${formatBytes(asset.size)})`\n}\n\nfunction formatAssetResourceName(hash: string): string {\n return `asset:${hash.slice(0, 8)}`\n}\n\nexport function coercePayloadToToolResponse(payload: unknown): CallToolResult {\n if (\n payload &&\n typeof payload === 'object' &&\n Array.isArray((payload as CallToolResult).content)\n ) {\n return payload as CallToolResult\n }\n\n return {\n content: [\n {\n type: 'text' as const,\n text: typeof payload === 'string' ? payload : JSON.stringify(payload, null, 2)\n }\n ]\n }\n}\n\nexport { createToolErrorResponse }\n", "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\u2019s 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\u2019s 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\u2019s 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\u2019s 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"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["nanoid", "existsSync", "rmSync", "readFileSync", "statSync", "createServer", "join", "port", "resolve", "reject", "join", "existsSync", "statSync", "join", "join", "existsSync", "list", "statSync", "nanoid", "nanoid", "resolve", "reject", "z", "z", "existsSync", "formatAssetResourceName", "formatBytes", "statSync", "readFileSync", "createAssetResourceLinkBlock", "describeAsset", "rmSync", "createServer", "resolve", "reject", "nanoid"]
|
|
7
7
|
}
|