@tempad-dev/mcp 0.3.1 → 0.3.2

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 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.2",
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": "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",
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.2\",\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.2",
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");
@@ -628,7 +659,9 @@ You are connected to a Figma design file via the MCP server. Help convert design
628
659
  // src/tools.ts
629
660
  var GetCodeParametersSchema = z2.object({
630
661
  nodeId: z2.string().describe("Optional node id to target; defaults to the current single selection.").optional(),
631
- preferredLang: z2.enum(["jsx", "vue"]).describe("Preferred output language; otherwise uses the design\u2019s hint/detected language, then JSX.").optional(),
662
+ preferredLang: z2.enum(["jsx", "vue"]).describe(
663
+ "Preferred output language; otherwise uses the design\u2019s hint/detected language, then JSX."
664
+ ).optional(),
632
665
  resolveTokens: z2.boolean().describe("Resolve token references to concrete values; default false returns token metadata.").optional()
633
666
  });
634
667
  var GetTokenDefsParametersSchema = z2.object({
@@ -725,7 +758,7 @@ function createCodeToolResponse(payload) {
725
758
  }
726
759
  const summary = [];
727
760
  const codeSize = Buffer.byteLength(payload.code, "utf8");
728
- summary.push(`Generated ${payload.lang.toUpperCase()} snippet (${formatBytes(codeSize)}).`);
761
+ summary.push(`Generated \`${payload.lang}\` snippet (${formatBytes(codeSize)}).`);
729
762
  if (payload.message) {
730
763
  summary.push(payload.message);
731
764
  }
@@ -822,12 +855,13 @@ function coercePayloadToToolResponse(payload) {
822
855
  // src/hub.ts
823
856
  var SHUTDOWN_TIMEOUT = 2e3;
824
857
  var { wsPortCandidates, toolTimeoutMs, maxPayloadBytes, autoActivateGraceMs } = getMcpServerConfig();
858
+ log.info({ version: PACKAGE_VERSION }, "TemPad MCP Hub starting...");
825
859
  var extensions = [];
826
860
  var consumerCount = 0;
827
861
  var autoActivateTimer = null;
828
862
  var selectedWsPort = 0;
829
863
  var mcp = new McpServer(
830
- { name: "tempad-dev-mcp", version: "0.1.0" },
864
+ { name: "tempad-dev-mcp", version: PACKAGE_VERSION },
831
865
  MCP_INSTRUCTIONS ? { instructions: MCP_INSTRUCTIONS } : void 0
832
866
  );
833
867
  function enrichToolDefinition(tool) {
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.ts"],
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: `![Screenshot](${payload.asset.url})`\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.ts"],
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.2\",\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('Optional node id to target; defaults to the current single selection.')\n .optional(),\n preferredLang: z\n .enum(['jsx', 'vue'])\n .describe(\n 'Preferred output language; otherwise uses the design\u2019s hint/detected language, then JSX.'\n )\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}\\` 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: `![Screenshot](${payload.asset.url})`\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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",
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
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tempad-dev/mcp",
3
3
  "description": "MCP server for TemPad Dev.",
4
- "version": "0.3.1",
4
+ "version": "0.3.2",
5
5
  "type": "module",
6
6
  "main": "dist/cli.js",
7
7
  "bin": "dist/cli.js",