Skip to content

Commit ca39007

Browse files
committed
feat: add comprehensive agent guides for extension, MCP server, shared contracts, and plugins
1 parent 513ea06 commit ca39007

File tree

7 files changed

+686
-0
lines changed

7 files changed

+686
-0
lines changed

AGENTS.md

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
# Tempad Dev — Agent Guide (Root)
2+
3+
## Purpose
4+
5+
Provide a single entry point for coding agents. This file links to package-level guides and highlights repo-wide constraints and workflows.
6+
7+
## Repo map (high level)
8+
9+
- `packages/extension/` — Figma plugin + MCP tools implementation
10+
- `packages/mcp-server/` — MCP server runtime
11+
- `packages/mcp-shared/` — shared types and contracts
12+
- `packages/plugins/` — plugin-side code and transforms
13+
14+
## Start here
15+
16+
- `packages/extension/AGENTS.md`
17+
- `packages/mcp-server/AGENTS.md`
18+
- `packages/mcp-shared/AGENTS.md`
19+
- `packages/plugins/AGENTS.md`
20+
21+
## Global conventions
22+
23+
- Package manager: `pnpm`
24+
- Prefer repo-level scripts unless a package explicitly documents otherwise.
25+
26+
## Common commands
27+
28+
- Typecheck: `pnpm typecheck`
29+
- Lint (and format): `pnpm lint:fix`
30+
31+
## Doc index
32+
33+
- `docs/extension/requirements.md`
34+
- `docs/extension/design.md`
35+
36+
## Guardrails
37+
38+
- Keep changes minimal and consistent with existing style.
39+
- Avoid adding new global dependencies unless explicitly requested or approved.
40+
41+
## Contributing & verification
42+
43+
### Tech stack (repo-wide)
44+
45+
- Package manager: `pnpm` (workspace scripts are commonly run as `pnpm -r ...`).
46+
- Language: TypeScript.
47+
- Extension: Vue 3 + WXT (Web Extension Toolkit).
48+
- MCP server: Node.js 18+ + `@modelcontextprotocol/sdk` + WebSocket transport.
49+
- Shared contracts: `zod` schemas.
50+
- Build tool (non-extension packages): `tsdown`.
51+
52+
### Key scripts
53+
54+
Run these at repo root unless noted.
55+
56+
- Dev extension: `pnpm dev`
57+
- Build everything: `pnpm build`
58+
- Build extension: `pnpm build:ext`
59+
- Build plugins: `pnpm build:plugins`
60+
- Build MCP: `pnpm build:mcp`
61+
- Typecheck all packages: `pnpm typecheck`
62+
- Lint all packages: `pnpm lint` / auto-fix: `pnpm lint:fix`
63+
- Format: `pnpm format`
64+
- Zip extension artifact: `pnpm zip`
65+
66+
### Verification checklist (agent-driven changes)
67+
68+
Pick the checks that match your change.
69+
70+
1. Always
71+
72+
- `pnpm typecheck`
73+
- `pnpm lint` (or `pnpm lint:fix`)
74+
75+
2. Extension UI / codegen
76+
77+
- `pnpm dev`
78+
- In Figma, open TemPad Dev panel and validate the impacted section (e.g. “Inspect → Code”).
79+
80+
3. Extension build / packaging
81+
82+
- `pnpm build:ext`
83+
- `pnpm zip`
84+
85+
4. Rewrite subsystem
86+
87+
- `pnpm --filter @tempad-dev/extension build:rewrite`
88+
- Optional: `pnpm --filter @tempad-dev/extension tsx scripts/check-rewrite.ts`
89+
- Requires `FIGMA_EMAIL`, `FIGMA_PASSWORD`, `FIGMA_FILE_KEY`.
90+
91+
5. MCP schemas / tool behavior
92+
93+
- If you change tool schemas/contracts: update `packages/mcp-shared` first, then `packages/mcp-server`, then `packages/extension`.
94+
- Re-check payload limits and omission rules; see `docs/extension/requirements.md` and `docs/extension/design.md`.

docs/extension/design.md

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
# MCP get_code - Design
2+
3+
This document describes the implementation design for MCP `get_code` in `packages/extension/mcp/tools/code`. It aligns with the requirements and reflects the current pipeline.
4+
5+
## High-level pipeline
6+
7+
1. **Validate selection**
8+
- Exactly one visible root node required.
9+
- Build a visible tree with depth capping.
10+
11+
2. **Collect data**
12+
- `collectNodeData()`
13+
- `getCSSAsync()` once per node.
14+
- `getStyledTextSegments()` for text nodes.
15+
- Preprocess styles (clean background, expand shorthands, merge inferred layout, infer resizing, apply overflow).
16+
- Apply positioning (auto layout absolute, constraints).
17+
- Replace image fills with uploaded assets.
18+
19+
3. **Normalize variables**
20+
- Normalize variable names and codeSyntax to a canonical form.
21+
- Capture variable usage candidates for token detection.
22+
23+
4. **Asset planning and export**
24+
- Plan vector/image export at the tree level.
25+
- Export SVGs/images only once.
26+
27+
5. **Sanitize styles**
28+
- Patch known layout issues (negative gap).
29+
- Ensure layout parents are `position: relative` when children are absolute.
30+
31+
6. **Build layout-only styles**
32+
- Extract layout-related CSS into a secondary map for SVG external layout.
33+
34+
7. **Render markup**
35+
- Render nodes into JSX/HTML component tree.
36+
- Inject SVG content or `<img>` when applicable.
37+
- Apply Tailwind class conversion.
38+
39+
8. **Token pipeline**
40+
- Detect token references in output code.
41+
- Apply plugin transforms to token names.
42+
- Rewrite code with transformed token names.
43+
- Resolve tokens to values when requested.
44+
45+
9. **Truncate and finalize output**
46+
- Enforce payload size limits.
47+
- Emit warnings only for truncation or inferred auto layout.
48+
49+
## Tree and layout semantics
50+
51+
### Visible tree
52+
53+
- Built via `buildVisibleTree`.
54+
- Nodes include bounds, data-hints, and inferred layout hints.
55+
- GROUP/BOOLEAN nodes are preserved for structure but ignored for layout-parent calculations.
56+
57+
### Layout parent resolution
58+
59+
- `getLayoutParent` walks up to the nearest non-GROUP/BOOLEAN ancestor.
60+
- All relative transforms and constraints are interpreted against this layout parent.
61+
62+
### Positioning rules
63+
64+
- **Explicit auto layout (layoutMode)**
65+
- Children with `layoutPositioning === 'ABSOLUTE'` use absolute positioning.
66+
- Other children stay in flow.
67+
- **Inferred auto layout**
68+
- Can emit flex/padding/gap (hinted), but is non-authoritative.
69+
- Constraint-based positioning is skipped under inferred layout.
70+
- **No layout**
71+
- Constraint-based absolute positioning is applied to children.
72+
73+
### Relative container injection
74+
75+
- A layout parent is made `position: relative` if any descendant is absolute.
76+
- GROUP/BOOLEAN nodes are not made relative/absolute.
77+
78+
## Styles pipeline
79+
80+
### Preprocess (per node)
81+
82+
- `cleanFigmaSpecificStyles`:
83+
- Fix background quirks and inject fills when absent.
84+
- `expandShorthands`:
85+
- Break down padding/margin/inset shorthands.
86+
- `mergeInferredAutoLayout`:
87+
- Inject inferred flex/padding/gap where applicable.
88+
- `inferResizingStyles`:
89+
- Translate Figma layout sizing into `align-self` and size deletions.
90+
- `applyOverflowStyles`:
91+
- Add overflow rules based on clips/scroll.
92+
93+
### Sanitize (tree-level)
94+
95+
- `patchNegativeGapStyles`
96+
- `ensureRelativeForAbsoluteChildren`
97+
98+
### Layout-only extraction
99+
100+
- Builds layout-only style map for SVG containers.
101+
- SVG roots remove width/height from layout map (SVG has own size).
102+
103+
## SVG and asset strategy
104+
105+
- Vector-like nodes may be exported to SVG.
106+
- Vector containers can be converted to a single SVG if all leaves are vector-like.
107+
- SVG nodes only receive external layout styles, not visual paint styles.
108+
- Placeholder SVG is emitted when export fails or is unavailable, using node width/height.
109+
110+
## Token pipeline (detailed)
111+
112+
1. Build source index from variable IDs and codeSyntax.
113+
2. Extract raw token names from code (boundary-aware).
114+
3. Apply plugin transforms to names.
115+
4. Rewrite code with transformed names.
116+
5. Extract final used names from code.
117+
6. Build used token metadata and (optionally) resolved values.
118+
119+
## Error handling
120+
121+
- Fatal: invalid selection, no renderable root, failure to build markup.
122+
- Non-fatal: CSS collection failure, text segment failures, export failure.
123+
- Warnings (output field): only truncation and inferred auto layout presence.
124+
125+
## Performance notes
126+
127+
- Single-pass CSS collection per node.
128+
- Asset export is planned and executed once.
129+
- Token detection is string-based and bounded by truncation.

docs/extension/requirements.md

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# MCP get_code - Requirements
2+
3+
This document records the source requirements and hard constraints for the MCP `get_code` tool in `packages/extension/mcp/tools/code`.
4+
5+
## Non-negotiables
6+
7+
- Accept exactly one visible node; otherwise throw a user-facing error.
8+
- Never emit empty optional fields (`assets`, `tokens`, `warnings`).
9+
- Do not use `renderBounds` diffs for positioning.
10+
- Do not inject positioning containers on GROUP/BOOLEAN nodes.
11+
- Keep `getCSSAsync()` at most once per node.
12+
13+
## Scope
14+
15+
- Applies to MCP `get_code` only (not the UI codegen pipeline).
16+
- Output is markup + Tailwind classes + optional assets/tokens metadata.
17+
18+
## Input constraints
19+
20+
- Exactly one node is required.
21+
- The node must be visible.
22+
- Tree traversal is capped by a depth limit (semantic-tree driven). If capped, log a warning.
23+
24+
## Output contract (GetCodeResult)
25+
26+
- Required fields:
27+
- `lang`: resolved language for output markup.
28+
- `code`: string markup.
29+
- `codegen`: `{ plugin: string, config: CodegenConfig }`.
30+
- Optional fields (omit when empty):
31+
- `assets`: array of exported assets (image/vector).
32+
- `tokens`: `{ used?: Record<string, TokenInfo>, resolved?: Record<string, string> }`.
33+
- `warnings`: only for truncation or inferred auto layout.
34+
35+
## Size and truncation
36+
37+
- Total payload is constrained by `MCP_MAX_PAYLOAD_BYTES`.
38+
- The `code` field is limited to ~60% of that cap.
39+
- If truncated, add a warning and truncate the code string only.
40+
41+
## Layout and positioning
42+
43+
### Layout parent
44+
45+
Figma `relativeTransform` is relative to the container parent, not to a GROUP/BOOLEAN parent. The layout parent is the nearest ancestor that is not `GROUP` or `BOOLEAN_OPERATION`.
46+
47+
### Positioning rules
48+
49+
- If parent has explicit `layoutMode` (auto layout):
50+
- Children with `layoutPositioning === 'ABSOLUTE'` use absolute positioning.
51+
- Other children stay in flow (flex layout).
52+
- If parent has inferred auto layout:
53+
- Treat it as a layout parent (see “Inferred auto layout”).
54+
- Do not apply constraint-based absolute positioning for its children.
55+
- If parent has no auto layout:
56+
- Compute absolute positioning from `constraints` + `relativeTransform`.
57+
58+
### Group/boolean
59+
60+
- GROUP and BOOLEAN_OPERATION nodes are kept in the tree for structure and hints.
61+
- They must not become positioning containers (`position: absolute/relative` is not injected there).
62+
63+
### Relative containers for absolute children
64+
65+
- When any node is absolutely positioned, the layout parent is ensured to be `position: relative`.
66+
- Do not add `left/top` to the container during this step.
67+
68+
### Constraint calculation
69+
70+
- Use `relativeTransform` translation plus node/parent sizes to compute `left/top/right/bottom`.
71+
- Respect constraints (`MIN|MAX|CENTER|STRETCH|SCALE`).
72+
- If no constraints exist, fall back to `left/top`.
73+
- All numeric outputs are rounded to at most 3 decimals.
74+
75+
## Inferred auto layout
76+
77+
- Inferred auto layout may emit flex/gap/padding CSS for readability, but it is not authoritative.
78+
- Inferred layouts are flagged with `data-hint-auto-layout="inferred"` for downstream interpretation.
79+
- Children under inferred layout must not be constraint-positioned, unless `layoutPositioning === 'ABSOLUTE'`.
80+
81+
## SVG and assets
82+
83+
- Vector assets are exported as SVG when a node (or container) is classified as vector-only.
84+
- Images are exported as PNG/JPEG when the node is an image fill.
85+
- SVG must contain its own visual styles; no external fill/bg classes.
86+
- SVG layout is governed by external positioning only.
87+
- SVG size comes from node size (rounded), not export metadata.
88+
- When vector export fails or assets are unavailable, preserve layout using a placeholder SVG with node size.
89+
- Omit `assets` when empty.
90+
91+
## Token handling
92+
93+
- Token detection is based on the final emitted markup (after plugin transform and token rewrites).
94+
- Variable names are normalized consistently across Figma variable names, `codeSyntax`, and plugin transforms.
95+
- `usedTokens` represent tokens referenced by the final code.
96+
- `resolvedTokens` are only emitted when `resolveTokens` is requested.
97+
- Omit `tokens` when both `used` and `resolved` are empty.
98+
99+
## Text
100+
101+
- Use `getStyledTextSegments` where available; failures are logged (not fatal).
102+
- Use fill data when Figma CSS omits visible text paints.
103+
104+
## Logging
105+
106+
- Only emit `warnings` for truncation and inferred auto layout.
107+
- Other degradations should be logged to console with `[tempad-dev]` prefix.
108+
109+
## Performance
110+
111+
- `getCSSAsync` must be called at most once per node.
112+
- `getStyledTextSegments` only for text nodes.
113+
- Avoid repeated vector export calls; plan and export once per tree.

0 commit comments

Comments
 (0)