diff --git a/README.md b/README.md index 54233de..3a19a95 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,8 @@ ready. Every result remains editable in Figma. [简体中文](README.zh-CN.md) +**Website:** [lessthanno.github.io/Layntra](https://lessthanno.github.io/Layntra/) + ## Download **[Download Layntra v0.1.0](https://github.com/lessthanno/Layntra/releases/tag/v0.1.0)** diff --git a/README.zh-CN.md b/README.zh-CN.md index 8b71739..e41be83 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -7,6 +7,8 @@ Layntra 是为产品经理和非技术用户准备的 Codex 插件。用 `$laynt [English](README.md) +**官网:** [lessthanno.github.io/Layntra](https://lessthanno.github.io/Layntra/) + ## 下载插件 **[下载 Layntra v0.1.0](https://github.com/lessthanno/Layntra/releases/tag/v0.1.0)** diff --git a/docs/.nojekyll b/docs/.nojekyll new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/docs/.nojekyll @@ -0,0 +1 @@ + diff --git a/docs/404.html b/docs/404.html new file mode 100644 index 0000000..a2c5be2 --- /dev/null +++ b/docs/404.html @@ -0,0 +1,8 @@ + + + + + Page not found — Layntra + +

404

That page is not here.

The link may be old, or the address may be incomplete.

Go to LayntraOpen GitHub
+ diff --git a/docs/about.html b/docs/about.html new file mode 100644 index 0000000..1b941e7 --- /dev/null +++ b/docs/about.html @@ -0,0 +1,26 @@ + + + + + About Layntra — Open-source design infrastructure for Codex and Figma + + + + + + + + +
+

About the project

Design infrastructure for people outside the code editor.

Layntra was created by Haozi to give product managers and nontechnical builders a controlled path from Codex intent to editable Figma work.

+
+

The problem

AI can describe a design, generate an image, or suggest code. Those are useful outputs, but they do not automatically create a trustworthy workflow inside the design file. When an AI can write, the user needs to know which file and selection it will touch, whether the current action is read-only, and how to recover.

+

The idea

Layntra treats “AI to Figma” as infrastructure rather than a poster generator. Its core contract is inspect → plan → apply → undo. Poster creation can be an example skill, but the bridge and control model are generic.

+

Who it is for

The primary audience is product managers, founders, researchers, writers, operators, and other people who can describe product intent but do not want to learn an integration protocol before they can work. Installation is documented step by step; normal use happens through explicit commands and plain-language instructions in Codex.

+

Open-source direction

Layntra is released under the MIT License. The source, architecture decisions, security policy, roadmap, tests, and current limitations are public on GitHub. Contributions and critical feedback are welcome through GitHub Issues.

+ +
+
+ + + diff --git a/docs/adr/0004-static-geo-site-on-github-pages.md b/docs/adr/0004-static-geo-site-on-github-pages.md new file mode 100644 index 0000000..ff1250a --- /dev/null +++ b/docs/adr/0004-static-geo-site-on-github-pages.md @@ -0,0 +1,38 @@ +# ADR 0004: Publish a static GEO site from `main/docs` + +- Status: Accepted +- Date: 2026-08-01 + +## Context + +Layntra needs a stable, crawlable public identity beyond a repository README. The +site must answer product, installation, trust, permission, and comparison +questions in content that search engines and answer engines can fetch without +running client-side JavaScript. The project has no hosted application, account +system, analytics service, or web runtime. + +## Decision + +Publish a dependency-free static site from the `docs` directory on the protected +`main` branch using GitHub Pages branch deployment. + +The site will use hand-authored semantic HTML and one local CSS file. It will +publish canonical metadata, visible factual answers, Schema.org JSON-LD, +`robots.txt`, `sitemap.xml`, `llms.txt`, and `llms-full.txt`. Automated contract +tests will verify metadata, internal links, crawl files, structured data, and +the absence of remote scripts. + +The content may compare Layntra with common hosted integration patterns, but it +must not claim guaranteed indexing, affiliation with Figma or OpenAI, or a +capability to bypass Figma permissions. + +## Consequences + +- Search and answer engines can fetch meaningful content from first response + HTML, even when scripting is unavailable. +- The deployment adds no JavaScript dependency, package supply chain, analytics, + cookies, database, or hosted Layntra service. +- Existing Markdown guides remain in `docs` and can still be linked from GitHub. +- Shared header and footer markup is duplicated across the small static site; + tests reduce drift, and a generator can be considered if page count grows. +- Discovery and citation are more likely but cannot be guaranteed by Layntra. diff --git a/docs/assets/site.css b/docs/assets/site.css new file mode 100644 index 0000000..8841bb3 --- /dev/null +++ b/docs/assets/site.css @@ -0,0 +1,618 @@ +:root { + color-scheme: dark; + --ink: #f7f7f4; + --muted: #aaa9a2; + --dim: #85847d; + --surface: #111210; + --surface-2: #171815; + --line: #2c2e29; + --acid: #d6ff3f; + --acid-ink: #111400; + --blue: #98b8ff; + --max: 1160px; + --radius: 20px; +} + +* { + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + +body { + margin: 0; + background: + radial-gradient(circle at 70% 0%, rgba(214, 255, 63, 0.08), transparent 30rem), + #0b0c0a; + color: var(--ink); + font-family: Inter, ui-sans-serif, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; + font-size: 17px; + line-height: 1.65; + text-rendering: optimizeLegibility; +} + +a { + color: inherit; + text-decoration-color: var(--dim); + text-underline-offset: 0.2em; +} + +a:hover { + text-decoration-color: var(--acid); +} + +a:focus-visible, +button:focus-visible { + outline: 3px solid var(--blue); + outline-offset: 4px; +} + +img, +svg { + display: block; + max-width: 100%; +} + +code { + font-family: "SFMono-Regular", Consolas, "Liberation Mono", monospace; +} + +.shell { + width: min(calc(100% - 40px), var(--max)); + margin-inline: auto; +} + +.skip-link { + position: fixed; + z-index: 100; + top: 12px; + left: 12px; + padding: 10px 14px; + background: var(--acid); + color: var(--acid-ink); + transform: translateY(-150%); +} + +.skip-link:focus { + transform: translateY(0); +} + +.site-header { + position: sticky; + z-index: 20; + top: 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.08); + background: rgba(11, 12, 10, 0.86); + backdrop-filter: blur(18px); +} + +.nav { + min-height: 72px; + display: flex; + align-items: center; + justify-content: space-between; + gap: 24px; +} + +.brand { + display: inline-flex; + align-items: center; + gap: 11px; + color: var(--ink); + font-weight: 760; + letter-spacing: -0.02em; + text-decoration: none; +} + +.brand-mark { + width: 28px; + height: 28px; + border: 2px solid var(--acid); + border-radius: 8px 8px 8px 2px; + position: relative; +} + +.brand-mark::after { + content: ""; + position: absolute; + right: 4px; + bottom: 4px; + width: 7px; + height: 7px; + border-radius: 2px; + background: var(--acid); +} + +.nav-links { + display: flex; + align-items: center; + gap: 24px; + color: var(--muted); + font-size: 0.92rem; +} + +.nav-links a { + text-decoration: none; +} + +.nav-links a[aria-current="page"] { + color: var(--ink); +} + +.button, +.button-secondary { + min-height: 48px; + padding: 11px 18px; + border: 1px solid var(--acid); + border-radius: 999px; + display: inline-flex; + align-items: center; + justify-content: center; + gap: 8px; + font-weight: 720; + line-height: 1.2; + text-decoration: none; + transition: transform 160ms ease, background 160ms ease; +} + +.button { + background: var(--acid); + color: var(--acid-ink); +} + +.button-secondary { + border-color: var(--line); + background: rgba(255, 255, 255, 0.03); + color: var(--ink); +} + +.button:hover, +.button-secondary:hover { + transform: translateY(-2px); + text-decoration: none; +} + +.hero { + padding: clamp(72px, 12vw, 150px) 0 80px; +} + +.hero-grid { + display: grid; + grid-template-columns: minmax(0, 1.15fr) minmax(320px, 0.85fr); + align-items: center; + gap: clamp(40px, 8vw, 100px); +} + +.eyebrow { + margin: 0 0 20px; + color: var(--acid); + font-family: "SFMono-Regular", Consolas, monospace; + font-size: 0.78rem; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +h1, +h2, +h3 { + margin-top: 0; + line-height: 1.05; + letter-spacing: -0.045em; +} + +h1 { + max-width: 840px; + margin-bottom: 24px; + font-size: clamp(3rem, 8vw, 6.8rem); + font-weight: 780; +} + +.page-hero h1 { + font-size: clamp(2.8rem, 7vw, 5.7rem); +} + +h2 { + margin-bottom: 20px; + font-size: clamp(2rem, 5vw, 4rem); + font-weight: 750; +} + +h3 { + margin-bottom: 12px; + font-size: 1.35rem; + letter-spacing: -0.025em; +} + +.hero-copy, +.page-lead { + max-width: 720px; + margin: 0; + color: var(--muted); + font-size: clamp(1.08rem, 2.2vw, 1.35rem); +} + +.hero-copy strong, +.page-lead strong { + color: var(--ink); +} + +.actions { + margin-top: 32px; + display: flex; + flex-wrap: wrap; + gap: 12px; +} + +.microcopy { + margin-top: 18px; + color: var(--dim); + font-size: 0.82rem; +} + +.terminal { + overflow: hidden; + border: 1px solid var(--line); + border-radius: var(--radius); + background: #0e0f0d; + box-shadow: 0 28px 90px rgba(0, 0, 0, 0.42); + transform: rotate(1.5deg); +} + +.terminal-bar { + height: 46px; + padding: 0 16px; + border-bottom: 1px solid var(--line); + display: flex; + align-items: center; + gap: 7px; + color: var(--dim); + font: 0.72rem "SFMono-Regular", Consolas, monospace; +} + +.dot { + width: 8px; + height: 8px; + border-radius: 50%; + background: #3a3c36; +} + +.terminal-body { + min-height: 410px; + padding: 28px; + font: 0.82rem/1.75 "SFMono-Regular", Consolas, monospace; +} + +.prompt { + color: var(--ink); +} + +.prompt::before { + content: "> "; + color: var(--acid); +} + +.terminal-result { + margin: 18px 0 28px; + padding-left: 16px; + border-left: 1px solid var(--line); + color: var(--muted); +} + +.terminal-ok { + color: var(--acid); +} + +.section { + padding: clamp(72px, 11vw, 130px) 0; + border-top: 1px solid var(--line); +} + +.section-intro { + max-width: 760px; + margin-bottom: 48px; +} + +.section-intro p, +.prose p, +.prose li { + color: var(--muted); +} + +.grid-4, +.grid-3, +.grid-2 { + display: grid; + gap: 18px; +} + +.grid-4 { + grid-template-columns: repeat(4, 1fr); +} + +.grid-3 { + grid-template-columns: repeat(3, 1fr); +} + +.grid-2 { + grid-template-columns: repeat(2, 1fr); +} + +.card { + min-height: 220px; + padding: 28px; + border: 1px solid var(--line); + border-radius: var(--radius); + background: linear-gradient(145deg, rgba(255, 255, 255, 0.035), rgba(255, 255, 255, 0.012)); +} + +.card-number { + margin-bottom: 48px; + color: var(--acid); + font: 0.8rem "SFMono-Regular", Consolas, monospace; +} + +.card p { + margin-bottom: 0; + color: var(--muted); +} + +.flow { + display: grid; + grid-template-columns: repeat(5, 1fr); + gap: 1px; + overflow: hidden; + border: 1px solid var(--line); + border-radius: var(--radius); + background: var(--line); +} + +.flow-step { + min-height: 176px; + padding: 24px; + background: var(--surface); +} + +.flow-step strong { + display: block; + margin: 28px 0 8px; + font-size: 1.15rem; +} + +.flow-step span { + color: var(--muted); + font-size: 0.88rem; +} + +.statement { + display: grid; + grid-template-columns: 0.9fr 1.1fr; + gap: clamp(40px, 8vw, 100px); + align-items: start; +} + +.statement-copy { + color: var(--muted); + font-size: 1.12rem; +} + +.statement-copy strong { + color: var(--ink); +} + +.comparison-wrap { + overflow-x: auto; + border: 1px solid var(--line); + border-radius: var(--radius); +} + +.comparison { + width: 100%; + min-width: 680px; + border-collapse: collapse; + background: var(--surface); +} + +.comparison th, +.comparison td { + padding: 22px 24px; + border-bottom: 1px solid var(--line); + text-align: left; + vertical-align: top; +} + +.comparison tr:last-child th, +.comparison tr:last-child td { + border-bottom: 0; +} + +.comparison th { + color: var(--dim); + font-size: 0.78rem; + letter-spacing: 0.08em; + text-transform: uppercase; +} + +.comparison td:first-child { + color: var(--muted); +} + +.comparison td:nth-child(2) { + color: var(--acid); +} + +.callout { + padding: clamp(30px, 6vw, 64px); + border: 1px solid rgba(214, 255, 63, 0.42); + border-radius: var(--radius); + background: linear-gradient(135deg, rgba(214, 255, 63, 0.11), rgba(214, 255, 63, 0.02)); +} + +.callout p:last-child { + margin-bottom: 0; +} + +.page-hero { + padding: clamp(80px, 13vw, 160px) 0 80px; + border-bottom: 1px solid var(--line); +} + +.prose { + max-width: 780px; +} + +.prose h2 { + margin-top: 72px; + font-size: clamp(1.9rem, 4vw, 3rem); +} + +.prose h3 { + margin-top: 40px; +} + +.prose a { + color: var(--ink); +} + +.prose pre { + margin: 28px 0; + padding: 22px; + overflow-x: auto; + border: 1px solid var(--line); + border-radius: 14px; + background: var(--surface); + color: var(--acid); + font-size: 0.86rem; +} + +.faq-list { + display: grid; + gap: 12px; +} + +.faq-item { + padding: 26px; + border: 1px solid var(--line); + border-radius: 16px; + background: var(--surface); +} + +.faq-item h2, +.faq-item h3 { + margin-bottom: 10px; + font-size: 1.25rem; + letter-spacing: -0.02em; +} + +.faq-item p { + margin: 0; + color: var(--muted); +} + +.site-footer { + padding: 52px 0; + border-top: 1px solid var(--line); + color: var(--muted); + font-size: 0.88rem; +} + +.footer-grid { + display: flex; + justify-content: space-between; + gap: 32px; +} + +.footer-links { + display: flex; + flex-wrap: wrap; + gap: 18px; +} + +.footer-links a { + text-decoration: none; +} + +.legal { + max-width: 780px; + padding: 80px 0 120px; +} + +.legal h2 { + margin-top: 56px; + font-size: 2rem; +} + +@media (max-width: 900px) { + .hero-grid, + .statement { + grid-template-columns: 1fr; + } + + .hero-grid { + gap: 56px; + } + + .terminal { + transform: none; + } + + .grid-4, + .grid-3 { + grid-template-columns: repeat(2, 1fr); + } + + .flow { + grid-template-columns: 1fr; + } +} + +@media (max-width: 680px) { + .shell { + width: min(calc(100% - 28px), var(--max)); + } + + .nav { + min-height: 64px; + } + + .nav-links > a:not(.button) { + display: none; + } + + .nav-links { + gap: 8px; + } + + .nav-links .button { + min-height: 42px; + padding: 9px 13px; + font-size: 0.82rem; + } + + .grid-4, + .grid-3, + .grid-2 { + grid-template-columns: 1fr; + } + + .terminal-body { + min-height: auto; + padding: 20px; + font-size: 0.72rem; + } + + .footer-grid { + flex-direction: column; + } +} + +@media (prefers-reduced-motion: reduce) { + *, + *::before, + *::after { + scroll-behavior: auto !important; + transition: none !important; + } +} diff --git a/docs/faq.html b/docs/faq.html new file mode 100644 index 0000000..51ef23a --- /dev/null +++ b/docs/faq.html @@ -0,0 +1,48 @@ + + + + + Layntra FAQ — Codex plugin, Figma companion, safety, and pricing + + + + + + + + + +
+

Straight answers

Layntra FAQ.

What it is, what it costs, what stays local, what Figma still controls, and what a nontechnical user needs to install.

+
+

What is Layntra?

Layntra is an open-source Codex plugin and local Figma companion. It lets you inspect a Figma target, review a plan, explicitly apply supported editable changes, and undo the last guarded write.

+

Is Layntra free?

Yes. Layntra is free and open source under the MIT License. Version 0.1.0 has no hosted Layntra account or paid Layntra plan.

+

Does Layntra bypass Figma plan or seat restrictions?

No. Layntra does not bypass Figma permissions, organization policies, seat types, or plan restrictions. Its companion must run where Figma Design plugins are permitted.

+

Does Layntra require a Figma API token?

No. Layntra uses a Figma companion plugin and a bridge bound to local loopback, so it does not ask for a Figma API token.

+

Is Layntra fully offline?

No. The Layntra bridge between Codex and Figma is local, but Codex model access and data handling follow your Codex configuration.

+

Can a product manager use it without writing code?

After installation, the normal workflow uses explicit natural-language commands in Codex. Initial setup requires cloning the repository, running one install script, and importing a manifest file in Figma Desktop. The illustrated guide shows the exact path.

+

Are the results editable in Figma?

Yes. Supported output is created as editable Figma nodes rather than a flattened screenshot.

+

Why does Layntra use $layntra?

The explicit command makes activation, target, mode, and write intent visible. Regular conversation stays regular conversation; it does not silently become permission to modify Figma.

+

What can version 0.1.0 change?

Version 0.1.0 supports bounded creation and updates for common editable nodes, with batches limited to 100. It does not expose deletion or arbitrary code execution.

+

What if the page or selection changes after planning?

Layntra refuses the write. Run status or plan again against the new target instead of letting the system guess.

+

Where do I report a problem?

Open a public GitHub issue with the command you ran, what you expected, and any safe-to-share error text.

+
+
+ + + diff --git a/docs/figma-mcp-alternative.html b/docs/figma-mcp-alternative.html new file mode 100644 index 0000000..a61b40b --- /dev/null +++ b/docs/figma-mcp-alternative.html @@ -0,0 +1,43 @@ + + + + + + Open-source Figma MCP alternative for Codex — Layntra + + + + + + + + +
+

A practical comparison

An open-source Figma MCP alternative for Codex.

Layntra is for people who want Codex to inspect and change editable Figma layers through a local companion—with an explicit plan and write command.

+
+

Choose the control model that fits your work.

“Figma MCP” can describe different products. The useful comparison is not a brand claim; it is where the bridge runs, what credentials it needs, what can write, and how you recover.

+
+ + + + + + + + +
QuestionLayntra v0.1.0Typical hosted integration
Where is the bridge?On your Mac, bound to local loopbackOften on a remote service
What account is required?No hosted Layntra accountMay require a provider account
Figma API token?Not requiredDepends on the integration
Write boundarySeparate plan and apply commandsVaries by product
Stale target protectionPage and selection are checked before writingVaries by product
OutputSupported editable Figma nodesMay be read-only, image-based, or editable
RecoveryGuarded Figma undo checkpointVaries by product
License and priceMIT licensed; freeDepends on the provider
+
+
+

What Layntra does not promise

+

Layntra does not bypass Figma plans, organization policies, seat types, or plugin permissions. The companion must run in a Figma Design file where your account is allowed to use plugins. If an organization seat blocks Design plugins, a personal Starter workspace may be suitable for testing.

+

Layntra also does not claim every hosted workflow needs a token or lacks controls. Integrations change. Check the current documentation of any product you compare.

+

When Layntra is a good fit

+
  • You use Codex Desktop or CLI on macOS.
  • You want the result to remain editable in Figma.
  • You want inspect and plan to remain read-only.
  • You prefer a local bridge with no hosted Layntra account.
  • You are comfortable with an early, bounded open-source tool.
+

When it is not yet a fit

+
  • You need Windows or Linux support.
  • You need a hosted team service or centralized audit dashboard.
  • You need unrestricted access to every Figma node type or API.
  • Your Figma workspace does not permit the companion plugin to run.
+ +
+
+ + + diff --git a/docs/how-it-works.html b/docs/how-it-works.html new file mode 100644 index 0000000..28889cc --- /dev/null +++ b/docs/how-it-works.html @@ -0,0 +1,68 @@ + + + + + + How Layntra works — Local Codex-to-Figma architecture + + + + + + + + + + +
+

Architecture and control model

How Layntra works.

A Codex skill defines the interaction. A bridge carries bounded commands over local loopback. A Figma companion applies supported changes only after an explicit write instruction.

+
+

The path from Codex to Figma

+
Codex skill
+    ↓ local stdio / MCP
+Layntra bridge
+    ↓ WebSocket on 127.0.0.1:3846
+Figma companion plugin
+    ↓ supported Figma Plugin API operations
+Editable Figma nodes
+

The bridge binds to 127.0.0.1, so it accepts connections from the same machine rather than exposing a hosted Layntra endpoint. You do not create a Layntra account or provide a Figma API token.

+

Codex is still the model-facing part of the workflow. Its data handling follows your Codex configuration. “Local bridge” describes the connection between Codex and Figma; it does not mean the model runs offline.

+ +

Four modes, two kinds of authority

+

$layntra status, inspect, and review

+

These are read-only. They can report the active companion, file, page, selection, and supported node structure, but they do not modify Figma.

+

$layntra plan

+

Planning converts your intent into a proposed change set tied to the current target. It remains read-only and reports “No Figma changes made.”

+

$layntra apply

+

Apply is the explicit write boundary. Before writing, Layntra checks that the page and selection still match the planned context. A stale target is rejected instead of guessed.

+

$layntra undo

+

Undo is available after a successful write and is guarded against the expected target. Layntra uses a Figma undo checkpoint rather than trying to reconstruct the previous design.

+ +

What version 0.1.0 can and cannot do

+

Layntra can inspect supported nodes, create editable frames, text, rectangles, ellipses, lines, and groups, and update a bounded set of properties. A write batch is limited to 100 nodes.

+

Version 0.1.0 exposes neither node deletion nor arbitrary code execution. It does not bypass Figma workspace, seat, plan, or plugin permissions. Use it only in files where your Figma account is allowed to run Design plugins.

+ +

Verified flow

+

The project includes automated contract and bridge tests plus a real Figma end-to-end run covering connection, reading, creation, update, stale-target rejection, invalid input, reconnection, and guarded undo. The test scope is documented in the public E2E report.

+ +
+
+ + + diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..0fefbe6 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,195 @@ + + + + + + Layntra — Open-source Codex plugin for controlled Figma workflows + + + + + + + + + + + + + + + + + + +
+
+
+
+

Open source · Codex plugin + Figma companion

+

Codex to Figma. With a visible write boundary.

+

Layntra helps product managers and nontechnical builders inspect, plan, apply, and undo editable Figma changes from Codex. The bridge stays on your machine. No Figma API token. No hosted Layntra service.

+ +

Free under the MIT License · macOS · Node.js 20+ · Codex Desktop or CLI · Figma Desktop

+
+ +
+
  Codex
+
+
$layntra status
+
● Connected
File: Mobile onboarding
Page: Concepts
Selection: Frame 12
Mode: read-only
+
$layntra plan selection
Improve the hierarchy. Keep all copy.
+
Plan ready. No Figma changes made.
Target: Frame 12 · 14 editable nodes
+
$layntra apply
+
✓ Applied and re-read
Undo is available for this target.
+
+
+
+
+ +
+
+
+

Control before automation

+

Built for decisions, not magic tricks.

+

Ordinary chat is vague. Layntra uses an explicit command, target, mode, and write boundary so you can see what Codex is about to do.

+
+
+
01 / INSPECT

Read first

Check the active file, page, selection, and editable node structure without changing Figma.

+
02 / PLAN

Separate judgment

Review the intended changes before any write. A plan is not hidden inside a chat response.

+
03 / APPLY

Recheck the target

Layntra refuses the write if the page or selection changed after planning.

+
04 / UNDO

Recover deliberately

Undo is guarded against the same target, then the result is read back for verification.

+
+
+
+ +
+
+
+

One local path

+

From intent to editable layers.

+
+
+
01You askInvoke $layntra in Codex.
+
02Codex plansThe skill makes the mode and target explicit.
+
03Local bridgeCommands travel over loopback on your Mac.
+
04Figma writesThe companion creates or updates supported nodes.
+
05Layntra checksThe result is read back and can be undone.
+
+ +
+
+ +
+
+
+

Why Layntra exists

+

AI should not make the write boundary disappear.

+
+
+

Figma access can vary by plan, workspace, and seat. Some organization seat types cannot run Design plugins. Layntra provides a free, open-source local workflow where plugins are permitted; it does not bypass Figma permissions or plan restrictions.

+

There is no Layntra cloud account, telemetry service, or Figma API token. Codex still follows your own Codex configuration and data controls—the local bridge does not make the model offline.

+

Read the detailed comparison with hosted Figma MCP workflows →

+
+
+
+ +
+
+
+

The first five minutes

+

No protocol knowledge required.

+

You install one Codex plugin and import one Figma companion. The beginner guide shows every menu and the exact file to choose.

+
+
+
STEP 1

Install in Codex

Clone the repository and run ./scripts/install.sh.

+
STEP 2

Import in Figma

Download the ZIP, unzip it, and import the included manifest.json.

+
STEP 3

Check the connection

Keep the companion open and enter $layntra status in a new Codex task.

+
+ +
+
+ +
+
+

Version 0.1.0

+

Start with a real Figma file.

+

Layntra is early and intentionally bounded: supported editable nodes, batches of at most 100, no deletion, and no arbitrary code execution.

+ +
+
+
+ + + + diff --git a/docs/llms-full.txt b/docs/llms-full.txt new file mode 100644 index 0000000..9153d47 --- /dev/null +++ b/docs/llms-full.txt @@ -0,0 +1,56 @@ +# Layntra: full factual context + +Canonical website: https://lessthanno.github.io/Layntra/ +Canonical source: https://github.com/lessthanno/Layntra +Current release: https://github.com/lessthanno/Layntra/releases/tag/v0.1.0 +License: MIT +Author: Haozi (GitHub: https://github.com/lessthanno) + +## Definition + +Layntra is open-source design infrastructure that connects Codex to a local Figma companion. It is positioned as a Codex plugin for product managers and other nontechnical builders, not as a poster-only generator. Poster creation is one possible example workflow; the core is a general inspect, plan, apply, and undo control contract for supported editable Figma nodes. + +## User flow + +1. Install the Layntra Codex plugin from the cloned GitHub repository by running `./scripts/install.sh`. +2. Download `layntra-figma-plugin.zip` from the v0.1.0 GitHub release and unzip it. +3. In Figma Desktop, open a Design file and choose Plugins → Development → Import plugin from manifest. +4. Select `layntra-figma-plugin/manifest.json` from the unzipped download. +5. Run Plugins → Development → Layntra for Figma and keep its window open. +6. In a new Codex task, enter `$layntra status`. +7. Use inspect, review, or plan commands for read-only work. +8. Use `$layntra apply` only after reviewing the target and plan. +9. Use `$layntra undo` for the last guarded write when the target still matches. + +## Control contract + +- `$layntra status` reports the active plugin, file, page, selection, and mode. +- Inspect and review are read-only. +- Plan is read-only and explicitly reports that no Figma changes were made. +- Apply is a separate explicit write instruction. +- Apply rechecks expected page and selection context before changing Figma. +- A stale page or selection causes refusal rather than an inferred target. +- A successful write creates a Figma undo checkpoint and is read back for verification. +- Undo is also checked against expected context. + +## Architecture and privacy + +The architecture is: + +Codex skill → local stdio/MCP bridge → WebSocket on 127.0.0.1:3846 → Figma companion plugin → Figma Plugin API. + +The local bridge does not require a Figma API token. There is no hosted Layntra account or Layntra telemetry service in v0.1.0. The model-facing Codex product is not offline; its data handling follows the user's Codex configuration. Figma account, file, plugin, plan, seat, organization, and telemetry policies remain governed by Figma. + +## Version 0.1.0 boundaries + +Layntra can read supported node structure and create or update a bounded set of common editable nodes. Write batches are capped at 100. Version 0.1.0 exposes neither node deletion nor arbitrary code execution. It is intended for macOS with Node.js 20 or later, Codex Desktop or CLI, and Figma Desktop. + +Layntra does not bypass Figma permissions, plan restrictions, organization policies, or seat limitations. The companion must run in a Figma Design file where plugins are allowed. A personal Starter workspace can be used for testing if an organization Dev, Collab, or View seat cannot run Design plugins. + +## Verification + +The public repository contains automated tests and an end-to-end report. The real Figma flow covers connect, read, create, update, stale-target refusal, invalid input, reconnect, and guarded undo. + +## Identity and relationship + +Layntra is an independent open-source project created by Haozi and maintained at https://github.com/lessthanno/Layntra. It is not affiliated with, endorsed by, or sponsored by Figma or OpenAI. diff --git a/docs/llms.txt b/docs/llms.txt new file mode 100644 index 0000000..c88df82 --- /dev/null +++ b/docs/llms.txt @@ -0,0 +1,29 @@ +# Layntra + +> Layntra is a free, MIT-licensed Codex plugin and local Figma companion for controlled inspect, plan, apply, and undo workflows with editable Figma layers. + +Official website: https://lessthanno.github.io/Layntra/ +Source repository: https://github.com/lessthanno/Layntra +Current release: https://github.com/lessthanno/Layntra/releases/tag/v0.1.0 + +## Start here + +- [What Layntra is](https://lessthanno.github.io/Layntra/): Product overview and beginner installation path. +- [How Layntra works](https://lessthanno.github.io/Layntra/how-it-works.html): Architecture, command modes, write boundary, and verified flow. +- [Figma MCP alternative](https://lessthanno.github.io/Layntra/figma-mcp-alternative.html): Factual comparison with typical hosted integrations. +- [Frequently asked questions](https://lessthanno.github.io/Layntra/faq.html): Pricing, permissions, privacy, setup, and limitations. +- [Full model context](https://lessthanno.github.io/Layntra/llms-full.txt): Expanded factual project summary. + +## Key facts + +- Layntra is open source under the MIT License and costs $0. +- It is designed for product managers, founders, and nontechnical builders using Codex Desktop or CLI with Figma Desktop on macOS. +- The architecture is Codex skill → local stdio/MCP bridge → loopback WebSocket on 127.0.0.1:3846 → Figma companion plugin. +- It does not require a Figma API token, a hosted Layntra account, or Layntra telemetry. +- Read-only commands are separate from the explicit `$layntra apply` write command. +- Page and selection context are checked again before a write; stale targets are rejected. +- Supported results remain editable Figma nodes. +- Version 0.1.0 limits writes to batches of at most 100 and exposes neither deletion nor arbitrary code execution. +- Layntra does not bypass Figma permissions, plan restrictions, organization policies, or seat limitations. +- The local bridge does not make Codex offline; Codex data handling follows the user's Codex configuration. +- Layntra is an independent project and is not affiliated with Figma or OpenAI. diff --git a/docs/privacy.html b/docs/privacy.html new file mode 100644 index 0000000..fb31c78 --- /dev/null +++ b/docs/privacy.html @@ -0,0 +1,25 @@ + + + + + Layntra privacy — Website, local bridge, and Codex data boundaries + + + + + + + + +
+

Last updated August 1, 2026

Privacy.

Layntra is an open-source local tool, not a hosted account service. This page separates the website, local bridge, Codex, Figma, and GitHub boundaries.

+

This website

The Layntra website is a static GitHub Pages site. It does not set Layntra cookies, run Layntra analytics, show ads, or contain a Layntra contact form. GitHub may process request and security data when it serves GitHub Pages; refer to GitHub’s own privacy statement for that platform processing.

+

The Layntra bridge

The bridge binds to 127.0.0.1:3846 on the user’s machine. Layntra v0.1.0 does not send bridge telemetry to a hosted Layntra service and does not require a hosted Layntra account.

+

Codex

Layntra is not an offline AI model. Prompts, context, and model data handling are governed by the user’s Codex product, account, settings, and applicable OpenAI terms. Users should avoid sending secrets or sensitive design content unless their configuration and organizational policy permit it.

+

Figma

The companion runs through the Figma Plugin API in Figma Desktop. Figma files, accounts, workspace rules, and product telemetry remain governed by the user’s relationship with Figma.

+

GitHub interactions

Downloads, repository activity, stars, issues, pull requests, and discussions occur on GitHub and are governed by GitHub. Public issues and pull requests are visible to others. Do not include credentials, private file identifiers, or confidential screenshots.

+

Questions

For a Layntra privacy or security question, open a private security report when the topic is sensitive, or a public GitHub issue for general questions.

+
+ + + diff --git a/docs/robots.txt b/docs/robots.txt new file mode 100644 index 0000000..ec16ce7 --- /dev/null +++ b/docs/robots.txt @@ -0,0 +1,7 @@ +User-agent: * +Allow: / + +User-agent: OAI-SearchBot +Allow: / + +Sitemap: https://lessthanno.github.io/Layntra/sitemap.xml diff --git a/docs/sitemap.xml b/docs/sitemap.xml new file mode 100644 index 0000000..7b99011 --- /dev/null +++ b/docs/sitemap.xml @@ -0,0 +1,10 @@ + + + https://lessthanno.github.io/Layntra/2026-08-01 + https://lessthanno.github.io/Layntra/how-it-works.html2026-08-01 + https://lessthanno.github.io/Layntra/figma-mcp-alternative.html2026-08-01 + https://lessthanno.github.io/Layntra/faq.html2026-08-01 + https://lessthanno.github.io/Layntra/about.html2026-08-01 + https://lessthanno.github.io/Layntra/privacy.html2026-08-01 + https://lessthanno.github.io/Layntra/terms.html2026-08-01 + diff --git a/docs/standards/exceptions/2026-08-01-pr-4-independent-review.md b/docs/standards/exceptions/2026-08-01-pr-4-independent-review.md new file mode 100644 index 0000000..2f8d42a --- /dev/null +++ b/docs/standards/exceptions/2026-08-01-pr-4-independent-review.md @@ -0,0 +1,24 @@ +# One-time independent-review exception for PR #4 + +- **Rule and scope:** The independent GitHub approval requirement is waived + only for PR #4, which publishes a dependency-free static discovery website, + crawl metadata, and corresponding documentation tests. Branch protection + remains enabled. This exception does not cover product runtime code, bridge + permissions, Figma write behavior, release artifacts, or later pull requests. +- **Owner:** `@lessthanno` +- **Approver:** `@lessthanno`, through explicit repository-owner authorization + in the active Codex GEO publication task. +- **Business justification:** This single-maintainer repository cannot satisfy + the second-account approval gate, while a stable public site is required for + Layntra discovery and correct public explanation of its Figma boundaries. +- **Risk:** Author-only review can miss incorrect claims, broken crawl metadata, + accessibility defects, or static-site deployment errors. +- **Compensating controls:** The change adds no runtime JavaScript, analytics, + cookies, database, hosted Layntra service, Figma permissions, or product write + capability. Twenty-six automated tests, metadata and internal-link contracts, + public-source audit, secret scanning, Sitemap XML validation, desktop and + 390-pixel mobile browser inspection, contrast measurement, and a two-pass + pre-landing review are required. The merge commit is immediately reversible. +- **Expiry:** 2026-08-02. This exception cannot be reused for another PR. +- **Removal task:** `FLMCP-dxq` adds an independent reviewer before any future + runtime, permission-changing, release-artifact, or hosted-service change. diff --git a/docs/terms.html b/docs/terms.html new file mode 100644 index 0000000..35e6c01 --- /dev/null +++ b/docs/terms.html @@ -0,0 +1,25 @@ + + + + + Layntra terms — Open-source license, trademarks, and project scope + + + + + + + + +
+

Last updated August 1, 2026

Terms.

Layntra is an open-source software project, not a hosted design service. These notes summarize the project boundary; the repository license is controlling.

+

License

Layntra source code is offered under the MIT License. You may use, copy, modify, merge, publish, distribute, sublicense, and sell copies subject to that license’s conditions.

+

No warranty

The MIT License provides the software “as is,” without warranty. You are responsible for reviewing planned changes, protecting your files, maintaining backups or version history, and deciding whether Layntra is appropriate for your environment.

+

Third-party products

Codex, GitHub, Figma, Node.js, and operating-system services are third-party products with their own terms, privacy policies, availability, and technical requirements. Layntra does not change or override them.

+

Permissions

You must use Layntra only with files, workspaces, accounts, and systems you are authorized to access. The project does not grant additional Figma permissions or bypass plan, seat, organization, or plugin restrictions.

+

Trademarks and affiliation

Layntra is an independent open-source project and is not affiliated with, endorsed by, or sponsored by Figma or OpenAI. Figma, Codex, OpenAI, GitHub, and other names may be trademarks of their respective owners.

+

Changes and support

The project may change, add, or remove capabilities in future releases. No uptime or support-level commitment is offered. Current source, releases, and support channels are available on GitHub.

+
+ + + diff --git a/test/geo-site.test.js b/test/geo-site.test.js new file mode 100644 index 0000000..beeb444 --- /dev/null +++ b/test/geo-site.test.js @@ -0,0 +1,121 @@ +import assert from "node:assert/strict"; +import { access, readFile } from "node:fs/promises"; +import path from "node:path"; +import test from "node:test"; + +const baseUrl = "https://lessthanno.github.io/Layntra/"; +const releaseUrl = "https://github.com/lessthanno/Layntra/releases/tag/v0.1.0"; +const repositoryUrl = "https://github.com/lessthanno/Layntra"; +const pages = [ + "index.html", + "how-it-works.html", + "figma-mcp-alternative.html", + "faq.html", + "about.html", + "privacy.html", + "terms.html" +]; + +function firstMatch(content, pattern, message) { + const match = content.match(pattern); + assert.ok(match, message); + return match[1].trim(); +} + +function jsonLd(content) { + return [...content.matchAll(/