coderio 1.0.1-alpha.2 → 1.0.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 +48 -18
- package/dist/cli.js +8 -24
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -3
- package/dist/index.js +3 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -54,12 +54,12 @@ https://github.com/user-attachments/assets/bd0c3f18-e98a-4050-bf22-46b198fadac2
|
|
|
54
54
|
|
|
55
55
|
CodeRio can be seamlessly integrated into Cursor as a Skill. Simply input a prompt like **"Create a React project and restore this design with high fidelity,"** along with your output directory, Figma URL([Design Link](https://www.figma.com/design/c0UBII8lURfxZIY8W6tSDR/Top-16-Websites-of-2024---Awwwards--Community-?node-id=30-8264&t=FB3Hohq2nsH7ZFts-4)), and Token. The Agent will guide you step-by-step through the page generation process. For Landing Pages, it achieves **high-fidelity restoration**, accurately reproducing images and styles. It also automatically encapsulates reusable components (such as cards) and strictly adheres to **frontend development best practices**.
|
|
56
56
|
|
|
57
|
+
|
|
57
58
|
https://github.com/user-attachments/assets/43817e97-ffd2-40e3-9d33-78ee55b2ec2d
|
|
58
59
|
|
|
59
60
|
## 🚀 Quick Start
|
|
60
61
|
|
|
61
62
|
### Option 1: CLI (Recommended 👍🏻)
|
|
62
|
-
|
|
63
63
|
Best for one-click generation.
|
|
64
64
|
|
|
65
65
|
#### 1. Prerequisites
|
|
@@ -79,34 +79,62 @@ npm install -g coderio
|
|
|
79
79
|
pnpm add -g coderio
|
|
80
80
|
```
|
|
81
81
|
|
|
82
|
-
> **Note for pnpm v9+ users**: If you see a warning about "Ignored build scripts", run:
|
|
82
|
+
> **Note for pnpm v9+ users**: If you see a warning about "Ignored build scripts", run:
|
|
83
|
+
>
|
|
84
|
+
> ```bash
|
|
85
|
+
> pnpm approve-builds
|
|
86
|
+
> ```
|
|
87
|
+
>
|
|
88
|
+
> This allows native dependencies (better-sqlite3) to compile properly.
|
|
83
89
|
>
|
|
84
90
|
> **Note**: Validation features (e.g., `d2c --mode full`) require optional dependencies `playwright` and `sharp`. They are not bundled with coderio by default to keep installation lightweight. Please install them globally beforehand for smoother execution:
|
|
85
91
|
>
|
|
86
92
|
> ```bash
|
|
87
93
|
> npm install -g playwright sharp
|
|
88
94
|
> npx playwright install chromium
|
|
89
|
-
> ```
|
|
95
|
+
> ```
|
|
90
96
|
|
|
91
97
|
#### 3. Configuration
|
|
92
98
|
|
|
93
|
-
> **Important**:
|
|
99
|
+
> **Important**: This tool requires an LLM with **multimodal (vision) capabilities** to analyze design screenshots.
|
|
100
|
+
> We highly recommend using **`gemini-3-pro-preview`** for the best balance of performance and cost.
|
|
94
101
|
|
|
95
|
-
Create
|
|
102
|
+
Create `~/.coderio/config.yaml` (Windows: `%USERPROFILE%\.coderio\config.yaml`) with:
|
|
96
103
|
|
|
97
104
|
```yaml
|
|
98
105
|
model:
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
106
|
+
provider: openai # anthropic | openai | google
|
|
107
|
+
model: gemini-3-pro-preview
|
|
108
|
+
baseUrl: https://api.anthropic.com
|
|
109
|
+
apiKey: your-api-key-here
|
|
110
|
+
|
|
111
|
+
figma:
|
|
112
|
+
token: your-figma-token-here
|
|
113
|
+
|
|
114
|
+
debug:
|
|
115
|
+
enabled: false
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
<details>
|
|
119
|
+
<summary><strong>macOS / Linux One-click Command</strong></summary>
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
mkdir -p ~/.coderio
|
|
123
|
+
cat > ~/.coderio/config.yaml << 'EOF'
|
|
124
|
+
model:
|
|
125
|
+
provider: openai # anthropic | openai | google
|
|
126
|
+
model: gemini-3-pro-preview
|
|
127
|
+
baseUrl: https://api.anthropic.com
|
|
128
|
+
apiKey: your-api-key-here
|
|
103
129
|
|
|
104
130
|
figma:
|
|
105
|
-
|
|
131
|
+
token: your-figma-token-here
|
|
106
132
|
|
|
107
133
|
debug:
|
|
108
|
-
|
|
134
|
+
enabled: false
|
|
135
|
+
EOF
|
|
109
136
|
```
|
|
137
|
+
</details>
|
|
110
138
|
|
|
111
139
|
#### 4. Usage
|
|
112
140
|
|
|
@@ -135,7 +163,10 @@ pnpm dev
|
|
|
135
163
|
|
|
136
164
|
#### 6. View Validation Report
|
|
137
165
|
|
|
138
|
-
|
|
166
|
+
```bash
|
|
167
|
+
# Open validation report in browser
|
|
168
|
+
open coderio/<design-name_node-id>/process/validation/index.html
|
|
169
|
+
```
|
|
139
170
|
|
|
140
171
|
#### 📖 All Commands
|
|
141
172
|
|
|
@@ -148,22 +179,21 @@ report path: coderio/<design-name_node-id>/process/validation/index.html
|
|
|
148
179
|
| `images` | - | Download and process Figma assets |
|
|
149
180
|
|
|
150
181
|
### Option 2: Skill (Portable Embedded Workflow)
|
|
151
|
-
|
|
152
182
|
Best for control and precision using AI Agents.
|
|
153
183
|
|
|
154
184
|
**Prerequisites**:
|
|
155
185
|
Copy the Skill file to your Cursor configuration directory:
|
|
156
|
-
|
|
157
|
-
|
|
186
|
+
```bash
|
|
187
|
+
mkdir -p ~/.cursor/skills/design-to-code
|
|
188
|
+
cp docs/skills/SKILL.md ~/.cursor/skills/design-to-code/SKILL.md
|
|
189
|
+
```
|
|
158
190
|
|
|
159
191
|
**Using in Cursor**:
|
|
160
|
-
|
|
161
|
-
1. Open Cursor Chat.
|
|
192
|
+
1. Open Cursor Chat (`Cmd` + `L`).
|
|
162
193
|
2. Type: **"Use design-to-code skill to convert this design: [Your Figma URL]"**
|
|
163
194
|
3. The Agent will guide you step-by-step through protocol extraction and code generation.
|
|
164
195
|
|
|
165
196
|
**Using in Claude Code**:
|
|
166
|
-
|
|
167
197
|
1. Start Claude Code.
|
|
168
198
|
2. Type: **"Read docs/skills/SKILL.md and perform design conversion: [Your Figma URL]"**
|
|
169
199
|
|
package/dist/cli.js
CHANGED
|
@@ -475,7 +475,7 @@ var AGENT_CONTEXT_WINDOW_TOKENS = 128e3;
|
|
|
475
475
|
|
|
476
476
|
// src/cli/init.ts
|
|
477
477
|
function registerCommands(program) {
|
|
478
|
-
const version = false ? "0.0.1" : "1.0.1
|
|
478
|
+
const version = false ? "0.0.1" : "1.0.1";
|
|
479
479
|
program.name(CLI_NAME).description(`${CLI_NAME} - Convert Figma designs to code`).version(version, "-v, -V, --version", "Output the version number").showHelpAfterError();
|
|
480
480
|
}
|
|
481
481
|
|
|
@@ -594,17 +594,12 @@ var Workspace = class {
|
|
|
594
594
|
}
|
|
595
595
|
/**
|
|
596
596
|
* Delete all files and directories inside the workspace
|
|
597
|
-
* @param workspace - The workspace structure
|
|
598
|
-
* @param exclude - Optional list of file/directory names to exclude from deletion
|
|
599
597
|
*/
|
|
600
|
-
deleteWorkspace(workspace
|
|
598
|
+
deleteWorkspace(workspace) {
|
|
601
599
|
try {
|
|
602
600
|
if (fs2.existsSync(workspace.root)) {
|
|
603
601
|
const entries = fs2.readdirSync(workspace.root);
|
|
604
602
|
for (const entry of entries) {
|
|
605
|
-
if (exclude.includes(entry)) {
|
|
606
|
-
continue;
|
|
607
|
-
}
|
|
608
603
|
const fullPath = path2.join(workspace.root, entry);
|
|
609
604
|
fs2.rmSync(fullPath, { recursive: true, force: true });
|
|
610
605
|
}
|
|
@@ -658,7 +653,7 @@ function saveDebugLog(requestInfo, responseInfo) {
|
|
|
658
653
|
"------------response------------",
|
|
659
654
|
JSON.stringify(responseInfo, null, 2)
|
|
660
655
|
].join("\n");
|
|
661
|
-
writeFile(workspaceManager.path?.debug ?? "", `fetch_${(/* @__PURE__ */ new Date()).toISOString()
|
|
656
|
+
writeFile(workspaceManager.path?.debug ?? "", `fetch_${(/* @__PURE__ */ new Date()).toISOString()}.md`, debugContent);
|
|
662
657
|
}
|
|
663
658
|
async function get(url, config) {
|
|
664
659
|
const response = await axios.get(url, config);
|
|
@@ -1558,7 +1553,7 @@ async function callModel(options) {
|
|
|
1558
1553
|
"------------response------------",
|
|
1559
1554
|
JSON.stringify(message.text, null, 2)
|
|
1560
1555
|
].join("\n");
|
|
1561
|
-
writeFile(workspaceManager.path?.debug ?? "", `model_${(/* @__PURE__ */ new Date()).toISOString()
|
|
1556
|
+
writeFile(workspaceManager.path?.debug ?? "", `model_${(/* @__PURE__ */ new Date()).toISOString()}.md`, debugContent);
|
|
1562
1557
|
}
|
|
1563
1558
|
return message.text;
|
|
1564
1559
|
} catch (error) {
|
|
@@ -2017,7 +2012,7 @@ var parseFigmaUrl = (url) => {
|
|
|
2017
2012
|
if (!fileId || !nodeId) {
|
|
2018
2013
|
throw new Error("Invalid Figma URL");
|
|
2019
2014
|
}
|
|
2020
|
-
return { fileId, name, nodeId, projectName: `${name}_${nodeId
|
|
2015
|
+
return { fileId, name, nodeId, projectName: `${name}_${nodeId}` };
|
|
2021
2016
|
};
|
|
2022
2017
|
|
|
2023
2018
|
// src/cli/d2p.ts
|
|
@@ -6338,14 +6333,6 @@ async function checkpointExists(checkpointer, threadId) {
|
|
|
6338
6333
|
return false;
|
|
6339
6334
|
}
|
|
6340
6335
|
}
|
|
6341
|
-
async function clearCheckpoint(checkpointer, threadId) {
|
|
6342
|
-
try {
|
|
6343
|
-
await checkpointer.deleteThread(threadId);
|
|
6344
|
-
} catch (error) {
|
|
6345
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
6346
|
-
logger.printWarnLog(`Failed to clear checkpoint: ${errorMessage}`);
|
|
6347
|
-
}
|
|
6348
|
-
}
|
|
6349
6336
|
async function promptCheckpointChoice(checkpointer, threadId) {
|
|
6350
6337
|
const hasCheckpoint = await checkpointExists(checkpointer, threadId);
|
|
6351
6338
|
if (!hasCheckpoint) {
|
|
@@ -6354,9 +6341,6 @@ async function promptCheckpointChoice(checkpointer, threadId) {
|
|
|
6354
6341
|
const choice = await promptUserChoice();
|
|
6355
6342
|
return choice === "resume";
|
|
6356
6343
|
}
|
|
6357
|
-
async function clearThreadCheckpoint(checkpointer, threadId) {
|
|
6358
|
-
await clearCheckpoint(checkpointer, threadId);
|
|
6359
|
-
}
|
|
6360
6344
|
function initializeSqliteSaver(dbPath) {
|
|
6361
6345
|
const dbDir = path14.dirname(dbPath);
|
|
6362
6346
|
if (!fs11.existsSync(dbDir)) {
|
|
@@ -6372,13 +6356,13 @@ async function design2code(url, mode) {
|
|
|
6372
6356
|
const urlInfo = parseFigmaUrl(url);
|
|
6373
6357
|
const threadId = urlInfo.projectName;
|
|
6374
6358
|
const workspace = workspaceManager.initWorkspace(threadId);
|
|
6375
|
-
|
|
6359
|
+
let checkpointer = initializeSqliteSaver(workspace.db);
|
|
6376
6360
|
const resume = await promptCheckpointChoice(checkpointer, threadId);
|
|
6377
6361
|
logger.printInfoLog(`Starting design-to-code process for: ${urlInfo.projectName}`);
|
|
6378
6362
|
if (resume !== true) {
|
|
6379
|
-
workspaceManager.deleteWorkspace(workspace
|
|
6363
|
+
workspaceManager.deleteWorkspace(workspace);
|
|
6380
6364
|
logger.printInfoLog("Starting fresh...");
|
|
6381
|
-
|
|
6365
|
+
checkpointer = initializeSqliteSaver(workspace.db);
|
|
6382
6366
|
} else {
|
|
6383
6367
|
logger.printInfoLog("Resuming from cache...");
|
|
6384
6368
|
}
|