figma-to-code-agent 0.6.0 → 0.7.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.
- package/CHANGELOG.md +32 -0
- package/README.md +68 -76
- package/README.zh-CN.md +173 -0
- package/dist/agent/ConversationContext.d.ts +91 -0
- package/dist/agent/ConversationContext.d.ts.map +1 -0
- package/dist/agent/ConversationContext.js +271 -0
- package/dist/agent/ConversationContext.js.map +1 -0
- package/dist/agent/DecisionEngine.d.ts +77 -0
- package/dist/agent/DecisionEngine.d.ts.map +1 -0
- package/dist/agent/DecisionEngine.js +414 -0
- package/dist/agent/DecisionEngine.js.map +1 -0
- package/dist/agent/ExecutionOrchestrator.d.ts +55 -0
- package/dist/agent/ExecutionOrchestrator.d.ts.map +1 -0
- package/dist/agent/ExecutionOrchestrator.js +360 -0
- package/dist/agent/ExecutionOrchestrator.js.map +1 -0
- package/dist/agent/IntentUnderstandingEngine.d.ts +43 -0
- package/dist/agent/IntentUnderstandingEngine.d.ts.map +1 -0
- package/dist/agent/IntentUnderstandingEngine.js +261 -0
- package/dist/agent/IntentUnderstandingEngine.js.map +1 -0
- package/dist/agent/index.d.ts +9 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +30 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/types.d.ts +111 -0
- package/dist/agent/types.d.ts.map +1 -0
- package/dist/agent/types.js +6 -0
- package/dist/agent/types.js.map +1 -0
- package/dist/cli/InteractiveCLI.d.ts +109 -0
- package/dist/cli/InteractiveCLI.d.ts.map +1 -0
- package/dist/cli/InteractiveCLI.js +534 -0
- package/dist/cli/InteractiveCLI.js.map +1 -0
- package/dist/cli/ProgressDisplay.d.ts +117 -0
- package/dist/cli/ProgressDisplay.d.ts.map +1 -0
- package/dist/cli/ProgressDisplay.js +370 -0
- package/dist/cli/ProgressDisplay.js.map +1 -0
- package/dist/cli/index.d.ts +6 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +22 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/consistency/DesignConsistencyChecker.d.ts +125 -0
- package/dist/consistency/DesignConsistencyChecker.d.ts.map +1 -0
- package/dist/consistency/DesignConsistencyChecker.js +448 -0
- package/dist/consistency/DesignConsistencyChecker.js.map +1 -0
- package/dist/consistency/index.d.ts +5 -0
- package/dist/consistency/index.d.ts.map +1 -0
- package/dist/consistency/index.js +21 -0
- package/dist/consistency/index.js.map +1 -0
- package/dist/context/CodeStyleMatcher.d.ts +124 -0
- package/dist/context/CodeStyleMatcher.d.ts.map +1 -0
- package/dist/context/CodeStyleMatcher.js +558 -0
- package/dist/context/CodeStyleMatcher.js.map +1 -0
- package/dist/context/IncrementalUpdater.d.ts +97 -0
- package/dist/context/IncrementalUpdater.d.ts.map +1 -0
- package/dist/context/IncrementalUpdater.js +431 -0
- package/dist/context/IncrementalUpdater.js.map +1 -0
- package/dist/context/index.d.ts +6 -0
- package/dist/context/index.d.ts.map +1 -0
- package/dist/context/index.js +22 -0
- package/dist/context/index.js.map +1 -0
- package/dist/feedback/FeedbackLoop.d.ts +125 -0
- package/dist/feedback/FeedbackLoop.d.ts.map +1 -0
- package/dist/feedback/FeedbackLoop.js +353 -0
- package/dist/feedback/FeedbackLoop.js.map +1 -0
- package/dist/feedback/index.d.ts +5 -0
- package/dist/feedback/index.d.ts.map +1 -0
- package/dist/feedback/index.js +21 -0
- package/dist/feedback/index.js.map +1 -0
- package/dist/mcp/FigmaMCPIntegration.d.ts +72 -0
- package/dist/mcp/FigmaMCPIntegration.d.ts.map +1 -0
- package/dist/mcp/FigmaMCPIntegration.js +173 -0
- package/dist/mcp/FigmaMCPIntegration.js.map +1 -0
- package/dist/mcp/MCPServiceManager.d.ts +109 -0
- package/dist/mcp/MCPServiceManager.d.ts.map +1 -0
- package/dist/mcp/MCPServiceManager.js +237 -0
- package/dist/mcp/MCPServiceManager.js.map +1 -0
- package/dist/mcp/MCPToolAdapter.d.ts +73 -0
- package/dist/mcp/MCPToolAdapter.d.ts.map +1 -0
- package/dist/mcp/MCPToolAdapter.js +249 -0
- package/dist/mcp/MCPToolAdapter.js.map +1 -0
- package/dist/mcp/index.d.ts +7 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +23 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp-server/MCPServer.d.ts +125 -0
- package/dist/mcp-server/MCPServer.d.ts.map +1 -0
- package/dist/mcp-server/MCPServer.js +449 -0
- package/dist/mcp-server/MCPServer.js.map +1 -0
- package/dist/mcp-server/index.d.ts +5 -0
- package/dist/mcp-server/index.d.ts.map +1 -0
- package/dist/mcp-server/index.js +21 -0
- package/dist/mcp-server/index.js.map +1 -0
- package/dist/monitoring/ExecutionSummary.d.ts +160 -0
- package/dist/monitoring/ExecutionSummary.d.ts.map +1 -0
- package/dist/monitoring/ExecutionSummary.js +345 -0
- package/dist/monitoring/ExecutionSummary.js.map +1 -0
- package/dist/monitoring/Logger.d.ts +139 -0
- package/dist/monitoring/Logger.d.ts.map +1 -0
- package/dist/monitoring/Logger.js +406 -0
- package/dist/monitoring/Logger.js.map +1 -0
- package/dist/monitoring/index.d.ts +6 -0
- package/dist/monitoring/index.d.ts.map +1 -0
- package/dist/monitoring/index.js +22 -0
- package/dist/monitoring/index.js.map +1 -0
- package/dist/performance/LLMCache.d.ts +133 -0
- package/dist/performance/LLMCache.d.ts.map +1 -0
- package/dist/performance/LLMCache.js +358 -0
- package/dist/performance/LLMCache.js.map +1 -0
- package/dist/performance/ParallelProcessor.d.ts +89 -0
- package/dist/performance/ParallelProcessor.d.ts.map +1 -0
- package/dist/performance/ParallelProcessor.js +253 -0
- package/dist/performance/ParallelProcessor.js.map +1 -0
- package/dist/performance/TokenMonitor.d.ts +166 -0
- package/dist/performance/TokenMonitor.d.ts.map +1 -0
- package/dist/performance/TokenMonitor.js +315 -0
- package/dist/performance/TokenMonitor.js.map +1 -0
- package/dist/performance/index.d.ts +7 -0
- package/dist/performance/index.d.ts.map +1 -0
- package/dist/performance/index.js +23 -0
- package/dist/performance/index.js.map +1 -0
- package/dist/prototype/InteractivePrototypeGenerator.d.ts +175 -0
- package/dist/prototype/InteractivePrototypeGenerator.d.ts.map +1 -0
- package/dist/prototype/InteractivePrototypeGenerator.js +624 -0
- package/dist/prototype/InteractivePrototypeGenerator.js.map +1 -0
- package/dist/prototype/index.d.ts +5 -0
- package/dist/prototype/index.d.ts.map +1 -0
- package/dist/prototype/index.js +21 -0
- package/dist/prototype/index.js.map +1 -0
- package/dist/skill/SkillConfig.d.ts +66 -0
- package/dist/skill/SkillConfig.d.ts.map +1 -0
- package/dist/skill/SkillConfig.js +233 -0
- package/dist/skill/SkillConfig.js.map +1 -0
- package/dist/skill/SkillInterface.d.ts +102 -0
- package/dist/skill/SkillInterface.d.ts.map +1 -0
- package/dist/skill/SkillInterface.js +425 -0
- package/dist/skill/SkillInterface.js.map +1 -0
- package/dist/skill/index.d.ts +7 -0
- package/dist/skill/index.d.ts.map +1 -0
- package/dist/skill/index.js +23 -0
- package/dist/skill/index.js.map +1 -0
- package/dist/skill/types.d.ts +103 -0
- package/dist/skill/types.d.ts.map +1 -0
- package/dist/skill/types.js +6 -0
- package/dist/skill/types.js.map +1 -0
- package/dist/templates/TemplateManager.d.ts +147 -0
- package/dist/templates/TemplateManager.d.ts.map +1 -0
- package/dist/templates/TemplateManager.js +418 -0
- package/dist/templates/TemplateManager.js.map +1 -0
- package/dist/templates/index.d.ts +6 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +10 -0
- package/dist/templates/index.js.map +1 -0
- package/dist/tools/CodeGenerationTool.d.ts +32 -0
- package/dist/tools/CodeGenerationTool.d.ts.map +1 -0
- package/dist/tools/CodeGenerationTool.js +63 -0
- package/dist/tools/CodeGenerationTool.js.map +1 -0
- package/dist/tools/FigmaExtractionTool.d.ts +45 -0
- package/dist/tools/FigmaExtractionTool.d.ts.map +1 -0
- package/dist/tools/FigmaExtractionTool.js +105 -0
- package/dist/tools/FigmaExtractionTool.js.map +1 -0
- package/dist/tools/ProjectAnalysisTool.d.ts +104 -0
- package/dist/tools/ProjectAnalysisTool.d.ts.map +1 -0
- package/dist/tools/ProjectAnalysisTool.js +428 -0
- package/dist/tools/ProjectAnalysisTool.js.map +1 -0
- package/dist/tools/ToolRegistry.d.ts +59 -0
- package/dist/tools/ToolRegistry.d.ts.map +1 -0
- package/dist/tools/ToolRegistry.js +162 -0
- package/dist/tools/ToolRegistry.js.map +1 -0
- package/dist/tools/TransformationTool.d.ts +30 -0
- package/dist/tools/TransformationTool.d.ts.map +1 -0
- package/dist/tools/TransformationTool.js +50 -0
- package/dist/tools/TransformationTool.js.map +1 -0
- package/dist/tools/index.d.ts +10 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/tools/index.js +32 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/types.d.ts +74 -0
- package/dist/tools/types.d.ts.map +1 -0
- package/dist/tools/types.js +6 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/transformation/transformers/LayoutOptimizer.d.ts +8 -0
- package/dist/transformation/transformers/LayoutOptimizer.d.ts.map +1 -1
- package/dist/transformation/transformers/LayoutOptimizer.js +157 -15
- package/dist/transformation/transformers/LayoutOptimizer.js.map +1 -1
- package/dist/version/VersionManager.d.ts +128 -0
- package/dist/version/VersionManager.d.ts.map +1 -0
- package/dist/version/VersionManager.js +400 -0
- package/dist/version/VersionManager.js.map +1 -0
- package/dist/version/index.d.ts +5 -0
- package/dist/version/index.d.ts.map +1 -0
- package/dist/version/index.js +21 -0
- package/dist/version/index.js.map +1 -0
- package/package.json +3 -1
- package/QUICKSTART.md +0 -178
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 版本管理系统
|
|
4
|
+
* 管理代码生成的版本历史,支持版本回滚和差异对比
|
|
5
|
+
*/
|
|
6
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
+
if (k2 === undefined) k2 = k;
|
|
8
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
+
}
|
|
12
|
+
Object.defineProperty(o, k2, desc);
|
|
13
|
+
}) : (function(o, m, k, k2) {
|
|
14
|
+
if (k2 === undefined) k2 = k;
|
|
15
|
+
o[k2] = m[k];
|
|
16
|
+
}));
|
|
17
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
+
}) : function(o, v) {
|
|
20
|
+
o["default"] = v;
|
|
21
|
+
});
|
|
22
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
+
var ownKeys = function(o) {
|
|
24
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
+
var ar = [];
|
|
26
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
+
return ar;
|
|
28
|
+
};
|
|
29
|
+
return ownKeys(o);
|
|
30
|
+
};
|
|
31
|
+
return function (mod) {
|
|
32
|
+
if (mod && mod.__esModule) return mod;
|
|
33
|
+
var result = {};
|
|
34
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
+
__setModuleDefault(result, mod);
|
|
36
|
+
return result;
|
|
37
|
+
};
|
|
38
|
+
})();
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.VersionManager = void 0;
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const uuid_1 = require("uuid");
|
|
44
|
+
/**
|
|
45
|
+
* 版本管理器
|
|
46
|
+
*/
|
|
47
|
+
class VersionManager {
|
|
48
|
+
constructor(projectRoot) {
|
|
49
|
+
this.versions = new Map();
|
|
50
|
+
this.versionsDir = path.join(projectRoot, '.figma-versions');
|
|
51
|
+
this.ensureVersionsDir();
|
|
52
|
+
this.loadVersions();
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* 创建新版本
|
|
56
|
+
*/
|
|
57
|
+
async createVersion(files, config, description = 'Auto-generated version') {
|
|
58
|
+
const version = {
|
|
59
|
+
id: (0, uuid_1.v4)(),
|
|
60
|
+
timestamp: new Date(),
|
|
61
|
+
description,
|
|
62
|
+
files,
|
|
63
|
+
config,
|
|
64
|
+
metadata: {
|
|
65
|
+
parentVersionId: this.currentVersionId,
|
|
66
|
+
stats: this.calculateStats(files),
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
// 保存版本
|
|
70
|
+
await this.saveVersion(version);
|
|
71
|
+
// 更新内存中的版本列表
|
|
72
|
+
this.versions.set(version.id, version);
|
|
73
|
+
this.currentVersionId = version.id;
|
|
74
|
+
return version;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* 获取版本列表
|
|
78
|
+
*/
|
|
79
|
+
listVersions() {
|
|
80
|
+
return Array.from(this.versions.values()).sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* 获取特定版本
|
|
84
|
+
*/
|
|
85
|
+
getVersion(versionId) {
|
|
86
|
+
return this.versions.get(versionId);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* 获取当前版本
|
|
90
|
+
*/
|
|
91
|
+
getCurrentVersion() {
|
|
92
|
+
if (!this.currentVersionId) {
|
|
93
|
+
return undefined;
|
|
94
|
+
}
|
|
95
|
+
return this.versions.get(this.currentVersionId);
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 回滚到指定版本
|
|
99
|
+
*/
|
|
100
|
+
async rollback(versionId, targetDir) {
|
|
101
|
+
const version = this.versions.get(versionId);
|
|
102
|
+
if (!version) {
|
|
103
|
+
throw new Error(`Version ${versionId} not found`);
|
|
104
|
+
}
|
|
105
|
+
// 清空目标目录(保留 node_modules 等)
|
|
106
|
+
await this.cleanTargetDir(targetDir);
|
|
107
|
+
// 恢复文件
|
|
108
|
+
for (const [filePath, content] of version.files) {
|
|
109
|
+
const fullPath = path.join(targetDir, filePath);
|
|
110
|
+
const dir = path.dirname(fullPath);
|
|
111
|
+
if (!fs.existsSync(dir)) {
|
|
112
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
113
|
+
}
|
|
114
|
+
fs.writeFileSync(fullPath, content, 'utf-8');
|
|
115
|
+
}
|
|
116
|
+
// 更新当前版本
|
|
117
|
+
this.currentVersionId = versionId;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* 比较两个版本
|
|
121
|
+
*/
|
|
122
|
+
async compareVersions(versionIdA, versionIdB) {
|
|
123
|
+
const versionA = this.versions.get(versionIdA);
|
|
124
|
+
const versionB = this.versions.get(versionIdB);
|
|
125
|
+
if (!versionA || !versionB) {
|
|
126
|
+
throw new Error('One or both versions not found');
|
|
127
|
+
}
|
|
128
|
+
const filesAdded = [];
|
|
129
|
+
const filesRemoved = [];
|
|
130
|
+
const filesModified = [];
|
|
131
|
+
const changes = new Map();
|
|
132
|
+
// 检查版本 B 中的文件
|
|
133
|
+
for (const [filePath, contentB] of versionB.files) {
|
|
134
|
+
const contentA = versionA.files.get(filePath);
|
|
135
|
+
if (!contentA) {
|
|
136
|
+
// 文件在 A 中不存在,是新增的
|
|
137
|
+
filesAdded.push(filePath);
|
|
138
|
+
}
|
|
139
|
+
else if (contentA !== contentB) {
|
|
140
|
+
// 文件被修改
|
|
141
|
+
filesModified.push(filePath);
|
|
142
|
+
changes.set(filePath, this.calculateFileDiff(filePath, contentA, contentB));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// 检查版本 A 中被删除的文件
|
|
146
|
+
for (const filePath of versionA.files.keys()) {
|
|
147
|
+
if (!versionB.files.has(filePath)) {
|
|
148
|
+
filesRemoved.push(filePath);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return {
|
|
152
|
+
versionA: versionIdA,
|
|
153
|
+
versionB: versionIdB,
|
|
154
|
+
filesAdded,
|
|
155
|
+
filesRemoved,
|
|
156
|
+
filesModified,
|
|
157
|
+
changes,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* 删除版本
|
|
162
|
+
*/
|
|
163
|
+
async deleteVersion(versionId) {
|
|
164
|
+
const version = this.versions.get(versionId);
|
|
165
|
+
if (!version) {
|
|
166
|
+
throw new Error(`Version ${versionId} not found`);
|
|
167
|
+
}
|
|
168
|
+
// 删除版本文件
|
|
169
|
+
const versionFile = path.join(this.versionsDir, `${versionId}.json`);
|
|
170
|
+
if (fs.existsSync(versionFile)) {
|
|
171
|
+
fs.unlinkSync(versionFile);
|
|
172
|
+
}
|
|
173
|
+
// 从内存中删除
|
|
174
|
+
this.versions.delete(versionId);
|
|
175
|
+
// 如果删除的是当前版本,更新当前版本指针
|
|
176
|
+
if (this.currentVersionId === versionId) {
|
|
177
|
+
const versions = this.listVersions();
|
|
178
|
+
this.currentVersionId = versions.length > 0 ? versions[0].id : undefined;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* 添加版本标签
|
|
183
|
+
*/
|
|
184
|
+
async tagVersion(versionId, tag) {
|
|
185
|
+
const version = this.versions.get(versionId);
|
|
186
|
+
if (!version) {
|
|
187
|
+
throw new Error(`Version ${versionId} not found`);
|
|
188
|
+
}
|
|
189
|
+
if (!version.metadata.tags) {
|
|
190
|
+
version.metadata.tags = [];
|
|
191
|
+
}
|
|
192
|
+
if (!version.metadata.tags.includes(tag)) {
|
|
193
|
+
version.metadata.tags.push(tag);
|
|
194
|
+
await this.saveVersion(version);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* 按标签查找版本
|
|
199
|
+
*/
|
|
200
|
+
findVersionsByTag(tag) {
|
|
201
|
+
return Array.from(this.versions.values()).filter((v) => v.metadata.tags && v.metadata.tags.includes(tag));
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* 导出版本
|
|
205
|
+
*/
|
|
206
|
+
async exportVersion(versionId, outputPath) {
|
|
207
|
+
const version = this.versions.get(versionId);
|
|
208
|
+
if (!version) {
|
|
209
|
+
throw new Error(`Version ${versionId} not found`);
|
|
210
|
+
}
|
|
211
|
+
const exportData = {
|
|
212
|
+
version: {
|
|
213
|
+
id: version.id,
|
|
214
|
+
timestamp: version.timestamp,
|
|
215
|
+
description: version.description,
|
|
216
|
+
config: version.config,
|
|
217
|
+
metadata: version.metadata,
|
|
218
|
+
},
|
|
219
|
+
files: Array.from(version.files.entries()),
|
|
220
|
+
};
|
|
221
|
+
fs.writeFileSync(outputPath, JSON.stringify(exportData, null, 2), 'utf-8');
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* 导入版本
|
|
225
|
+
*/
|
|
226
|
+
async importVersion(importPath) {
|
|
227
|
+
const content = fs.readFileSync(importPath, 'utf-8');
|
|
228
|
+
const importData = JSON.parse(content);
|
|
229
|
+
const version = {
|
|
230
|
+
...importData.version,
|
|
231
|
+
timestamp: new Date(importData.version.timestamp),
|
|
232
|
+
files: new Map(importData.files),
|
|
233
|
+
};
|
|
234
|
+
// 生成新的 ID 避免冲突
|
|
235
|
+
version.id = (0, uuid_1.v4)();
|
|
236
|
+
version.metadata.parentVersionId = undefined;
|
|
237
|
+
await this.saveVersion(version);
|
|
238
|
+
this.versions.set(version.id, version);
|
|
239
|
+
return version;
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* 保存版本到磁盘
|
|
243
|
+
*/
|
|
244
|
+
async saveVersion(version) {
|
|
245
|
+
const versionFile = path.join(this.versionsDir, `${version.id}.json`);
|
|
246
|
+
const data = {
|
|
247
|
+
id: version.id,
|
|
248
|
+
timestamp: version.timestamp.toISOString(),
|
|
249
|
+
description: version.description,
|
|
250
|
+
config: version.config,
|
|
251
|
+
metadata: version.metadata,
|
|
252
|
+
files: Array.from(version.files.entries()),
|
|
253
|
+
};
|
|
254
|
+
fs.writeFileSync(versionFile, JSON.stringify(data, null, 2), 'utf-8');
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* 从磁盘加载版本
|
|
258
|
+
*/
|
|
259
|
+
loadVersions() {
|
|
260
|
+
if (!fs.existsSync(this.versionsDir)) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const files = fs.readdirSync(this.versionsDir);
|
|
264
|
+
for (const file of files) {
|
|
265
|
+
if (!file.endsWith('.json')) {
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
try {
|
|
269
|
+
const filePath = path.join(this.versionsDir, file);
|
|
270
|
+
const content = fs.readFileSync(filePath, 'utf-8');
|
|
271
|
+
const data = JSON.parse(content);
|
|
272
|
+
const version = {
|
|
273
|
+
id: data.id,
|
|
274
|
+
timestamp: new Date(data.timestamp),
|
|
275
|
+
description: data.description,
|
|
276
|
+
config: data.config,
|
|
277
|
+
metadata: data.metadata,
|
|
278
|
+
files: new Map(data.files),
|
|
279
|
+
};
|
|
280
|
+
this.versions.set(version.id, version);
|
|
281
|
+
// 更新当前版本(最新的)
|
|
282
|
+
if (!this.currentVersionId ||
|
|
283
|
+
version.timestamp > this.versions.get(this.currentVersionId).timestamp) {
|
|
284
|
+
this.currentVersionId = version.id;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
console.error(`Failed to load version from ${file}:`, error);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* 确保版本目录存在
|
|
294
|
+
*/
|
|
295
|
+
ensureVersionsDir() {
|
|
296
|
+
if (!fs.existsSync(this.versionsDir)) {
|
|
297
|
+
fs.mkdirSync(this.versionsDir, { recursive: true });
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* 计算统计信息
|
|
302
|
+
*/
|
|
303
|
+
calculateStats(files) {
|
|
304
|
+
let linesOfCode = 0;
|
|
305
|
+
let componentsCount = 0;
|
|
306
|
+
for (const [filePath, content] of files) {
|
|
307
|
+
linesOfCode += content.split('\n').length;
|
|
308
|
+
// 简单的组件计数(检测文件名)
|
|
309
|
+
const ext = path.extname(filePath);
|
|
310
|
+
if (['.tsx', '.jsx', '.vue'].includes(ext)) {
|
|
311
|
+
componentsCount++;
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
return {
|
|
315
|
+
filesCount: files.size,
|
|
316
|
+
linesOfCode,
|
|
317
|
+
componentsCount,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* 计算文件差异
|
|
322
|
+
*/
|
|
323
|
+
calculateFileDiff(filePath, contentA, contentB) {
|
|
324
|
+
const linesA = contentA.split('\n');
|
|
325
|
+
const linesB = contentB.split('\n');
|
|
326
|
+
let linesAdded = 0;
|
|
327
|
+
let linesRemoved = 0;
|
|
328
|
+
let linesModified = 0;
|
|
329
|
+
// 简单的行级差异(实际应该使用更复杂的 diff 算法)
|
|
330
|
+
const maxLines = Math.max(linesA.length, linesB.length);
|
|
331
|
+
for (let i = 0; i < maxLines; i++) {
|
|
332
|
+
const lineA = linesA[i];
|
|
333
|
+
const lineB = linesB[i];
|
|
334
|
+
if (lineA === undefined) {
|
|
335
|
+
linesAdded++;
|
|
336
|
+
}
|
|
337
|
+
else if (lineB === undefined) {
|
|
338
|
+
linesRemoved++;
|
|
339
|
+
}
|
|
340
|
+
else if (lineA !== lineB) {
|
|
341
|
+
linesModified++;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
// 生成简单的 diff 字符串
|
|
345
|
+
const diff = this.generateSimpleDiff(linesA, linesB);
|
|
346
|
+
return {
|
|
347
|
+
path: filePath,
|
|
348
|
+
linesAdded,
|
|
349
|
+
linesRemoved,
|
|
350
|
+
linesModified,
|
|
351
|
+
diff,
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* 生成简单的 diff 字符串
|
|
356
|
+
*/
|
|
357
|
+
generateSimpleDiff(linesA, linesB) {
|
|
358
|
+
const diffLines = [];
|
|
359
|
+
const maxLines = Math.max(linesA.length, linesB.length);
|
|
360
|
+
for (let i = 0; i < maxLines; i++) {
|
|
361
|
+
const lineA = linesA[i];
|
|
362
|
+
const lineB = linesB[i];
|
|
363
|
+
if (lineA === undefined) {
|
|
364
|
+
diffLines.push(`+ ${lineB}`);
|
|
365
|
+
}
|
|
366
|
+
else if (lineB === undefined) {
|
|
367
|
+
diffLines.push(`- ${lineA}`);
|
|
368
|
+
}
|
|
369
|
+
else if (lineA !== lineB) {
|
|
370
|
+
diffLines.push(`- ${lineA}`);
|
|
371
|
+
diffLines.push(`+ ${lineB}`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
return diffLines.join('\n');
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* 清空目标目录
|
|
378
|
+
*/
|
|
379
|
+
async cleanTargetDir(targetDir) {
|
|
380
|
+
const skipDirs = ['node_modules', '.git', '.figma-versions', '.figma-backups'];
|
|
381
|
+
if (!fs.existsSync(targetDir)) {
|
|
382
|
+
return;
|
|
383
|
+
}
|
|
384
|
+
const entries = fs.readdirSync(targetDir, { withFileTypes: true });
|
|
385
|
+
for (const entry of entries) {
|
|
386
|
+
if (skipDirs.includes(entry.name)) {
|
|
387
|
+
continue;
|
|
388
|
+
}
|
|
389
|
+
const fullPath = path.join(targetDir, entry.name);
|
|
390
|
+
if (entry.isDirectory()) {
|
|
391
|
+
fs.rmSync(fullPath, { recursive: true, force: true });
|
|
392
|
+
}
|
|
393
|
+
else {
|
|
394
|
+
fs.unlinkSync(fullPath);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
exports.VersionManager = VersionManager;
|
|
400
|
+
//# sourceMappingURL=VersionManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VersionManager.js","sourceRoot":"","sources":["../../src/version/VersionManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/version/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 版本管理模块
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
__exportStar(require("./VersionManager"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/version/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,mDAAiC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "figma-to-code-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "AI Agent that converts Figma designs to production-ready code with optional LLM enhancements",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -73,9 +73,11 @@
|
|
|
73
73
|
},
|
|
74
74
|
"dependencies": {
|
|
75
75
|
"@aws-sdk/client-bedrock-runtime": "^3.987.0",
|
|
76
|
+
"@types/uuid": "^10.0.0",
|
|
76
77
|
"axios": "^1.6.7",
|
|
77
78
|
"fast-check": "^3.15.1",
|
|
78
79
|
"puppeteer": "^22.0.0",
|
|
80
|
+
"uuid": "^13.0.0",
|
|
79
81
|
"ws": "^8.19.0"
|
|
80
82
|
}
|
|
81
83
|
}
|
package/QUICKSTART.md
DELETED
|
@@ -1,178 +0,0 @@
|
|
|
1
|
-
# Quick Start
|
|
2
|
-
|
|
3
|
-
## 1. Install
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
npm install -g figma-to-code-agent
|
|
7
|
-
```
|
|
8
|
-
|
|
9
|
-
Or skip install and use `npx figma-to-code-agent` directly.
|
|
10
|
-
|
|
11
|
-
## 2. Get Your Figma Token
|
|
12
|
-
|
|
13
|
-
1. Go to [Figma API Settings](https://www.figma.com/developers/api#access-tokens)
|
|
14
|
-
2. Click "Get personal access token"
|
|
15
|
-
3. Copy the token
|
|
16
|
-
|
|
17
|
-
## 3. Get File Key & Node ID
|
|
18
|
-
|
|
19
|
-
From your Figma URL:
|
|
20
|
-
|
|
21
|
-
```
|
|
22
|
-
https://www.figma.com/design/ABC123DEF456/My-Design?node-id=100-200
|
|
23
|
-
^^^^^^^^^^^^^^ ^^^^^^^
|
|
24
|
-
File Key Node ID
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
Node ID format: `100-200` (use hyphen, not colon)
|
|
28
|
-
|
|
29
|
-
## 4. Generate Code
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
# React component
|
|
33
|
-
npx figma-to-code-agent \
|
|
34
|
-
--token YOUR_FIGMA_TOKEN \
|
|
35
|
-
--file ABC123DEF456 \
|
|
36
|
-
--node 100-200 \
|
|
37
|
-
--framework react \
|
|
38
|
-
--output ./output
|
|
39
|
-
|
|
40
|
-
# Vue component
|
|
41
|
-
npx figma-to-code-agent \
|
|
42
|
-
--token YOUR_FIGMA_TOKEN \
|
|
43
|
-
--file ABC123DEF456 \
|
|
44
|
-
--node 100-200 \
|
|
45
|
-
--framework vue \
|
|
46
|
-
--output ./output
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
Or use environment variable:
|
|
50
|
-
|
|
51
|
-
```bash
|
|
52
|
-
export FIGMA_TOKEN="your-token"
|
|
53
|
-
npx figma-to-code-agent --file ABC123DEF456 --node 100-200 --output ./output
|
|
54
|
-
```
|
|
55
|
-
|
|
56
|
-
## 5. Preview in Browser
|
|
57
|
-
|
|
58
|
-
Add `--preview` to instantly open the result in your browser:
|
|
59
|
-
|
|
60
|
-
```bash
|
|
61
|
-
npx figma-to-code-agent \
|
|
62
|
-
--token YOUR_FIGMA_TOKEN \
|
|
63
|
-
--file ABC123DEF456 \
|
|
64
|
-
--node 100-200 \
|
|
65
|
-
--framework react \
|
|
66
|
-
--output ./output \
|
|
67
|
-
--preview
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
This copies the generated files to the built-in test app, starts a Vite dev server, and opens your browser. Press `Ctrl+C` to stop — temporary files are cleaned up automatically.
|
|
71
|
-
|
|
72
|
-
## 6. TypeScript Output (Optional)
|
|
73
|
-
|
|
74
|
-
By default, generates `.jsx` / `.vue`. Add `--typescript` for `.tsx` output:
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
npx figma-to-code-agent \
|
|
78
|
-
--token YOUR_FIGMA_TOKEN \
|
|
79
|
-
--file ABC123DEF456 \
|
|
80
|
-
--node 100-200 \
|
|
81
|
-
--framework react \
|
|
82
|
-
--typescript \
|
|
83
|
-
--output ./output
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
## Generated Output
|
|
87
|
-
|
|
88
|
-
For a React component with CSS Modules, you'll get:
|
|
89
|
-
|
|
90
|
-
```
|
|
91
|
-
output/
|
|
92
|
-
├── Component.jsx # React component
|
|
93
|
-
├── Component.module.css # CSS Module styles
|
|
94
|
-
└── assets/ # Downloaded images
|
|
95
|
-
├── hero-image.png
|
|
96
|
-
└── icon-close.png
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
For plain CSS mode (`--style css`):
|
|
100
|
-
|
|
101
|
-
```
|
|
102
|
-
output/
|
|
103
|
-
├── Component.jsx # React component
|
|
104
|
-
├── Component.css # Standalone CSS file
|
|
105
|
-
└── assets/
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
For Vue, a single `.vue` file with `<template>`, `<script setup>`, and `<style scoped>`.
|
|
109
|
-
|
|
110
|
-
## What Gets Generated
|
|
111
|
-
|
|
112
|
-
- Pixel-accurate layout using absolute positioning
|
|
113
|
-
- Responsive scaling — auto-fits viewport width, no horizontal scrollbar
|
|
114
|
-
- Full typography (font family, size, weight, line-height, letter-spacing, color)
|
|
115
|
-
- Images exported at 2x resolution for retina displays
|
|
116
|
-
- Vector icons auto-detected and exported as PNG
|
|
117
|
-
- Hidden layers and mask shapes filtered out
|
|
118
|
-
- CSS Modules with scoped class names
|
|
119
|
-
|
|
120
|
-
## CLI Reference
|
|
121
|
-
|
|
122
|
-
| Option | Description | Default |
|
|
123
|
-
|--------|-------------|---------|
|
|
124
|
-
| `--token <token>` | Figma API token (or `FIGMA_TOKEN` env) | — |
|
|
125
|
-
| `--file <key>` | Figma file key | — |
|
|
126
|
-
| `--node <id>` | Target node ID | root |
|
|
127
|
-
| `--framework` | `react` or `vue` | `react` |
|
|
128
|
-
| `--style` | `css-modules`, `tailwind`, or `css` | `css-modules` |
|
|
129
|
-
| `--typescript` | Enable TypeScript output | `false` |
|
|
130
|
-
| `--output <dir>` | Output directory | `./output` |
|
|
131
|
-
| `--extract-tokens <fmt>` | Extract design tokens: `css`, `scss`, `json`, `js` | — |
|
|
132
|
-
| `--preview` | Preview in browser after generation | — |
|
|
133
|
-
|
|
134
|
-
## AI Enhancements (Optional)
|
|
135
|
-
|
|
136
|
-
For smarter component naming and code optimization, add an LLM provider:
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
# AWS Bedrock
|
|
140
|
-
npx figma-to-code-agent \
|
|
141
|
-
--token YOUR_FIGMA_TOKEN \
|
|
142
|
-
--file ABC123DEF456 \
|
|
143
|
-
--framework react \
|
|
144
|
-
--llm-provider bedrock \
|
|
145
|
-
--llm-model anthropic.claude-3-5-sonnet-20241022-v2:0 \
|
|
146
|
-
--ai-naming \
|
|
147
|
-
--output ./output
|
|
148
|
-
|
|
149
|
-
# OpenAI
|
|
150
|
-
LLM_API_KEY="sk-..." npx figma-to-code-agent \
|
|
151
|
-
--token YOUR_FIGMA_TOKEN \
|
|
152
|
-
--file ABC123DEF456 \
|
|
153
|
-
--framework react \
|
|
154
|
-
--llm-provider openai \
|
|
155
|
-
--llm-model gpt-4o \
|
|
156
|
-
--ai-naming \
|
|
157
|
-
--output ./output
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
| AI Option | What It Does |
|
|
161
|
-
|-----------|-------------|
|
|
162
|
-
| `--ai-naming` | Renames `Frame123` → `UserProfileCard` |
|
|
163
|
-
| `--ai-splitting` | Splits large designs into sub-components |
|
|
164
|
-
| `--ai-optimization` | Improves code quality and accessibility |
|
|
165
|
-
|
|
166
|
-
## Troubleshooting
|
|
167
|
-
|
|
168
|
-
**"Figma token is required"**
|
|
169
|
-
Set `--token` or `export FIGMA_TOKEN="your-token"`
|
|
170
|
-
|
|
171
|
-
**"Rate limited" / 429 errors**
|
|
172
|
-
The tool auto-retries with backoff. If persistent, wait a minute and try again. Downloaded images are cached locally to avoid repeated API calls.
|
|
173
|
-
|
|
174
|
-
**Images not showing**
|
|
175
|
-
Check that the `assets/` folder was generated alongside your component. Image paths are relative imports.
|
|
176
|
-
|
|
177
|
-
**Preview not working**
|
|
178
|
-
The `--preview` flag requires the built-in test-app. If installed globally, it should work out of the box. If using npx, the test-app is included in the package.
|