create-stylus-ide 1.0.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/Readme.MD +1515 -0
- package/cli.js +28 -0
- package/frontend/.vscode/settings.json +9 -0
- package/frontend/app/api/chat/route.ts +101 -0
- package/frontend/app/api/check-setup/route.ts +93 -0
- package/frontend/app/api/cleanup/route.ts +14 -0
- package/frontend/app/api/compile/route.ts +95 -0
- package/frontend/app/api/compile-stream/route.ts +98 -0
- package/frontend/app/api/complete/route.ts +86 -0
- package/frontend/app/api/deploy/route.ts +118 -0
- package/frontend/app/api/export-abi/route.ts +58 -0
- package/frontend/app/favicon.ico +0 -0
- package/frontend/app/globals.css +177 -0
- package/frontend/app/layout.tsx +29 -0
- package/frontend/app/ml/page.tsx +694 -0
- package/frontend/app/page.tsx +1132 -0
- package/frontend/app/providers.tsx +18 -0
- package/frontend/app/qlearning/page.tsx +188 -0
- package/frontend/app/raytracing/page.tsx +268 -0
- package/frontend/components/abi/ABIDialog.tsx +132 -0
- package/frontend/components/ai/AICompletionPopup.tsx +76 -0
- package/frontend/components/ai/ChatPanel.tsx +292 -0
- package/frontend/components/ai/QuickActions.tsx +128 -0
- package/frontend/components/blockchain/BlockchainContractBanner.tsx +64 -0
- package/frontend/components/blockchain/BlockchainLoadingDialog.tsx +188 -0
- package/frontend/components/deploy/DeployDialog.tsx +334 -0
- package/frontend/components/editor/FileTabs.tsx +181 -0
- package/frontend/components/editor/MonacoEditor.tsx +306 -0
- package/frontend/components/file-tree/ContextMenu.tsx +110 -0
- package/frontend/components/file-tree/DeleteConfirmDialog.tsx +61 -0
- package/frontend/components/file-tree/FileInputDialog.tsx +97 -0
- package/frontend/components/file-tree/FileNode.tsx +60 -0
- package/frontend/components/file-tree/FileTree.tsx +259 -0
- package/frontend/components/file-tree/FileTreeSkeleton.tsx +26 -0
- package/frontend/components/file-tree/FolderNode.tsx +105 -0
- package/frontend/components/github/GitHubLoadingDialog.tsx +201 -0
- package/frontend/components/github/GitHubMetadataBanner.tsx +61 -0
- package/frontend/components/github/LoadFromGitHubDialog.tsx +125 -0
- package/frontend/components/github/URLCopyButton.tsx +60 -0
- package/frontend/components/interact/ContractInteraction.tsx +323 -0
- package/frontend/components/interact/ContractPlaceholder.tsx +41 -0
- package/frontend/components/orbit/BenchmarkDialog.tsx +342 -0
- package/frontend/components/orbit/OrbitExplorer.tsx +273 -0
- package/frontend/components/project/ProjectActions.tsx +176 -0
- package/frontend/components/q-learning/ContractConfig.tsx +172 -0
- package/frontend/components/q-learning/MazeGrid.tsx +346 -0
- package/frontend/components/q-learning/PathAnimation.tsx +384 -0
- package/frontend/components/q-learning/QTableHeatmap.tsx +300 -0
- package/frontend/components/q-learning/TrainingForm.tsx +349 -0
- package/frontend/components/ray-tracing/ContractConfig.tsx +245 -0
- package/frontend/components/ray-tracing/MintingForm.tsx +280 -0
- package/frontend/components/ray-tracing/RenderCanvas.tsx +228 -0
- package/frontend/components/ray-tracing/RenderingPanel.tsx +259 -0
- package/frontend/components/ray-tracing/StyleControls.tsx +217 -0
- package/frontend/components/setup/SetupGuide.tsx +290 -0
- package/frontend/components/ui/KeyboardShortcutHint.tsx +74 -0
- package/frontend/components/ui/alert-dialog.tsx +157 -0
- package/frontend/components/ui/alert.tsx +66 -0
- package/frontend/components/ui/badge.tsx +46 -0
- package/frontend/components/ui/button.tsx +62 -0
- package/frontend/components/ui/card.tsx +92 -0
- package/frontend/components/ui/context-menu.tsx +252 -0
- package/frontend/components/ui/dialog.tsx +143 -0
- package/frontend/components/ui/dropdown-menu.tsx +257 -0
- package/frontend/components/ui/input.tsx +21 -0
- package/frontend/components/ui/label.tsx +24 -0
- package/frontend/components/ui/progress.tsx +31 -0
- package/frontend/components/ui/scroll-area.tsx +58 -0
- package/frontend/components/ui/select.tsx +190 -0
- package/frontend/components/ui/separator.tsx +28 -0
- package/frontend/components/ui/sheet.tsx +139 -0
- package/frontend/components/ui/skeleton.tsx +13 -0
- package/frontend/components/ui/slider.tsx +63 -0
- package/frontend/components/ui/sonner.tsx +40 -0
- package/frontend/components/ui/tabs.tsx +66 -0
- package/frontend/components/ui/textarea.tsx +18 -0
- package/frontend/components/wallet/ConnectButton.tsx +167 -0
- package/frontend/components/wallet/FaucetButton.tsx +256 -0
- package/frontend/components.json +22 -0
- package/frontend/eslint.config.mjs +18 -0
- package/frontend/hooks/useAICompletion.ts +75 -0
- package/frontend/hooks/useBlockchainLoader.ts +58 -0
- package/frontend/hooks/useChats.ts +137 -0
- package/frontend/hooks/useCompilation.ts +173 -0
- package/frontend/hooks/useFileTabs.ts +178 -0
- package/frontend/hooks/useGitHubLoader.ts +50 -0
- package/frontend/hooks/useKeyboardShortcuts.ts +47 -0
- package/frontend/hooks/usePanelState.ts +115 -0
- package/frontend/hooks/useProjectState.ts +276 -0
- package/frontend/hooks/useResponsive.ts +29 -0
- package/frontend/lib/abi-parser.ts +58 -0
- package/frontend/lib/blockchain-api.ts +374 -0
- package/frontend/lib/blockchain-explorers.ts +75 -0
- package/frontend/lib/blockchain-loader.ts +112 -0
- package/frontend/lib/cargo-template.ts +64 -0
- package/frontend/lib/compilation.ts +529 -0
- package/frontend/lib/constants.ts +31 -0
- package/frontend/lib/deployment.ts +176 -0
- package/frontend/lib/file-utils.ts +83 -0
- package/frontend/lib/github-api.ts +246 -0
- package/frontend/lib/github-loader.ts +369 -0
- package/frontend/lib/ml-contract-template.txt +900 -0
- package/frontend/lib/orbit-chains.ts +181 -0
- package/frontend/lib/output-formatter.ts +68 -0
- package/frontend/lib/project-manager.ts +632 -0
- package/frontend/lib/ray-tracing-abi.ts +206 -0
- package/frontend/lib/storage.ts +189 -0
- package/frontend/lib/templates.ts +1662 -0
- package/frontend/lib/url-parser.ts +188 -0
- package/frontend/lib/utils.ts +6 -0
- package/frontend/lib/wagmi-config.ts +24 -0
- package/frontend/next.config.ts +7 -0
- package/frontend/package-lock.json +16259 -0
- package/frontend/package.json +60 -0
- package/frontend/postcss.config.mjs +7 -0
- package/frontend/public/file.svg +1 -0
- package/frontend/public/globe.svg +1 -0
- package/frontend/public/ml-weights/.gitkeep +0 -0
- package/frontend/public/ml-weights/model.pkl +0 -0
- package/frontend/public/ml-weights/model_weights.json +27102 -0
- package/frontend/public/ml-weights/test_samples.json +7888 -0
- package/frontend/public/next.svg +1 -0
- package/frontend/public/vercel.svg +1 -0
- package/frontend/public/window.svg +1 -0
- package/frontend/scripts/check-env.js +52 -0
- package/frontend/scripts/setup.js +285 -0
- package/frontend/tailwind.config.ts +64 -0
- package/frontend/tsconfig.json +34 -0
- package/frontend/types/blockchain.ts +63 -0
- package/frontend/types/github.ts +54 -0
- package/frontend/types/project.ts +106 -0
- package/ml-training/README.md +56 -0
- package/ml-training/train_tiny_model.py +325 -0
- package/ml-training/update_template.py +59 -0
- package/package.json +30 -0
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub repository loader - converts GitHub repos to ProjectState
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { ProjectState, ProjectFile } from "@/types/project";
|
|
6
|
+
import { GitHubURLInfo } from "@/lib/url-parser";
|
|
7
|
+
import { githubAPI } from "@/lib/github-api";
|
|
8
|
+
import { createProject } from "@/lib/project-manager";
|
|
9
|
+
import { GitHubFile } from "@/types/github";
|
|
10
|
+
|
|
11
|
+
export interface GitHubLoadProgress {
|
|
12
|
+
stage:
|
|
13
|
+
| "validating"
|
|
14
|
+
| "fetching-tree"
|
|
15
|
+
| "downloading-files"
|
|
16
|
+
| "complete"
|
|
17
|
+
| "error";
|
|
18
|
+
message: string;
|
|
19
|
+
progress: number; // 0-100
|
|
20
|
+
filesTotal?: number;
|
|
21
|
+
filesDownloaded?: number;
|
|
22
|
+
currentFile?: string;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Filter files to only include those in a specific folder
|
|
27
|
+
*/
|
|
28
|
+
function filterFilesByPath(
|
|
29
|
+
files: GitHubFile[], // ✅ CHANGE: was { path: string }[]
|
|
30
|
+
folderPath: string
|
|
31
|
+
): GitHubFile[] {
|
|
32
|
+
// ✅ CHANGE: was { path: string }[]
|
|
33
|
+
// Normalize folder path (remove trailing slash)
|
|
34
|
+
const normalizedPath = folderPath.endsWith("/")
|
|
35
|
+
? folderPath.slice(0, -1)
|
|
36
|
+
: folderPath;
|
|
37
|
+
|
|
38
|
+
return files.filter((file) => {
|
|
39
|
+
// File must start with the folder path
|
|
40
|
+
if (!file.path.startsWith(normalizedPath + "/")) {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Strip folder prefix from file paths
|
|
49
|
+
* Example: "src/lib.rs" with prefix "src" becomes "lib.rs"
|
|
50
|
+
*/
|
|
51
|
+
function stripPathPrefix(path: string, prefix: string): string {
|
|
52
|
+
const normalizedPrefix = prefix.endsWith("/") ? prefix : prefix + "/";
|
|
53
|
+
|
|
54
|
+
if (path.startsWith(normalizedPrefix)) {
|
|
55
|
+
return path.substring(normalizedPrefix.length);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return path;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Validate if repository has Rust/Stylus files
|
|
63
|
+
*/
|
|
64
|
+
function validateStylusRepo(files: { path: string }[]): {
|
|
65
|
+
isValid: boolean;
|
|
66
|
+
hasRust: boolean;
|
|
67
|
+
hasCargo: boolean;
|
|
68
|
+
warnings: string[];
|
|
69
|
+
} {
|
|
70
|
+
const hasRust = files.some((f) => f.path.endsWith(".rs"));
|
|
71
|
+
const hasCargo = files.some(
|
|
72
|
+
(f) => f.path === "Cargo.toml" || f.path.endsWith("/Cargo.toml")
|
|
73
|
+
);
|
|
74
|
+
const warnings: string[] = [];
|
|
75
|
+
|
|
76
|
+
if (!hasRust) {
|
|
77
|
+
warnings.push("No Rust files (.rs) found in repository");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (!hasCargo) {
|
|
81
|
+
warnings.push("No Cargo.toml found - this may not be a valid Rust project");
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Check for common non-Rust repos
|
|
85
|
+
const hasPackageJson = files.some((f) => f.path === "package.json");
|
|
86
|
+
const hasPyFiles = files.some((f) => f.path.endsWith(".py"));
|
|
87
|
+
const hasGoFiles = files.some((f) => f.path.endsWith(".go"));
|
|
88
|
+
|
|
89
|
+
if (hasPackageJson && !hasRust) {
|
|
90
|
+
warnings.push(
|
|
91
|
+
"This appears to be a JavaScript/TypeScript project, not Rust"
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
if (hasPyFiles && !hasRust) {
|
|
95
|
+
warnings.push("This appears to be a Python project, not Rust");
|
|
96
|
+
}
|
|
97
|
+
if (hasGoFiles && !hasRust) {
|
|
98
|
+
warnings.push("This appears to be a Go project, not Rust");
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
isValid: hasRust,
|
|
103
|
+
hasRust,
|
|
104
|
+
hasCargo,
|
|
105
|
+
warnings,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export type ProgressCallback = (progress: GitHubLoadProgress) => void;
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Load GitHub repository and convert to ProjectState
|
|
113
|
+
*/
|
|
114
|
+
export async function loadGitHubRepo(
|
|
115
|
+
urlInfo: GitHubURLInfo,
|
|
116
|
+
onProgress?: ProgressCallback
|
|
117
|
+
): Promise<ProjectState> {
|
|
118
|
+
const { owner, repo, branch, file } = urlInfo;
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
// Stage 1: Validate repository
|
|
122
|
+
onProgress?.({
|
|
123
|
+
stage: "validating",
|
|
124
|
+
message: `Checking repository ${owner}/${repo}...`,
|
|
125
|
+
progress: 10,
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const repoInfo = await githubAPI.getRepo(owner, repo);
|
|
129
|
+
const targetBranch = branch || repoInfo.default_branch;
|
|
130
|
+
|
|
131
|
+
// Check if specific branch exists
|
|
132
|
+
if (branch && branch !== repoInfo.default_branch) {
|
|
133
|
+
const branchExists = await githubAPI.branchExists(owner, repo, branch);
|
|
134
|
+
if (!branchExists) {
|
|
135
|
+
throw new Error(
|
|
136
|
+
`Branch "${branch}" not found. Available branch: ${repoInfo.default_branch}`
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Stage 2: Fetch repository tree
|
|
142
|
+
onProgress?.({
|
|
143
|
+
stage: "fetching-tree",
|
|
144
|
+
message: "Fetching repository structure...",
|
|
145
|
+
progress: 30,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const tree = await githubAPI.getRepoTree(owner, repo, targetBranch);
|
|
149
|
+
|
|
150
|
+
// Check if repo is empty
|
|
151
|
+
if (tree.tree.length === 0) {
|
|
152
|
+
throw new Error("Repository is empty. No files found.");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Validate it's a Rust/Stylus project
|
|
156
|
+
const validation = validateStylusRepo(tree.tree);
|
|
157
|
+
|
|
158
|
+
if (!validation.isValid) {
|
|
159
|
+
throw new Error(
|
|
160
|
+
`Not a valid Stylus project:\n${validation.warnings.join("\n")}`
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Show warnings but continue
|
|
165
|
+
if (validation.warnings.length > 0) {
|
|
166
|
+
console.warn("Repository warnings:", validation.warnings);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// Filter for relevant files only (Rust, TOML, MD, etc.)
|
|
170
|
+
let relevantFiles = tree.tree.filter((item) => {
|
|
171
|
+
if (item.type !== "blob") return false;
|
|
172
|
+
|
|
173
|
+
const ext = item.path.split(".").pop()?.toLowerCase();
|
|
174
|
+
return ["rs", "toml", "md", "txt", "lock", "gitignore"].includes(
|
|
175
|
+
ext || ""
|
|
176
|
+
);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// ✅ NEW: Filter by folder path if specified
|
|
180
|
+
if (urlInfo.path) {
|
|
181
|
+
const beforeFilter = relevantFiles.length;
|
|
182
|
+
relevantFiles = filterFilesByPath(relevantFiles, urlInfo.path);
|
|
183
|
+
|
|
184
|
+
console.log(
|
|
185
|
+
`Filtered to folder "${urlInfo.path}": ${beforeFilter} → ${relevantFiles.length} files`
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
if (relevantFiles.length === 0) {
|
|
189
|
+
throw new Error(`No files found in folder "${urlInfo.path}"`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
if (relevantFiles.length === 0) {
|
|
194
|
+
throw new Error("No Rust or configuration files found in repository");
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Stage 3: Download files
|
|
198
|
+
onProgress?.({
|
|
199
|
+
stage: "downloading-files",
|
|
200
|
+
message: `Downloading ${relevantFiles.length} files...`,
|
|
201
|
+
progress: 50,
|
|
202
|
+
filesTotal: relevantFiles.length,
|
|
203
|
+
filesDownloaded: 0,
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
const files: ProjectFile[] = [];
|
|
207
|
+
const failedFiles: string[] = [];
|
|
208
|
+
let downloadedCount = 0;
|
|
209
|
+
|
|
210
|
+
for (const item of relevantFiles) {
|
|
211
|
+
try {
|
|
212
|
+
onProgress?.({
|
|
213
|
+
stage: "downloading-files",
|
|
214
|
+
message: `Downloading ${item.path}...`,
|
|
215
|
+
progress: 50 + (downloadedCount / relevantFiles.length) * 40,
|
|
216
|
+
filesTotal: relevantFiles.length,
|
|
217
|
+
filesDownloaded: downloadedCount,
|
|
218
|
+
currentFile: item.path,
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
// Use raw content API (faster and no base64 decoding needed)
|
|
222
|
+
const content = await githubAPI.getRawFileContent(
|
|
223
|
+
owner,
|
|
224
|
+
repo,
|
|
225
|
+
item.path,
|
|
226
|
+
targetBranch
|
|
227
|
+
);
|
|
228
|
+
|
|
229
|
+
// Determine language from extension
|
|
230
|
+
const ext = item.path.split(".").pop()?.toLowerCase() || "text";
|
|
231
|
+
const languageMap: Record<string, ProjectFile["language"]> = {
|
|
232
|
+
rs: "rust",
|
|
233
|
+
toml: "toml",
|
|
234
|
+
md: "markdown",
|
|
235
|
+
txt: "text",
|
|
236
|
+
lock: "text",
|
|
237
|
+
gitignore: "gitignore",
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
// ✅ NEW: Strip folder prefix if loading specific folder
|
|
241
|
+
const displayPath = urlInfo.path
|
|
242
|
+
? stripPathPrefix(item.path, urlInfo.path)
|
|
243
|
+
: item.path;
|
|
244
|
+
|
|
245
|
+
files.push({
|
|
246
|
+
id: `github-${item.sha}`,
|
|
247
|
+
name: displayPath.split("/").pop() || displayPath,
|
|
248
|
+
path: displayPath, // Use stripped path
|
|
249
|
+
content,
|
|
250
|
+
language: languageMap[ext] || "text",
|
|
251
|
+
modified: false,
|
|
252
|
+
isOpen: false,
|
|
253
|
+
createdAt: new Date(),
|
|
254
|
+
updatedAt: new Date(),
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
downloadedCount++;
|
|
258
|
+
} catch (error) {
|
|
259
|
+
console.warn(`Failed to download ${item.path}:`, error);
|
|
260
|
+
failedFiles.push(item.path);
|
|
261
|
+
// Continue with other files
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
if (files.length === 0) {
|
|
266
|
+
throw new Error("Failed to download any files from repository");
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Warn about failed files
|
|
270
|
+
if (failedFiles.length > 0) {
|
|
271
|
+
console.warn(
|
|
272
|
+
`Failed to download ${failedFiles.length} files:`,
|
|
273
|
+
failedFiles
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Stage 4: Create project
|
|
278
|
+
onProgress?.({
|
|
279
|
+
stage: "complete",
|
|
280
|
+
message: "Building project...",
|
|
281
|
+
progress: 95,
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
// Create project from files
|
|
285
|
+
const project = createProject(`${owner}-${repo}`, "github");
|
|
286
|
+
|
|
287
|
+
// Replace default files with GitHub files
|
|
288
|
+
project.files = files;
|
|
289
|
+
|
|
290
|
+
// If specific file was requested, mark it as active
|
|
291
|
+
if (file) {
|
|
292
|
+
const targetFile = files.find((f) => f.path === file);
|
|
293
|
+
if (targetFile) {
|
|
294
|
+
targetFile.isOpen = true;
|
|
295
|
+
project.activeFilePath = targetFile.path;
|
|
296
|
+
} else {
|
|
297
|
+
console.warn(`Requested file "${file}" not found in repository`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
// If no file specified or file not found, open first .rs file by default
|
|
302
|
+
if (!project.activeFilePath) {
|
|
303
|
+
const firstRustFile = files.find((f) => f.language === "rust");
|
|
304
|
+
if (firstRustFile) {
|
|
305
|
+
firstRustFile.isOpen = true;
|
|
306
|
+
project.activeFilePath = firstRustFile.path;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// Update project metadata
|
|
311
|
+
project.name = urlInfo.path ? `${repo}/${urlInfo.path}` : repo;
|
|
312
|
+
project.metadata = {
|
|
313
|
+
source: "github",
|
|
314
|
+
owner,
|
|
315
|
+
repo,
|
|
316
|
+
branch: targetBranch,
|
|
317
|
+
url: urlInfo.rawUrl,
|
|
318
|
+
loadedAt: new Date().toISOString(),
|
|
319
|
+
folderPath: urlInfo.path, // ✅ NEW: Track loaded folder
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
onProgress?.({
|
|
323
|
+
stage: "complete",
|
|
324
|
+
message: `Loaded ${files.length} files from ${owner}/${repo}${
|
|
325
|
+
failedFiles.length > 0 ? ` (${failedFiles.length} files skipped)` : ""
|
|
326
|
+
}`,
|
|
327
|
+
progress: 100,
|
|
328
|
+
filesTotal: files.length,
|
|
329
|
+
filesDownloaded: files.length,
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
return project;
|
|
333
|
+
} catch (error) {
|
|
334
|
+
let errorMessage = "Unknown error occurred";
|
|
335
|
+
|
|
336
|
+
if (error instanceof Error) {
|
|
337
|
+
errorMessage = error.message;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
onProgress?.({
|
|
341
|
+
stage: "error",
|
|
342
|
+
message: errorMessage,
|
|
343
|
+
progress: 0,
|
|
344
|
+
});
|
|
345
|
+
|
|
346
|
+
throw error;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Validate if repository is suitable for Stylus IDE
|
|
352
|
+
*/
|
|
353
|
+
export function validateGitHubRepo(tree: { path: string }[]): {
|
|
354
|
+
isValid: boolean;
|
|
355
|
+
reason?: string;
|
|
356
|
+
} {
|
|
357
|
+
const hasRustFiles = tree.some((item) => item.path.endsWith(".rs"));
|
|
358
|
+
const hasCargoToml = tree.some((item) => item.path === "Cargo.toml");
|
|
359
|
+
|
|
360
|
+
if (!hasRustFiles) {
|
|
361
|
+
return { isValid: false, reason: "No Rust files found" };
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
if (!hasCargoToml) {
|
|
365
|
+
return { isValid: false, reason: "No Cargo.toml found" };
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
return { isValid: true };
|
|
369
|
+
}
|