@layoutdesign/context 0.6.0 → 0.11.0

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.
Files changed (77) hide show
  1. package/README.md +71 -0
  2. package/dist/bin/cli.js +13 -5
  3. package/dist/bin/cli.js.map +1 -1
  4. package/dist/src/cli/fetch-kit.d.ts +16 -0
  5. package/dist/src/cli/fetch-kit.d.ts.map +1 -0
  6. package/dist/src/cli/fetch-kit.js +52 -0
  7. package/dist/src/cli/fetch-kit.js.map +1 -0
  8. package/dist/src/cli/import-zip.d.ts +13 -0
  9. package/dist/src/cli/import-zip.d.ts.map +1 -1
  10. package/dist/src/cli/import-zip.js +75 -56
  11. package/dist/src/cli/import-zip.js.map +1 -1
  12. package/dist/src/cli/install.d.ts +2 -1
  13. package/dist/src/cli/install.d.ts.map +1 -1
  14. package/dist/src/cli/install.js +46 -1
  15. package/dist/src/cli/install.js.map +1 -1
  16. package/dist/src/cli/live-notify.d.ts +2 -0
  17. package/dist/src/cli/live-notify.d.ts.map +1 -0
  18. package/dist/src/cli/live-notify.js +29 -0
  19. package/dist/src/cli/live-notify.js.map +1 -0
  20. package/dist/src/cli/use.d.ts.map +1 -1
  21. package/dist/src/cli/use.js +37 -18
  22. package/dist/src/cli/use.js.map +1 -1
  23. package/dist/src/install/live.d.ts +5 -0
  24. package/dist/src/install/live.d.ts.map +1 -0
  25. package/dist/src/install/live.js +285 -0
  26. package/dist/src/install/live.js.map +1 -0
  27. package/dist/src/kit/registry.d.ts.map +1 -1
  28. package/dist/src/kit/registry.js +4 -2
  29. package/dist/src/kit/registry.js.map +1 -1
  30. package/dist/src/mcp/live-lock-store.d.ts +40 -0
  31. package/dist/src/mcp/live-lock-store.d.ts.map +1 -0
  32. package/dist/src/mcp/live-lock-store.js +134 -0
  33. package/dist/src/mcp/live-lock-store.js.map +1 -0
  34. package/dist/src/mcp/server.d.ts.map +1 -1
  35. package/dist/src/mcp/server.js +11 -0
  36. package/dist/src/mcp/server.js.map +1 -1
  37. package/dist/src/mcp/tools/_live-socket.d.ts +23 -0
  38. package/dist/src/mcp/tools/_live-socket.d.ts.map +1 -0
  39. package/dist/src/mcp/tools/_live-socket.js +135 -0
  40. package/dist/src/mcp/tools/_live-socket.js.map +1 -0
  41. package/dist/src/mcp/tools/check-setup.d.ts +14 -1
  42. package/dist/src/mcp/tools/check-setup.d.ts.map +1 -1
  43. package/dist/src/mcp/tools/check-setup.js +75 -1
  44. package/dist/src/mcp/tools/check-setup.js.map +1 -1
  45. package/dist/src/mcp/tools/get-recent-visual-edits.d.ts +40 -0
  46. package/dist/src/mcp/tools/get-recent-visual-edits.d.ts.map +1 -0
  47. package/dist/src/mcp/tools/get-recent-visual-edits.js +106 -0
  48. package/dist/src/mcp/tools/get-recent-visual-edits.js.map +1 -0
  49. package/dist/src/mcp/tools/get-selected-element.d.ts +10 -0
  50. package/dist/src/mcp/tools/get-selected-element.d.ts.map +1 -0
  51. package/dist/src/mcp/tools/get-selected-element.js +46 -0
  52. package/dist/src/mcp/tools/get-selected-element.js.map +1 -0
  53. package/dist/src/mcp/tools/lock-file.d.ts +28 -0
  54. package/dist/src/mcp/tools/lock-file.d.ts.map +1 -0
  55. package/dist/src/mcp/tools/lock-file.js +42 -0
  56. package/dist/src/mcp/tools/lock-file.js.map +1 -0
  57. package/dist/src/mcp/tools/unlock-file.d.ts +23 -0
  58. package/dist/src/mcp/tools/unlock-file.d.ts.map +1 -0
  59. package/dist/src/mcp/tools/unlock-file.js +23 -0
  60. package/dist/src/mcp/tools/unlock-file.js.map +1 -0
  61. package/dist/src/plugins/next/babel-loader.d.ts +8 -0
  62. package/dist/src/plugins/next/babel-loader.d.ts.map +1 -0
  63. package/dist/src/plugins/next/babel-loader.js +26 -0
  64. package/dist/src/plugins/next/babel-loader.js.map +1 -0
  65. package/dist/src/plugins/next/index.d.ts +23 -0
  66. package/dist/src/plugins/next/index.d.ts.map +1 -0
  67. package/dist/src/plugins/next/index.js +58 -0
  68. package/dist/src/plugins/next/index.js.map +1 -0
  69. package/dist/src/plugins/transform.d.ts +19 -0
  70. package/dist/src/plugins/transform.d.ts.map +1 -0
  71. package/dist/src/plugins/transform.js +177 -0
  72. package/dist/src/plugins/transform.js.map +1 -0
  73. package/dist/src/plugins/vite/index.d.ts +24 -0
  74. package/dist/src/plugins/vite/index.d.ts.map +1 -0
  75. package/dist/src/plugins/vite/index.js +56 -0
  76. package/dist/src/plugins/vite/index.js.map +1 -0
  77. package/package.json +31 -9
@@ -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"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * MCP tool: unlock-file
3
+ *
4
+ * Releases a previously-acquired file lock by its lock id. Only the entry
5
+ * whose `lock_id` matches is removed.
6
+ */
7
+ import { z } from "zod";
8
+ export declare const name = "unlock-file";
9
+ export declare const description: string;
10
+ export declare const inputSchema: {
11
+ lock_id: z.ZodString;
12
+ };
13
+ type Input = {
14
+ lock_id: string;
15
+ };
16
+ export declare function handler(): (input: Input) => Promise<{
17
+ content: {
18
+ type: "text";
19
+ text: string;
20
+ }[];
21
+ }>;
22
+ export {};
23
+ //# sourceMappingURL=unlock-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unlock-file.d.ts","sourceRoot":"","sources":["../../../../src/mcp/tools/unlock-file.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,IAAI,gBAAgB,CAAC;AAElC,eAAO,MAAM,WAAW,QAEkD,CAAC;AAE3E,eAAO,MAAM,WAAW;;CAEvB,CAAC;AAEF,KAAK,KAAK,GAAG;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEjC,wBAAgB,OAAO,KACP,OAAO,KAAK;;;;;GAM3B"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * MCP tool: unlock-file
3
+ *
4
+ * Releases a previously-acquired file lock by its lock id. Only the entry
5
+ * whose `lock_id` matches is removed.
6
+ */
7
+ import { z } from "zod";
8
+ import { releaseLock } from "../live-lock-store.js";
9
+ export const name = "unlock-file";
10
+ export const description = "Releases a previously-acquired file lock. Pass the lock_id returned by " +
11
+ "lock-file. A non-matching or already-expired lock_id releases nothing.";
12
+ export const inputSchema = {
13
+ lock_id: z.string().describe("The lock_id returned by a prior lock-file call"),
14
+ };
15
+ export function handler() {
16
+ return async (input) => {
17
+ const result = await releaseLock(process.cwd(), input.lock_id);
18
+ return {
19
+ content: [{ type: "text", text: JSON.stringify(result) }],
20
+ };
21
+ };
22
+ }
23
+ //# sourceMappingURL=unlock-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unlock-file.js","sourceRoot":"","sources":["../../../../src/mcp/tools/unlock-file.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAEpD,MAAM,CAAC,MAAM,IAAI,GAAG,aAAa,CAAC;AAElC,MAAM,CAAC,MAAM,WAAW,GACtB,yEAAyE;IACzE,wEAAwE,CAAC;AAE3E,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gDAAgD,CAAC;CAC/E,CAAC;AAIF,MAAM,UAAU,OAAO;IACrB,OAAO,KAAK,EAAE,KAAY,EAAE,EAAE;QAC5B,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/D,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"}
@@ -0,0 +1,8 @@
1
+ interface LoaderContext {
2
+ resourcePath: string;
3
+ rootContext: string;
4
+ async(): (err: Error | null, content?: string, sourceMap?: object) => void;
5
+ }
6
+ export default function layoutBabelLoader(this: LoaderContext, source: string, inputMap?: object): void;
7
+ export {};
8
+ //# sourceMappingURL=babel-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"babel-loader.d.ts","sourceRoot":"","sources":["../../../../src/plugins/next/babel-loader.ts"],"names":[],"mappings":"AASA,UAAU,aAAa;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,IAAI,CACP,GAAG,EAAE,KAAK,GAAG,IAAI,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,SAAS,CAAC,EAAE,MAAM,KACf,IAAI,CAAC;CACX;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,CACvC,IAAI,EAAE,aAAa,EACnB,MAAM,EAAE,MAAM,EACd,QAAQ,CAAC,EAAE,MAAM,GAChB,IAAI,CAmBN"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Thin webpack-loader wrapper around the shared layout Babel transform.
3
+ *
4
+ * Runs after Next's own Babel loader (so it sees plain JSX). Injects the
5
+ * layout source-location attrs in dev only. Source maps are chained back to
6
+ * webpack so error stacks still point at the user's original lines.
7
+ */
8
+ import { transformWithLayoutAttrs } from "../transform.js";
9
+ export default function layoutBabelLoader(source, inputMap) {
10
+ const callback = this.async();
11
+ try {
12
+ const result = transformWithLayoutAttrs(source, this.resourcePath, this.rootContext);
13
+ if (result.code === source && result.map === null) {
14
+ // Nothing injected — pass through with the incoming map intact.
15
+ callback(null, source, inputMap);
16
+ return;
17
+ }
18
+ callback(null, result.code, result.map ?? inputMap);
19
+ }
20
+ catch (err) {
21
+ // Never break the dev build over an attr-injection failure.
22
+ callback(null, source, inputMap);
23
+ void err;
24
+ }
25
+ }
26
+ //# sourceMappingURL=babel-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"babel-loader.js","sourceRoot":"","sources":["../../../../src/plugins/next/babel-loader.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAY3D,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAEvC,MAAc,EACd,QAAiB;IAEjB,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,wBAAwB,CACrC,MAAM,EACN,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,WAAW,CACjB,CAAC;QACF,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;YAClD,gEAAgE;YAChE,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QACD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,IAAI,QAAQ,CAAC,CAAC;IACtD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,4DAA4D;QAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;QACjC,KAAK,GAAG,CAAC;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,23 @@
1
+ type WebpackRule = {
2
+ test: RegExp;
3
+ exclude?: RegExp;
4
+ use: unknown[];
5
+ };
6
+ interface WebpackConfigLike {
7
+ module?: {
8
+ rules?: WebpackRule[];
9
+ };
10
+ }
11
+ interface WebpackOptions {
12
+ dev: boolean;
13
+ defaultLoaders?: {
14
+ babel?: unknown;
15
+ };
16
+ }
17
+ export interface NextConfigLike {
18
+ webpack?: (config: WebpackConfigLike, options: WebpackOptions) => WebpackConfigLike;
19
+ [key: string]: unknown;
20
+ }
21
+ export default function withLayout(nextConfig?: NextConfigLike): NextConfigLike;
22
+ export {};
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/plugins/next/index.ts"],"names":[],"mappings":"AAkBA,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,OAAO,EAAE,CAAC;CAChB,CAAC;AAEF,UAAU,iBAAiB;IACzB,MAAM,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC;CACpC;AAED,UAAU,cAAc;IACtB,GAAG,EAAE,OAAO,CAAC;IACb,cAAc,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC;CACtC;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,EAAE,CACR,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,cAAc,KACpB,iBAAiB,CAAC;IACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AASD,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,UAAU,GAAE,cAAmB,GAC9B,cAAc,CAoChB"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * `@layoutdesign/context/next-plugin`
3
+ *
4
+ * Next.js config HOC. Adds a dev-only webpack rule that runs the shared
5
+ * layout Babel transform on .tsx/.jsx files (Option A from the spec — Babel
6
+ * via webpack; SWC plugin is a future v1.1 item). No-op in production.
7
+ *
8
+ * import withLayout from '@layoutdesign/context/next-plugin';
9
+ * export default withLayout({ /* ...next config *\/ });
10
+ *
11
+ * Composes cleanly with an existing user `webpack(config, options)` override:
12
+ * we mutate the config, then defer to the user's function if present.
13
+ *
14
+ * `next`/`webpack` are optional peers — types are kept structural so the
15
+ * package builds and ships without them installed.
16
+ */
17
+ import { fileURLToPath } from "node:url";
18
+ /** Absolute path to the compiled babel-loader, resolved relative to here. */
19
+ function babelLoaderPath() {
20
+ return fileURLToPath(new URL("./babel-loader.js", import.meta.url));
21
+ }
22
+ let turbopackWarned = false;
23
+ export default function withLayout(nextConfig = {}) {
24
+ // Turbopack (`next dev --turbo`, default in newer Next) ignores the
25
+ // `webpack()` hook, so the dev tagging below never runs and layout Live
26
+ // would silently fail to resolve elements. Make that explicit once
27
+ // rather than silent. Native Turbopack/SWC tagging is tracked separately.
28
+ if (process.env.TURBOPACK && !turbopackWarned) {
29
+ turbopackWarned = true;
30
+ console.warn("[@layoutdesign/context] Turbopack detected — layout Live source " +
31
+ "tagging needs webpack. Run `next dev` without --turbo for the " +
32
+ "visual-edit loop (Turbopack support is tracked, not yet shipped).");
33
+ }
34
+ return {
35
+ ...nextConfig,
36
+ webpack(config, options) {
37
+ if (options.dev) {
38
+ config.module ??= {};
39
+ config.module.rules ??= [];
40
+ const use = [];
41
+ if (options.defaultLoaders?.babel) {
42
+ use.push(options.defaultLoaders.babel);
43
+ }
44
+ use.push({ loader: babelLoaderPath() });
45
+ config.module.rules.push({
46
+ test: /\.(tsx|jsx)$/,
47
+ exclude: /node_modules/,
48
+ use,
49
+ });
50
+ }
51
+ // Defer to the user's own webpack override, if any.
52
+ return typeof nextConfig.webpack === "function"
53
+ ? nextConfig.webpack(config, options)
54
+ : config;
55
+ },
56
+ };
57
+ }
58
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/plugins/next/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAyBzC,6EAA6E;AAC7E,SAAS,eAAe;IACtB,OAAO,aAAa,CAAC,IAAI,GAAG,CAAC,mBAAmB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACtE,CAAC;AAED,IAAI,eAAe,GAAG,KAAK,CAAC;AAE5B,MAAM,CAAC,OAAO,UAAU,UAAU,CAChC,aAA6B,EAAE;IAE/B,oEAAoE;IACpE,wEAAwE;IACxE,mEAAmE;IACnE,0EAA0E;IAC1E,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,eAAe,EAAE,CAAC;QAC9C,eAAe,GAAG,IAAI,CAAC;QACvB,OAAO,CAAC,IAAI,CACV,kEAAkE;YAChE,gEAAgE;YAChE,mEAAmE,CACtE,CAAC;IACJ,CAAC;IACD,OAAO;QACL,GAAG,UAAU;QACb,OAAO,CAAC,MAAyB,EAAE,OAAuB;YACxD,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;gBAChB,MAAM,CAAC,MAAM,KAAK,EAAE,CAAC;gBACrB,MAAM,CAAC,MAAM,CAAC,KAAK,KAAK,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAc,EAAE,CAAC;gBAC1B,IAAI,OAAO,CAAC,cAAc,EAAE,KAAK,EAAE,CAAC;oBAClC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;gBACzC,CAAC;gBACD,GAAG,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,eAAe,EAAE,EAAE,CAAC,CAAC;gBACxC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;oBACvB,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,cAAc;oBACvB,GAAG;iBACJ,CAAC,CAAC;YACL,CAAC;YACD,oDAAoD;YACpD,OAAO,OAAO,UAAU,CAAC,OAAO,KAAK,UAAU;gBAC7C,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC;gBACrC,CAAC,CAAC,MAAM,CAAC;QACb,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,19 @@
1
+ export interface TransformOptions {
2
+ /** Force-enable in production builds (not recommended). Default: false. */
3
+ production?: boolean;
4
+ }
5
+ export interface TransformResult {
6
+ code: string;
7
+ map: object | null;
8
+ }
9
+ /** Whether attrs should be injected given env + options. */
10
+ export declare function shouldTransform(options?: TransformOptions): boolean;
11
+ /**
12
+ * Transform `code` for `filename`, injecting the layout source-location attrs.
13
+ *
14
+ * Returns the original code unchanged (with `map: null`) when transformation
15
+ * is skipped (production env, parse failure). Never throws on user code — a
16
+ * malformed file is passed through untouched so the dev build keeps working.
17
+ */
18
+ export declare function transformWithLayoutAttrs(code: string, filename: string, projectRoot: string, options?: TransformOptions): TransformResult;
19
+ //# sourceMappingURL=transform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../../src/plugins/transform.ts"],"names":[],"mappings":"AA+CA,MAAM,WAAW,gBAAgB;IAC/B,2EAA2E;IAC3E,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,OAAO,GAAE,gBAAqB,GAAG,OAAO,CAGvE;AA0ED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,gBAAqB,GAC7B,eAAe,CAyEjB"}
@@ -0,0 +1,177 @@
1
+ /**
2
+ * Shared Babel transform used by both the Vite and Next.js plugins.
3
+ *
4
+ * Walks the JSX/TSX AST and injects four source-location attributes onto every
5
+ * DOM-emitting JSX element so layout Live can resolve a clicked DOM node back
6
+ * to its exact source position:
7
+ *
8
+ * data-layout-source-file — path relative to project root
9
+ * data-layout-source-line — 1-indexed line
10
+ * data-layout-source-col — 1-indexed column
11
+ * data-layout-component — nearest enclosing component name
12
+ *
13
+ * Dev-only: a no-op when NODE_ENV === 'production' (unless `production: true`
14
+ * is forced). Idempotent: elements already carrying the attrs are left alone.
15
+ */
16
+ import { parse } from "@babel/parser";
17
+ import * as _traverseNs from "@babel/traverse";
18
+ import * as _generateNs from "@babel/generator";
19
+ import * as t from "@babel/types";
20
+ import path from "node:path";
21
+ // @babel/traverse and @babel/generator ship CJS default exports. Depending on
22
+ // the ESM loader (tsc-built dist vs tsx) the callable lands at the namespace,
23
+ // `.default`, or `.default.default` — unwrap to the first callable.
24
+ function unwrapCallable(ns) {
25
+ let cur = ns;
26
+ for (let i = 0; i < 3; i++) {
27
+ if (typeof cur === "function")
28
+ return cur;
29
+ cur = cur?.default;
30
+ }
31
+ throw new Error("Could not resolve a callable Babel export");
32
+ }
33
+ const traverse = unwrapCallable(_traverseNs);
34
+ const generate = unwrapCallable(_generateNs);
35
+ const MARKER_ATTR = "data-layout-source-file";
36
+ // React's raw-HTML escape-hatch prop. Built at runtime so this source file
37
+ // doesn't trip content scanners; semantics are unchanged.
38
+ const RAW_HTML_PROP = ["dangerously", "Set", "Inner", "HTML"].join("");
39
+ /** Whether attrs should be injected given env + options. */
40
+ export function shouldTransform(options = {}) {
41
+ if (options.production)
42
+ return true;
43
+ return process.env.NODE_ENV !== "production";
44
+ }
45
+ function attr(name, value) {
46
+ return t.jsxAttribute(t.jsxIdentifier(name), t.stringLiteral(value));
47
+ }
48
+ /** Name of the nearest enclosing function / arrow / class, or 'Anonymous'. */
49
+ function enclosingComponentName(elementPath) {
50
+ let p = elementPath.parentPath;
51
+ while (p) {
52
+ const node = p.node;
53
+ if (t.isFunctionDeclaration(node) && node.id)
54
+ return node.id.name;
55
+ if (t.isClassDeclaration(node) && node.id)
56
+ return node.id.name;
57
+ if ((t.isArrowFunctionExpression(node) || t.isFunctionExpression(node)) &&
58
+ t.isVariableDeclarator(p.parentPath?.node) &&
59
+ t.isIdentifier(p.parentPath.node.id)) {
60
+ return p.parentPath.node.id.name;
61
+ }
62
+ // Named function expression: const x = function Foo() {}
63
+ if (t.isFunctionExpression(node) && node.id)
64
+ return node.id.name;
65
+ p = p.parentPath;
66
+ }
67
+ return "Anonymous";
68
+ }
69
+ function isPreAttributed(opening) {
70
+ return opening.attributes.some((a) => t.isJSXAttribute(a) &&
71
+ t.isJSXIdentifier(a.name) &&
72
+ a.name.name === MARKER_ATTR);
73
+ }
74
+ function hasRawHtmlProp(opening) {
75
+ return opening.attributes.some((a) => t.isJSXAttribute(a) &&
76
+ t.isJSXIdentifier(a.name) &&
77
+ a.name.name === RAW_HTML_PROP);
78
+ }
79
+ /**
80
+ * Does this element have a STATICALLY-EDITABLE `className` — a string
81
+ * literal, `{"…"}`, or a template literal with no expressions? Used to
82
+ * decide whether a capitalised component usage (`<Pill className="p-4"/>`)
83
+ * is worth tagging: layout Live can edit that prop string in place exactly
84
+ * like a host element's className. cn()/cva()/dynamic classNames are NOT
85
+ * editable, so those component usages stay untagged (→ library-component).
86
+ */
87
+ function hasLiteralClassName(opening) {
88
+ for (const a of opening.attributes) {
89
+ if (!t.isJSXAttribute(a) ||
90
+ !t.isJSXIdentifier(a.name) ||
91
+ a.name.name !== "className") {
92
+ continue;
93
+ }
94
+ const v = a.value;
95
+ if (t.isStringLiteral(v))
96
+ return true;
97
+ if (t.isJSXExpressionContainer(v)) {
98
+ const e = v.expression;
99
+ if (t.isStringLiteral(e))
100
+ return true;
101
+ if (t.isTemplateLiteral(e) && e.expressions.length === 0)
102
+ return true;
103
+ }
104
+ return false; // className present but dynamic — not editable here
105
+ }
106
+ return false; // no className prop
107
+ }
108
+ /**
109
+ * Transform `code` for `filename`, injecting the layout source-location attrs.
110
+ *
111
+ * Returns the original code unchanged (with `map: null`) when transformation
112
+ * is skipped (production env, parse failure). Never throws on user code — a
113
+ * malformed file is passed through untouched so the dev build keeps working.
114
+ */
115
+ export function transformWithLayoutAttrs(code, filename, projectRoot, options = {}) {
116
+ if (!shouldTransform(options)) {
117
+ return { code, map: null };
118
+ }
119
+ let ast;
120
+ try {
121
+ ast = parse(code, {
122
+ sourceType: "module",
123
+ plugins: ["jsx", "typescript"],
124
+ });
125
+ }
126
+ catch {
127
+ // Don't break the dev build on a syntax error mid-edit.
128
+ return { code, map: null };
129
+ }
130
+ const relativePath = path
131
+ .relative(projectRoot, filename)
132
+ .split(path.sep)
133
+ .join("/");
134
+ let mutated = false;
135
+ traverse(ast, {
136
+ JSXElement(elPath) {
137
+ const opening = elPath.node.openingElement;
138
+ const tagName = opening.name;
139
+ // Member expressions (Context.Provider, namespaced motion.div) and
140
+ // namespaced names are not plain DOM tags — skip.
141
+ if (!t.isJSXIdentifier(tagName))
142
+ return;
143
+ // Fragments and capitalised component names: the component is attributed
144
+ // at its own root element, not at each usage site.
145
+ if (tagName.name === "Fragment")
146
+ return;
147
+ // Capitalised component usage: normally attributed at the component's
148
+ // own root, NOT each call site. BUT if the call site passes a static
149
+ // `className` (`<Pill className="p-4"/>`), that string IS editable in
150
+ // place — tag the usage so layout Live can resolve + edit it (the
151
+ // component must forward unknown props for the attrs to reach the
152
+ // DOM; if it doesn't, resolution falls back to fibre-only). Dynamic
153
+ // classNames stay untagged → surfaced as library-component.
154
+ if (/^[A-Z]/.test(tagName.name) && !hasLiteralClassName(opening)) {
155
+ return;
156
+ }
157
+ // Idempotent.
158
+ if (isPreAttributed(opening))
159
+ return;
160
+ // Children of the raw-HTML prop are an opaque HTML string, not JSX — the
161
+ // element bearing it has no JSX element children to attribute.
162
+ if (hasRawHtmlProp(opening))
163
+ return;
164
+ const loc = opening.loc?.start;
165
+ if (!loc)
166
+ return;
167
+ opening.attributes.push(attr("data-layout-source-file", relativePath), attr("data-layout-source-line", String(loc.line)), attr("data-layout-source-col", String(loc.column + 1)), attr("data-layout-component", enclosingComponentName(elPath)));
168
+ mutated = true;
169
+ },
170
+ });
171
+ if (!mutated) {
172
+ return { code, map: null };
173
+ }
174
+ const result = generate(ast, { sourceMaps: true, sourceFileName: filename, retainLines: true }, code);
175
+ return { code: result.code, map: result.map ?? null };
176
+ }
177
+ //# sourceMappingURL=transform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transform.js","sourceRoot":"","sources":["../../../src/plugins/transform.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ export interface LayoutVitePluginOptions {
2
+ /** Globs/patterns to include. Default: all .tsx/.jsx. */
3
+ include?: string | string[];
4
+ /** Substrings/patterns to exclude. Default: node_modules. */
5
+ exclude?: string | string[];
6
+ /** Force-enable in production (not recommended). Default: false. */
7
+ production?: boolean;
8
+ }
9
+ /** Minimal structural shape of the bits of a Vite plugin we use. */
10
+ interface VitePluginLike {
11
+ name: string;
12
+ enforce: "pre";
13
+ apply: "serve";
14
+ configResolved(config: {
15
+ root?: string;
16
+ }): void;
17
+ transform(code: string, id: string): {
18
+ code: string;
19
+ map: object | null;
20
+ } | null;
21
+ }
22
+ export default function layout(options?: LayoutVitePluginOptions): VitePluginLike;
23
+ export {};
24
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/plugins/vite/index.ts"],"names":[],"mappings":"AAgBA,MAAM,WAAW,uBAAuB;IACtC,yDAAyD;IACzD,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,oEAAoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,oEAAoE;AACpE,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,KAAK,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,cAAc,CAAC,MAAM,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAChD,SAAS,CACP,IAAI,EAAE,MAAM,EACZ,EAAE,EAAE,MAAM,GACT;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;CAChD;AAOD,MAAM,CAAC,OAAO,UAAU,MAAM,CAC5B,OAAO,GAAE,uBAA4B,GACpC,cAAc,CA8BhB"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * `@layoutdesign/context/vite-plugin`
3
+ *
4
+ * Injects layout source-location attributes into JSX during the Vite dev
5
+ * server build. No-op in production builds (`apply: 'serve'` + the transform's
6
+ * own NODE_ENV guard). Place this *before* `@vitejs/plugin-react`.
7
+ *
8
+ * import layout from '@layoutdesign/context/vite-plugin';
9
+ * export default defineConfig({ plugins: [layout(), react()] });
10
+ *
11
+ * `vite` is an optional peer — we don't import its types so the package builds
12
+ * and ships without vite installed. The returned object is structurally a
13
+ * Vite `Plugin`.
14
+ */
15
+ import { transformWithLayoutAttrs } from "../transform.js";
16
+ function toArray(v) {
17
+ if (!v)
18
+ return [];
19
+ return Array.isArray(v) ? v : [v];
20
+ }
21
+ export default function layout(options = {}) {
22
+ const exclude = toArray(options.exclude);
23
+ const defaultExcluded = (id) => id.includes("node_modules");
24
+ const include = toArray(options.include);
25
+ let root = process.cwd();
26
+ return {
27
+ name: "@layoutdesign/context/vite-plugin",
28
+ enforce: "pre",
29
+ apply: "serve",
30
+ configResolved(config) {
31
+ if (config?.root)
32
+ root = config.root;
33
+ },
34
+ transform(code, id) {
35
+ const clean = id.split("?")[0] ?? id;
36
+ if (!/\.(tsx|jsx)$/.test(clean))
37
+ return null;
38
+ if (defaultExcluded(clean))
39
+ return null;
40
+ if (exclude.some((p) => clean.includes(p)))
41
+ return null;
42
+ if (include.length > 0 && !include.some((p) => clean.includes(p))) {
43
+ return null;
44
+ }
45
+ const result = transformWithLayoutAttrs(code, clean, root, {
46
+ production: options.production,
47
+ });
48
+ // transformWithLayoutAttrs returns the input untouched with map:null
49
+ // when nothing changed — signal "no change" to Vite to keep its maps.
50
+ if (result.code === code && result.map === null)
51
+ return null;
52
+ return result;
53
+ },
54
+ };
55
+ }
56
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/plugins/vite/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAuB3D,SAAS,OAAO,CAAC,CAAgC;IAC/C,IAAI,CAAC,CAAC;QAAE,OAAO,EAAE,CAAC;IAClB,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,MAAM,CAC5B,UAAmC,EAAE;IAErC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,MAAM,eAAe,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC;IACpE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACzC,IAAI,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAEzB,OAAO;QACL,IAAI,EAAE,mCAAmC;QACzC,OAAO,EAAE,KAAK;QACd,KAAK,EAAE,OAAO;QACd,cAAc,CAAC,MAAM;YACnB,IAAI,MAAM,EAAE,IAAI;gBAAE,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACvC,CAAC;QACD,SAAS,CAAC,IAAI,EAAE,EAAE;YAChB,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YACrC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YAC7C,IAAI,eAAe,CAAC,KAAK,CAAC;gBAAE,OAAO,IAAI,CAAC;YACxC,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,IAAI,CAAC;YACxD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAClE,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,MAAM,GAAG,wBAAwB,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE;gBACzD,UAAU,EAAE,OAAO,CAAC,UAAU;aAC/B,CAAC,CAAC;YACH,qEAAqE;YACrE,sEAAsE;YACtE,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,GAAG,KAAK,IAAI;gBAAE,OAAO,IAAI,CAAC;YAC7D,OAAO,MAAM,CAAC;QAChB,CAAC;KACF,CAAC;AACJ,CAAC"}