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 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: `pnpm approve-builds` to allow native dependencies (better-sqlite3) to compile properly.
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**: Requires a **multimodal (vision)** model (Recommended: `gemini-3-pro-preview`).
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 config file at `~/.coderio/config.yaml` (Windows: `%USERPROFILE%\.coderio\config.yaml`):
102
+ Create `~/.coderio/config.yaml` (Windows: `%USERPROFILE%\.coderio\config.yaml`) with:
96
103
 
97
104
  ```yaml
98
105
  model:
99
- provider: openai # anthropic | openai | google
100
- model: gemini-3-pro-preview
101
- baseUrl: https://api.anthropic.com
102
- apiKey: your-api-key-here
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
- token: your-figma-token-here
131
+ token: your-figma-token-here
106
132
 
107
133
  debug:
108
- enabled: false # set 'true', if you want to save model and request information
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
- report path: coderio/<design-name_node-id>/process/validation/index.html
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
- Copy `skills\design-to-code` folder to `~\.cursor\skills` (Windows: `%USERPROFILE%\.cursor\skills`)
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-alpha.2";
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, exclude = []) {
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().replace(/:/g, "-")}.md`, debugContent);
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().replace(/:/g, "-")}.md`, debugContent);
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.replace(/:/g, "_")}` };
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
- const checkpointer = initializeSqliteSaver(workspace.db);
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, ["checkpoint"]);
6363
+ workspaceManager.deleteWorkspace(workspace);
6380
6364
  logger.printInfoLog("Starting fresh...");
6381
- await clearThreadCheckpoint(checkpointer, threadId);
6365
+ checkpointer = initializeSqliteSaver(workspace.db);
6382
6366
  } else {
6383
6367
  logger.printInfoLog("Resuming from cache...");
6384
6368
  }