@layoutdesign/context 0.5.0 → 0.10.1
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 +71 -0
- package/dist/bin/cli.js +35 -0
- package/dist/bin/cli.js.map +1 -1
- package/dist/src/cli/diff.d.ts +4 -0
- package/dist/src/cli/diff.d.ts.map +1 -0
- package/dist/src/cli/diff.js +53 -0
- package/dist/src/cli/diff.js.map +1 -0
- package/dist/src/cli/import-tokens-json.d.ts +5 -0
- package/dist/src/cli/import-tokens-json.d.ts.map +1 -0
- package/dist/src/cli/import-tokens-json.js +174 -0
- package/dist/src/cli/import-tokens-json.js.map +1 -0
- package/dist/src/cli/install.d.ts +1 -0
- package/dist/src/cli/install.d.ts.map +1 -1
- package/dist/src/cli/install.js +25 -0
- package/dist/src/cli/install.js.map +1 -1
- package/dist/src/cli/lint.d.ts +7 -0
- package/dist/src/cli/lint.d.ts.map +1 -0
- package/dist/src/cli/lint.js +80 -0
- package/dist/src/cli/lint.js.map +1 -0
- package/dist/src/cli/live-notify.d.ts +2 -0
- package/dist/src/cli/live-notify.d.ts.map +1 -0
- package/dist/src/cli/live-notify.js +29 -0
- package/dist/src/cli/live-notify.js.map +1 -0
- package/dist/src/install/live.d.ts +5 -0
- package/dist/src/install/live.d.ts.map +1 -0
- package/dist/src/install/live.js +285 -0
- package/dist/src/install/live.js.map +1 -0
- package/dist/src/kit/stage.d.ts +19 -0
- package/dist/src/kit/stage.d.ts.map +1 -0
- package/dist/src/kit/stage.js +30 -0
- package/dist/src/kit/stage.js.map +1 -0
- package/dist/src/lint/diff.d.ts +23 -0
- package/dist/src/lint/diff.d.ts.map +1 -0
- package/dist/src/lint/diff.js +62 -0
- package/dist/src/lint/diff.js.map +1 -0
- package/dist/src/lint/layout-md.d.ts +21 -0
- package/dist/src/lint/layout-md.d.ts.map +1 -0
- package/dist/src/lint/layout-md.js +376 -0
- package/dist/src/lint/layout-md.js.map +1 -0
- package/dist/src/mcp/live-lock-store.d.ts +40 -0
- package/dist/src/mcp/live-lock-store.d.ts.map +1 -0
- package/dist/src/mcp/live-lock-store.js +134 -0
- package/dist/src/mcp/live-lock-store.js.map +1 -0
- package/dist/src/mcp/server.d.ts.map +1 -1
- package/dist/src/mcp/server.js +11 -0
- package/dist/src/mcp/server.js.map +1 -1
- package/dist/src/mcp/tools/_live-socket.d.ts +23 -0
- package/dist/src/mcp/tools/_live-socket.d.ts.map +1 -0
- package/dist/src/mcp/tools/_live-socket.js +135 -0
- package/dist/src/mcp/tools/_live-socket.js.map +1 -0
- package/dist/src/mcp/tools/check-setup.d.ts +14 -1
- package/dist/src/mcp/tools/check-setup.d.ts.map +1 -1
- package/dist/src/mcp/tools/check-setup.js +75 -1
- package/dist/src/mcp/tools/check-setup.js.map +1 -1
- package/dist/src/mcp/tools/get-recent-visual-edits.d.ts +40 -0
- package/dist/src/mcp/tools/get-recent-visual-edits.d.ts.map +1 -0
- package/dist/src/mcp/tools/get-recent-visual-edits.js +106 -0
- package/dist/src/mcp/tools/get-recent-visual-edits.js.map +1 -0
- package/dist/src/mcp/tools/get-selected-element.d.ts +10 -0
- package/dist/src/mcp/tools/get-selected-element.d.ts.map +1 -0
- package/dist/src/mcp/tools/get-selected-element.js +46 -0
- package/dist/src/mcp/tools/get-selected-element.js.map +1 -0
- package/dist/src/mcp/tools/lock-file.d.ts +28 -0
- package/dist/src/mcp/tools/lock-file.d.ts.map +1 -0
- package/dist/src/mcp/tools/lock-file.js +42 -0
- package/dist/src/mcp/tools/lock-file.js.map +1 -0
- package/dist/src/mcp/tools/unlock-file.d.ts +23 -0
- package/dist/src/mcp/tools/unlock-file.d.ts.map +1 -0
- package/dist/src/mcp/tools/unlock-file.js +23 -0
- package/dist/src/mcp/tools/unlock-file.js.map +1 -0
- package/dist/src/plugins/next/babel-loader.d.ts +8 -0
- package/dist/src/plugins/next/babel-loader.d.ts.map +1 -0
- package/dist/src/plugins/next/babel-loader.js +26 -0
- package/dist/src/plugins/next/babel-loader.js.map +1 -0
- package/dist/src/plugins/next/index.d.ts +23 -0
- package/dist/src/plugins/next/index.d.ts.map +1 -0
- package/dist/src/plugins/next/index.js +58 -0
- package/dist/src/plugins/next/index.js.map +1 -0
- package/dist/src/plugins/transform.d.ts +19 -0
- package/dist/src/plugins/transform.d.ts.map +1 -0
- package/dist/src/plugins/transform.js +177 -0
- package/dist/src/plugins/transform.js.map +1 -0
- package/dist/src/plugins/vite/index.d.ts +24 -0
- package/dist/src/plugins/vite/index.d.ts.map +1 -0
- package/dist/src/plugins/vite/index.js +56 -0
- package/dist/src/plugins/vite/index.js.map +1 -0
- package/package.json +32 -9
- package/skills/layout-md/SKILL.md +135 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface LiveRequest {
|
|
2
|
+
method: string;
|
|
3
|
+
params?: Record<string, unknown>;
|
|
4
|
+
}
|
|
5
|
+
export interface LiveConnection {
|
|
6
|
+
/** Send a single request and await its matching response result. */
|
|
7
|
+
send<T = unknown>(req: LiveRequest): Promise<T>;
|
|
8
|
+
/** Close the underlying socket. */
|
|
9
|
+
close(): void;
|
|
10
|
+
}
|
|
11
|
+
/** Stable per-project id: first 16 hex chars of sha256(projectRoot). */
|
|
12
|
+
export declare function computeProjectId(projectRoot: string): string;
|
|
13
|
+
/** Absolute path (or Windows pipe name) of the Live socket for a project. */
|
|
14
|
+
export declare function liveSocketPath(projectRoot: string): string;
|
|
15
|
+
/**
|
|
16
|
+
* Connect to the running Live app for `projectRoot` (defaults to cwd).
|
|
17
|
+
*
|
|
18
|
+
* Returns `null` — never throws — when Live is not running. "Not running" is
|
|
19
|
+
* any of: socket file absent (ENOENT), stale socket (ECONNREFUSED), or the
|
|
20
|
+
* connection not completing within {@link CONNECT_TIMEOUT_MS}.
|
|
21
|
+
*/
|
|
22
|
+
export declare function connectToLive(projectRoot?: string): Promise<LiveConnection | null>;
|
|
23
|
+
//# sourceMappingURL=_live-socket.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_live-socket.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/_live-socket.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IAChD,mCAAmC;IACnC,KAAK,IAAI,IAAI,CAAC;CACf;AAED,wEAAwE;AACxE,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAM5D;AAED,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAK1D;AAKD;;;;;;GAMG;AACH,wBAAsB,aAAa,CACjC,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAmChC"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared Unix-socket client for talking to a running layout Live desktop app.
|
|
3
|
+
*
|
|
4
|
+
* Live hosts a line-delimited JSON socket at `~/.layout/live-<projectId>.sock`
|
|
5
|
+
* (or `\\.\pipe\layout-live-<projectId>` on Windows) while it is open on a
|
|
6
|
+
* project. The MCP tool handlers in this directory connect to it on demand to
|
|
7
|
+
* query selection / edit / status state.
|
|
8
|
+
*
|
|
9
|
+
* If Live is not running the socket file is absent: `connectToLive()` resolves
|
|
10
|
+
* to `null` (callers treat this as "Live not running") rather than throwing.
|
|
11
|
+
*/
|
|
12
|
+
import net from "node:net";
|
|
13
|
+
import path from "node:path";
|
|
14
|
+
import os from "node:os";
|
|
15
|
+
import crypto from "node:crypto";
|
|
16
|
+
/** Stable per-project id: first 16 hex chars of sha256(projectRoot). */
|
|
17
|
+
export function computeProjectId(projectRoot) {
|
|
18
|
+
return crypto
|
|
19
|
+
.createHash("sha256")
|
|
20
|
+
.update(path.resolve(projectRoot))
|
|
21
|
+
.digest("hex")
|
|
22
|
+
.slice(0, 16);
|
|
23
|
+
}
|
|
24
|
+
/** Absolute path (or Windows pipe name) of the Live socket for a project. */
|
|
25
|
+
export function liveSocketPath(projectRoot) {
|
|
26
|
+
const id = computeProjectId(projectRoot);
|
|
27
|
+
return process.platform === "win32"
|
|
28
|
+
? `\\\\.\\pipe\\layout-live-${id}`
|
|
29
|
+
: path.join(os.homedir(), ".layout", `live-${id}.sock`);
|
|
30
|
+
}
|
|
31
|
+
const CONNECT_TIMEOUT_MS = 1500;
|
|
32
|
+
const REQUEST_TIMEOUT_MS = 3000;
|
|
33
|
+
/**
|
|
34
|
+
* Connect to the running Live app for `projectRoot` (defaults to cwd).
|
|
35
|
+
*
|
|
36
|
+
* Returns `null` — never throws — when Live is not running. "Not running" is
|
|
37
|
+
* any of: socket file absent (ENOENT), stale socket (ECONNREFUSED), or the
|
|
38
|
+
* connection not completing within {@link CONNECT_TIMEOUT_MS}.
|
|
39
|
+
*/
|
|
40
|
+
export async function connectToLive(projectRoot) {
|
|
41
|
+
const socketPath = liveSocketPath(projectRoot ?? process.cwd());
|
|
42
|
+
return new Promise((resolve) => {
|
|
43
|
+
let settled = false;
|
|
44
|
+
const socket = net.createConnection(socketPath);
|
|
45
|
+
const fail = (err) => {
|
|
46
|
+
if (settled)
|
|
47
|
+
return;
|
|
48
|
+
settled = true;
|
|
49
|
+
socket.destroy();
|
|
50
|
+
// ENOENT (no socket file) and ECONNREFUSED (stale socket) both mean
|
|
51
|
+
// "Live not running". Anything else is also treated as not-running so a
|
|
52
|
+
// tool call never hard-fails on a transport hiccup.
|
|
53
|
+
void err;
|
|
54
|
+
resolve(null);
|
|
55
|
+
};
|
|
56
|
+
const timer = setTimeout(() => fail({ code: "ETIMEDOUT" }), CONNECT_TIMEOUT_MS);
|
|
57
|
+
socket.once("error", (err) => {
|
|
58
|
+
clearTimeout(timer);
|
|
59
|
+
fail(err);
|
|
60
|
+
});
|
|
61
|
+
socket.once("connect", () => {
|
|
62
|
+
clearTimeout(timer);
|
|
63
|
+
if (settled) {
|
|
64
|
+
socket.destroy();
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
settled = true;
|
|
68
|
+
resolve(wrapSocket(socket));
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/** Wrap a connected socket in the line-delimited JSON request/response API. */
|
|
73
|
+
function wrapSocket(socket) {
|
|
74
|
+
let buffer = "";
|
|
75
|
+
const pending = new Map();
|
|
76
|
+
socket.setEncoding("utf8");
|
|
77
|
+
socket.on("data", (chunk) => {
|
|
78
|
+
buffer += chunk;
|
|
79
|
+
let nl;
|
|
80
|
+
while ((nl = buffer.indexOf("\n")) !== -1) {
|
|
81
|
+
const line = buffer.slice(0, nl).trim();
|
|
82
|
+
buffer = buffer.slice(nl + 1);
|
|
83
|
+
if (!line)
|
|
84
|
+
continue;
|
|
85
|
+
let msg;
|
|
86
|
+
try {
|
|
87
|
+
msg = JSON.parse(line);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
if (!msg.id)
|
|
93
|
+
continue;
|
|
94
|
+
const waiter = pending.get(msg.id);
|
|
95
|
+
if (!waiter)
|
|
96
|
+
continue;
|
|
97
|
+
pending.delete(msg.id);
|
|
98
|
+
clearTimeout(waiter.timer);
|
|
99
|
+
if (msg.ok)
|
|
100
|
+
waiter.resolve(msg.result);
|
|
101
|
+
else
|
|
102
|
+
waiter.reject(new Error(msg.error ?? "Live request failed"));
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
const rejectAll = (err) => {
|
|
106
|
+
for (const { reject, timer } of pending.values()) {
|
|
107
|
+
clearTimeout(timer);
|
|
108
|
+
reject(err);
|
|
109
|
+
}
|
|
110
|
+
pending.clear();
|
|
111
|
+
};
|
|
112
|
+
socket.on("error", (err) => rejectAll(err));
|
|
113
|
+
socket.on("close", () => rejectAll(new Error("Live socket closed")));
|
|
114
|
+
return {
|
|
115
|
+
send(req) {
|
|
116
|
+
const id = crypto.randomUUID();
|
|
117
|
+
return new Promise((resolve, reject) => {
|
|
118
|
+
const timer = setTimeout(() => {
|
|
119
|
+
pending.delete(id);
|
|
120
|
+
reject(new Error("Live request timed out"));
|
|
121
|
+
}, REQUEST_TIMEOUT_MS);
|
|
122
|
+
pending.set(id, {
|
|
123
|
+
resolve: resolve,
|
|
124
|
+
reject,
|
|
125
|
+
timer,
|
|
126
|
+
});
|
|
127
|
+
socket.write(JSON.stringify({ id, ...req }) + "\n");
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
close() {
|
|
131
|
+
socket.destroy();
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=_live-socket.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_live-socket.js","sourceRoot":"","sources":["../../../../src/mcp/tools/_live-socket.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,16 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
/** Structured status of the layout Live desktop app for `check-setup`. */
|
|
3
|
+
export interface LiveStatus {
|
|
4
|
+
installed: boolean;
|
|
5
|
+
running: boolean;
|
|
6
|
+
version?: string;
|
|
7
|
+
project?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Additive `check-setup` field (v0.7.0). Queries the Live socket for running
|
|
11
|
+
* status; never throws — Live being absent is the common, non-error case.
|
|
12
|
+
*/
|
|
13
|
+
export declare function getLiveStatus(): Promise<LiveStatus>;
|
|
2
14
|
export declare const name = "check-setup";
|
|
3
15
|
export declare const description: string;
|
|
4
16
|
export declare const inputSchema: {
|
|
@@ -6,12 +18,13 @@ export declare const inputSchema: {
|
|
|
6
18
|
figma: "figma";
|
|
7
19
|
playwright: "playwright";
|
|
8
20
|
layout: "layout";
|
|
21
|
+
live: "live";
|
|
9
22
|
all: "all";
|
|
10
23
|
}>>;
|
|
11
24
|
fix: z.ZodOptional<z.ZodBoolean>;
|
|
12
25
|
};
|
|
13
26
|
type Input = {
|
|
14
|
-
focus?: "all" | "figma" | "playwright" | "layout";
|
|
27
|
+
focus?: "all" | "figma" | "playwright" | "layout" | "live";
|
|
15
28
|
fix?: boolean;
|
|
16
29
|
};
|
|
17
30
|
export declare function handler(): (input: Input) => Promise<{
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-setup.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/check-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;
|
|
1
|
+
{"version":3,"file":"check-setup.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/check-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAaxB,0EAA0E;AAC1E,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAmBD;;;GAGG;AACH,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CAuBzD;AAyBD,eAAO,MAAM,IAAI,gBAAgB,CAAC;AAElC,eAAO,MAAM,WAAW,QAKoD,CAAC;AAE7E,eAAO,MAAM,WAAW;;;;;;;;;CAWvB,CAAC;AAEF,KAAK,KAAK,GAAG;IACX,KAAK,CAAC,EAAE,KAAK,GAAG,OAAO,GAAG,YAAY,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC3D,GAAG,CAAC,EAAE,OAAO,CAAC;CACf,CAAC;AAEF,wBAAgB,OAAO,KACP,OAAO,KAAK;;;;;GA6C3B"}
|
|
@@ -1,5 +1,75 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import os from "node:os";
|
|
5
|
+
import { execFileSync } from "node:child_process";
|
|
2
6
|
import { checkMcpRegistration, addFigmaMcpServer, addPlaywrightMcpServer, testEndpointReachable, } from "../../cli/setup-utils.js";
|
|
7
|
+
import { connectToLive } from "./_live-socket.js";
|
|
8
|
+
/** Best-effort detection of a locally installed `layout-live` binary/app. */
|
|
9
|
+
function isLiveInstalled() {
|
|
10
|
+
const candidates = [
|
|
11
|
+
"/Applications/Layout Live.app",
|
|
12
|
+
"/Applications/layout-live.app",
|
|
13
|
+
join(os.homedir(), "Applications", "Layout Live.app"),
|
|
14
|
+
];
|
|
15
|
+
if (candidates.some((p) => existsSync(p)))
|
|
16
|
+
return true;
|
|
17
|
+
try {
|
|
18
|
+
const cmd = process.platform === "win32" ? "where" : "which";
|
|
19
|
+
execFileSync(cmd, ["layout-live"], { stdio: "ignore" });
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Additive `check-setup` field (v0.7.0). Queries the Live socket for running
|
|
28
|
+
* status; never throws — Live being absent is the common, non-error case.
|
|
29
|
+
*/
|
|
30
|
+
export async function getLiveStatus() {
|
|
31
|
+
const installed = isLiveInstalled();
|
|
32
|
+
const live = await connectToLive();
|
|
33
|
+
if (!live) {
|
|
34
|
+
return { installed, running: false };
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const status = await live.send({ method: "check-status" });
|
|
38
|
+
return {
|
|
39
|
+
installed: true,
|
|
40
|
+
running: status?.running !== false,
|
|
41
|
+
version: status?.version,
|
|
42
|
+
project: status?.project,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return { installed, running: false };
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
live.close();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function renderLive(live) {
|
|
53
|
+
const icon = live.running ? "✅" : live.installed ? "⚠️" : "❌";
|
|
54
|
+
const lines = [`### layout Live ${icon}\n`];
|
|
55
|
+
if (live.running) {
|
|
56
|
+
lines.push(`- Status: running${live.version ? ` (v${live.version})` : ""}\n`);
|
|
57
|
+
if (live.project)
|
|
58
|
+
lines.push(`- Project: ${live.project}\n`);
|
|
59
|
+
}
|
|
60
|
+
else if (live.installed) {
|
|
61
|
+
lines.push("- Status: installed but not running\n");
|
|
62
|
+
lines.push("- Open the layout Live app to enable visual-edit context\n");
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
lines.push("- Status: not installed (optional)\n");
|
|
66
|
+
lines.push("- layout Live adds visual-edit context. Tools still work without it.\n");
|
|
67
|
+
}
|
|
68
|
+
lines.push("```json");
|
|
69
|
+
lines.push(JSON.stringify({ live }, null, 2));
|
|
70
|
+
lines.push("```\n");
|
|
71
|
+
return lines.join("\n");
|
|
72
|
+
}
|
|
3
73
|
export const name = "check-setup";
|
|
4
74
|
export const description = "Diagnose and optionally fix MCP server setup issues. " +
|
|
5
75
|
"Call this when Figma tools (push-to-figma, design-in-figma, url-to-figma) aren't working, " +
|
|
@@ -8,7 +78,7 @@ export const description = "Diagnose and optionally fix MCP server setup issues.
|
|
|
8
78
|
"With fix=true, attempts to re-register missing or misconfigured servers.";
|
|
9
79
|
export const inputSchema = {
|
|
10
80
|
focus: z
|
|
11
|
-
.enum(["all", "figma", "playwright", "layout"])
|
|
81
|
+
.enum(["all", "figma", "playwright", "layout", "live"])
|
|
12
82
|
.optional()
|
|
13
83
|
.describe("What to check. Default: 'all'"),
|
|
14
84
|
fix: z
|
|
@@ -43,6 +113,10 @@ export function handler() {
|
|
|
43
113
|
if (focus === "all" || focus === "layout") {
|
|
44
114
|
sections.push(checkLayout(state));
|
|
45
115
|
}
|
|
116
|
+
// --- layout Live (additive, v0.7.0) ---
|
|
117
|
+
if (focus === "all" || focus === "live") {
|
|
118
|
+
sections.push(renderLive(await getLiveStatus()));
|
|
119
|
+
}
|
|
46
120
|
// --- Next Steps ---
|
|
47
121
|
sections.push(buildNextSteps(state, shouldFix));
|
|
48
122
|
return { content: [{ type: "text", text: sections.join("\n") }] };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"check-setup.js","sourceRoot":"","sources":["../../../../src/mcp/tools/check-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"check-setup.js","sourceRoot":"","sources":["../../../../src/mcp/tools/check-setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool: get-recent-visual-edits
|
|
3
|
+
*
|
|
4
|
+
* Returns recent class/token/inline-style edits made by the user in layout
|
|
5
|
+
* Live. Reads from Live's socket when running; falls back to the on-disk
|
|
6
|
+
* `.layout/live/recent-edits.json` log when Live is not running.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
export declare const name = "get-recent-visual-edits";
|
|
10
|
+
export declare const description: string;
|
|
11
|
+
export declare const inputSchema: {
|
|
12
|
+
limit: z.ZodDefault<z.ZodNumber>;
|
|
13
|
+
since: z.ZodOptional<z.ZodString>;
|
|
14
|
+
file: z.ZodOptional<z.ZodString>;
|
|
15
|
+
};
|
|
16
|
+
type Input = {
|
|
17
|
+
limit?: number;
|
|
18
|
+
since?: string;
|
|
19
|
+
file?: string;
|
|
20
|
+
};
|
|
21
|
+
export interface VisualEdit {
|
|
22
|
+
id: string;
|
|
23
|
+
timestamp: string;
|
|
24
|
+
file: string;
|
|
25
|
+
line: number;
|
|
26
|
+
col: number;
|
|
27
|
+
component?: string;
|
|
28
|
+
property: string;
|
|
29
|
+
kind: "class" | "token" | "inline-style";
|
|
30
|
+
before: string;
|
|
31
|
+
after: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function handler(): (input: Input) => Promise<{
|
|
34
|
+
content: {
|
|
35
|
+
type: "text";
|
|
36
|
+
text: string;
|
|
37
|
+
}[];
|
|
38
|
+
}>;
|
|
39
|
+
export {};
|
|
40
|
+
//# sourceMappingURL=get-recent-visual-edits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-recent-visual-edits.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/get-recent-visual-edits.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,eAAO,MAAM,IAAI,4BAA4B,CAAC;AAE9C,eAAO,MAAM,WAAW,QAI6C,CAAC;AAEtE,eAAO,MAAM,WAAW;;;;CAiBvB,CAAC;AAEF,KAAK,KAAK,GAAG;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE/D,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,cAAc,CAAC;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AA8CD,wBAAgB,OAAO,KACP,OAAO,KAAK;;;;;GAwC3B"}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool: get-recent-visual-edits
|
|
3
|
+
*
|
|
4
|
+
* Returns recent class/token/inline-style edits made by the user in layout
|
|
5
|
+
* Live. Reads from Live's socket when running; falls back to the on-disk
|
|
6
|
+
* `.layout/live/recent-edits.json` log when Live is not running.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { promises as fs } from "node:fs";
|
|
10
|
+
import path from "node:path";
|
|
11
|
+
import { connectToLive } from "./_live-socket.js";
|
|
12
|
+
export const name = "get-recent-visual-edits";
|
|
13
|
+
export const description = "Returns recent visual edits made by the user in layout Live. Use this " +
|
|
14
|
+
"when the user references 'the change I just made', 'what I tweaked', or " +
|
|
15
|
+
"you need context on recent UI modifications before generating new code. " +
|
|
16
|
+
"Works even when Live is not running (reads the on-disk edit log).";
|
|
17
|
+
export const inputSchema = {
|
|
18
|
+
limit: z
|
|
19
|
+
.number()
|
|
20
|
+
.int()
|
|
21
|
+
.positive()
|
|
22
|
+
.max(100)
|
|
23
|
+
.default(20)
|
|
24
|
+
.describe("Maximum number of edits to return (most recent first)"),
|
|
25
|
+
since: z
|
|
26
|
+
.string()
|
|
27
|
+
.datetime()
|
|
28
|
+
.optional()
|
|
29
|
+
.describe("Only return edits with an ISO-8601 timestamp at or after this"),
|
|
30
|
+
file: z
|
|
31
|
+
.string()
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("Filter to edits on this file (relative to project root)"),
|
|
34
|
+
};
|
|
35
|
+
const EDIT_LOG = path.join(".layout", "live", "recent-edits.json");
|
|
36
|
+
function applyFilters(edits, input) {
|
|
37
|
+
const limit = input.limit ?? 20;
|
|
38
|
+
const sinceMs = input.since ? Date.parse(input.since) : undefined;
|
|
39
|
+
let filtered = edits;
|
|
40
|
+
if (input.file) {
|
|
41
|
+
filtered = filtered.filter((e) => e.file === input.file);
|
|
42
|
+
}
|
|
43
|
+
if (sinceMs !== undefined && !Number.isNaN(sinceMs)) {
|
|
44
|
+
filtered = filtered.filter((e) => Date.parse(e.timestamp) >= sinceMs);
|
|
45
|
+
}
|
|
46
|
+
// Most recent first.
|
|
47
|
+
filtered = [...filtered].sort((a, b) => Date.parse(b.timestamp) - Date.parse(a.timestamp));
|
|
48
|
+
const truncated = filtered.length > limit;
|
|
49
|
+
return { edits: filtered.slice(0, limit), truncated };
|
|
50
|
+
}
|
|
51
|
+
async function readEditLog(projectRoot) {
|
|
52
|
+
try {
|
|
53
|
+
const raw = await fs.readFile(path.join(projectRoot, EDIT_LOG), "utf8");
|
|
54
|
+
const parsed = JSON.parse(raw);
|
|
55
|
+
if (Array.isArray(parsed))
|
|
56
|
+
return parsed;
|
|
57
|
+
if (parsed && Array.isArray(parsed.edits)) {
|
|
58
|
+
return parsed.edits;
|
|
59
|
+
}
|
|
60
|
+
return [];
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export function handler() {
|
|
67
|
+
return async (input) => {
|
|
68
|
+
const projectRoot = process.cwd();
|
|
69
|
+
const live = await connectToLive(projectRoot);
|
|
70
|
+
let result;
|
|
71
|
+
if (live) {
|
|
72
|
+
try {
|
|
73
|
+
const res = await live.send({
|
|
74
|
+
method: "get-edits",
|
|
75
|
+
params: {
|
|
76
|
+
limit: input.limit ?? 20,
|
|
77
|
+
since: input.since,
|
|
78
|
+
file: input.file,
|
|
79
|
+
},
|
|
80
|
+
});
|
|
81
|
+
result = {
|
|
82
|
+
source: "live-socket",
|
|
83
|
+
edits: res?.edits ?? [],
|
|
84
|
+
truncated: Boolean(res?.truncated),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
const all = await readEditLog(projectRoot);
|
|
89
|
+
const { edits, truncated } = applyFilters(all, input);
|
|
90
|
+
result = { source: "edit-log-file", edits, truncated };
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
live.close();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
const all = await readEditLog(projectRoot);
|
|
98
|
+
const { edits, truncated } = applyFilters(all, input);
|
|
99
|
+
result = { source: "edit-log-file", edits, truncated };
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
103
|
+
};
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=get-recent-visual-edits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-recent-visual-edits.js","sourceRoot":"","sources":["../../../../src/mcp/tools/get-recent-visual-edits.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const name = "get-selected-element";
|
|
2
|
+
export declare const description: string;
|
|
3
|
+
export declare const inputSchema: {};
|
|
4
|
+
export declare function handler(): () => Promise<{
|
|
5
|
+
content: {
|
|
6
|
+
type: "text";
|
|
7
|
+
text: string;
|
|
8
|
+
}[];
|
|
9
|
+
}>;
|
|
10
|
+
//# sourceMappingURL=get-selected-element.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-selected-element.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/get-selected-element.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,IAAI,yBAAyB,CAAC;AAE3C,eAAO,MAAM,WAAW,QAG2D,CAAC;AAGpF,eAAO,MAAM,WAAW,IAAK,CAAC;AAY9B,wBAAgB,OAAO;;;;;GA8BtB"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool: get-selected-element
|
|
3
|
+
*
|
|
4
|
+
* Returns the element currently selected in the layout Live desktop app.
|
|
5
|
+
* Falls back cleanly to `{ running: false }` when Live is not running.
|
|
6
|
+
*/
|
|
7
|
+
import { connectToLive } from "./_live-socket.js";
|
|
8
|
+
export const name = "get-selected-element";
|
|
9
|
+
export const description = "Returns the element currently selected in layout Live (desktop app). " +
|
|
10
|
+
"Use this when the user says 'this', 'that one', or refers to something " +
|
|
11
|
+
"they have selected visually. Returns { running: false } if Live is not running.";
|
|
12
|
+
// No inputs — mirrors the existing raw-shape convention (e.g. get-design-system).
|
|
13
|
+
export const inputSchema = {};
|
|
14
|
+
export function handler() {
|
|
15
|
+
return async () => {
|
|
16
|
+
const live = await connectToLive();
|
|
17
|
+
if (!live) {
|
|
18
|
+
return {
|
|
19
|
+
content: [
|
|
20
|
+
{ type: "text", text: JSON.stringify({ running: false }) },
|
|
21
|
+
],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
try {
|
|
25
|
+
const sel = await live.send({ method: "get-selection" });
|
|
26
|
+
const payload = sel?.selected
|
|
27
|
+
? { running: true, ...sel }
|
|
28
|
+
: { running: true, selected: false };
|
|
29
|
+
return {
|
|
30
|
+
content: [{ type: "text", text: JSON.stringify(payload) }],
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Socket present but query failed — surface as not running rather than error.
|
|
35
|
+
return {
|
|
36
|
+
content: [
|
|
37
|
+
{ type: "text", text: JSON.stringify({ running: false }) },
|
|
38
|
+
],
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
finally {
|
|
42
|
+
live.close();
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=get-selected-element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-selected-element.js","sourceRoot":"","sources":["../../../../src/mcp/tools/get-selected-element.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAElD,MAAM,CAAC,MAAM,IAAI,GAAG,sBAAsB,CAAC;AAE3C,MAAM,CAAC,MAAM,WAAW,GACtB,uEAAuE;IACvE,yEAAyE;IACzE,iFAAiF,CAAC;AAEpF,kFAAkF;AAClF,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAY9B,MAAM,UAAU,OAAO;IACrB,OAAO,KAAK,IAAI,EAAE;QAChB,MAAM,IAAI,GAAG,MAAM,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE;iBACpE;aACF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CAAkB,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC,CAAC;YAC1E,MAAM,OAAO,GAAG,GAAG,EAAE,QAAQ;gBAC3B,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,GAAG,EAAE;gBAC3B,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;YACvC,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC;aACpE,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,8EAA8E;YAC9E,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE;iBACpE;aACF,CAAC;QACJ,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool: lock-file
|
|
3
|
+
*
|
|
4
|
+
* Reserves exclusive write access to a project file so Claude and the layout
|
|
5
|
+
* Live desktop app don't clobber each other's edits. Backed by the atomic
|
|
6
|
+
* file-based lock store at `.layout/live/locks.json`.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
export declare const name = "lock-file";
|
|
10
|
+
export declare const description: string;
|
|
11
|
+
export declare const inputSchema: {
|
|
12
|
+
path: z.ZodString;
|
|
13
|
+
ttl_seconds: z.ZodDefault<z.ZodNumber>;
|
|
14
|
+
reason: z.ZodOptional<z.ZodString>;
|
|
15
|
+
};
|
|
16
|
+
type Input = {
|
|
17
|
+
path: string;
|
|
18
|
+
ttl_seconds?: number;
|
|
19
|
+
reason?: string;
|
|
20
|
+
};
|
|
21
|
+
export declare function handler(): (input: Input) => Promise<{
|
|
22
|
+
content: {
|
|
23
|
+
type: "text";
|
|
24
|
+
text: string;
|
|
25
|
+
}[];
|
|
26
|
+
}>;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=lock-file.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock-file.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/lock-file.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,IAAI,cAAc,CAAC;AAEhC,eAAO,MAAM,WAAW,QAID,CAAC;AAExB,eAAO,MAAM,WAAW;;;;CAavB,CAAC;AAEF,KAAK,KAAK,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE,wBAAgB,OAAO,KACP,OAAO,KAAK;;;;;GAW3B"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool: lock-file
|
|
3
|
+
*
|
|
4
|
+
* Reserves exclusive write access to a project file so Claude and the layout
|
|
5
|
+
* Live desktop app don't clobber each other's edits. Backed by the atomic
|
|
6
|
+
* file-based lock store at `.layout/live/locks.json`.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { acquireLock } from "../live-lock-store.js";
|
|
10
|
+
export const name = "lock-file";
|
|
11
|
+
export const description = "Reserves exclusive write access to a file. Call this before editing a " +
|
|
12
|
+
"file that may also be open in layout Live. Hold for the specified TTL, " +
|
|
13
|
+
"then release with unlock-file. If the lock is held by Live, retry briefly " +
|
|
14
|
+
"or notify the user.";
|
|
15
|
+
export const inputSchema = {
|
|
16
|
+
path: z.string().describe("Path relative to project root"),
|
|
17
|
+
ttl_seconds: z
|
|
18
|
+
.number()
|
|
19
|
+
.int()
|
|
20
|
+
.positive()
|
|
21
|
+
.max(300)
|
|
22
|
+
.default(60)
|
|
23
|
+
.describe("How long the lock is held before it auto-expires"),
|
|
24
|
+
reason: z
|
|
25
|
+
.string()
|
|
26
|
+
.optional()
|
|
27
|
+
.describe("Why the lock is being acquired"),
|
|
28
|
+
};
|
|
29
|
+
export function handler() {
|
|
30
|
+
return async (input) => {
|
|
31
|
+
const result = await acquireLock(process.cwd(), {
|
|
32
|
+
path: input.path,
|
|
33
|
+
ttlSeconds: input.ttl_seconds ?? 60,
|
|
34
|
+
reason: input.reason,
|
|
35
|
+
holder: "claude",
|
|
36
|
+
});
|
|
37
|
+
return {
|
|
38
|
+
content: [{ type: "text", text: JSON.stringify(result) }],
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=lock-file.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lock-file.js","sourceRoot":"","sources":["../../../../src/mcp/tools/lock-file.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,MAAM,IAAI,GAAG,WAAW,CAAC;AAEhC,MAAM,CAAC,MAAM,WAAW,GACtB,wEAAwE;IACxE,yEAAyE;IACzE,4EAA4E;IAC5E,qBAAqB,CAAC;AAExB,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+BAA+B,CAAC;IAC1D,WAAW,EAAE,CAAC;SACX,MAAM,EAAE;SACR,GAAG,EAAE;SACL,QAAQ,EAAE;SACV,GAAG,CAAC,GAAG,CAAC;SACR,OAAO,CAAC,EAAE,CAAC;SACX,QAAQ,CAAC,kDAAkD,CAAC;IAC/D,MAAM,EAAE,CAAC;SACN,MAAM,EAAE;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,gCAAgC,CAAC;CAC9C,CAAC;AAIF,MAAM,UAAU,OAAO;IACrB,OAAO,KAAK,EAAE,KAAY,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE;YAC9C,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,UAAU,EAAE,KAAK,CAAC,WAAW,IAAI,EAAE;YACnC,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;QACH,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;SACnE,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC"}
|