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.
Files changed (135) hide show
  1. package/Readme.MD +1515 -0
  2. package/cli.js +28 -0
  3. package/frontend/.vscode/settings.json +9 -0
  4. package/frontend/app/api/chat/route.ts +101 -0
  5. package/frontend/app/api/check-setup/route.ts +93 -0
  6. package/frontend/app/api/cleanup/route.ts +14 -0
  7. package/frontend/app/api/compile/route.ts +95 -0
  8. package/frontend/app/api/compile-stream/route.ts +98 -0
  9. package/frontend/app/api/complete/route.ts +86 -0
  10. package/frontend/app/api/deploy/route.ts +118 -0
  11. package/frontend/app/api/export-abi/route.ts +58 -0
  12. package/frontend/app/favicon.ico +0 -0
  13. package/frontend/app/globals.css +177 -0
  14. package/frontend/app/layout.tsx +29 -0
  15. package/frontend/app/ml/page.tsx +694 -0
  16. package/frontend/app/page.tsx +1132 -0
  17. package/frontend/app/providers.tsx +18 -0
  18. package/frontend/app/qlearning/page.tsx +188 -0
  19. package/frontend/app/raytracing/page.tsx +268 -0
  20. package/frontend/components/abi/ABIDialog.tsx +132 -0
  21. package/frontend/components/ai/AICompletionPopup.tsx +76 -0
  22. package/frontend/components/ai/ChatPanel.tsx +292 -0
  23. package/frontend/components/ai/QuickActions.tsx +128 -0
  24. package/frontend/components/blockchain/BlockchainContractBanner.tsx +64 -0
  25. package/frontend/components/blockchain/BlockchainLoadingDialog.tsx +188 -0
  26. package/frontend/components/deploy/DeployDialog.tsx +334 -0
  27. package/frontend/components/editor/FileTabs.tsx +181 -0
  28. package/frontend/components/editor/MonacoEditor.tsx +306 -0
  29. package/frontend/components/file-tree/ContextMenu.tsx +110 -0
  30. package/frontend/components/file-tree/DeleteConfirmDialog.tsx +61 -0
  31. package/frontend/components/file-tree/FileInputDialog.tsx +97 -0
  32. package/frontend/components/file-tree/FileNode.tsx +60 -0
  33. package/frontend/components/file-tree/FileTree.tsx +259 -0
  34. package/frontend/components/file-tree/FileTreeSkeleton.tsx +26 -0
  35. package/frontend/components/file-tree/FolderNode.tsx +105 -0
  36. package/frontend/components/github/GitHubLoadingDialog.tsx +201 -0
  37. package/frontend/components/github/GitHubMetadataBanner.tsx +61 -0
  38. package/frontend/components/github/LoadFromGitHubDialog.tsx +125 -0
  39. package/frontend/components/github/URLCopyButton.tsx +60 -0
  40. package/frontend/components/interact/ContractInteraction.tsx +323 -0
  41. package/frontend/components/interact/ContractPlaceholder.tsx +41 -0
  42. package/frontend/components/orbit/BenchmarkDialog.tsx +342 -0
  43. package/frontend/components/orbit/OrbitExplorer.tsx +273 -0
  44. package/frontend/components/project/ProjectActions.tsx +176 -0
  45. package/frontend/components/q-learning/ContractConfig.tsx +172 -0
  46. package/frontend/components/q-learning/MazeGrid.tsx +346 -0
  47. package/frontend/components/q-learning/PathAnimation.tsx +384 -0
  48. package/frontend/components/q-learning/QTableHeatmap.tsx +300 -0
  49. package/frontend/components/q-learning/TrainingForm.tsx +349 -0
  50. package/frontend/components/ray-tracing/ContractConfig.tsx +245 -0
  51. package/frontend/components/ray-tracing/MintingForm.tsx +280 -0
  52. package/frontend/components/ray-tracing/RenderCanvas.tsx +228 -0
  53. package/frontend/components/ray-tracing/RenderingPanel.tsx +259 -0
  54. package/frontend/components/ray-tracing/StyleControls.tsx +217 -0
  55. package/frontend/components/setup/SetupGuide.tsx +290 -0
  56. package/frontend/components/ui/KeyboardShortcutHint.tsx +74 -0
  57. package/frontend/components/ui/alert-dialog.tsx +157 -0
  58. package/frontend/components/ui/alert.tsx +66 -0
  59. package/frontend/components/ui/badge.tsx +46 -0
  60. package/frontend/components/ui/button.tsx +62 -0
  61. package/frontend/components/ui/card.tsx +92 -0
  62. package/frontend/components/ui/context-menu.tsx +252 -0
  63. package/frontend/components/ui/dialog.tsx +143 -0
  64. package/frontend/components/ui/dropdown-menu.tsx +257 -0
  65. package/frontend/components/ui/input.tsx +21 -0
  66. package/frontend/components/ui/label.tsx +24 -0
  67. package/frontend/components/ui/progress.tsx +31 -0
  68. package/frontend/components/ui/scroll-area.tsx +58 -0
  69. package/frontend/components/ui/select.tsx +190 -0
  70. package/frontend/components/ui/separator.tsx +28 -0
  71. package/frontend/components/ui/sheet.tsx +139 -0
  72. package/frontend/components/ui/skeleton.tsx +13 -0
  73. package/frontend/components/ui/slider.tsx +63 -0
  74. package/frontend/components/ui/sonner.tsx +40 -0
  75. package/frontend/components/ui/tabs.tsx +66 -0
  76. package/frontend/components/ui/textarea.tsx +18 -0
  77. package/frontend/components/wallet/ConnectButton.tsx +167 -0
  78. package/frontend/components/wallet/FaucetButton.tsx +256 -0
  79. package/frontend/components.json +22 -0
  80. package/frontend/eslint.config.mjs +18 -0
  81. package/frontend/hooks/useAICompletion.ts +75 -0
  82. package/frontend/hooks/useBlockchainLoader.ts +58 -0
  83. package/frontend/hooks/useChats.ts +137 -0
  84. package/frontend/hooks/useCompilation.ts +173 -0
  85. package/frontend/hooks/useFileTabs.ts +178 -0
  86. package/frontend/hooks/useGitHubLoader.ts +50 -0
  87. package/frontend/hooks/useKeyboardShortcuts.ts +47 -0
  88. package/frontend/hooks/usePanelState.ts +115 -0
  89. package/frontend/hooks/useProjectState.ts +276 -0
  90. package/frontend/hooks/useResponsive.ts +29 -0
  91. package/frontend/lib/abi-parser.ts +58 -0
  92. package/frontend/lib/blockchain-api.ts +374 -0
  93. package/frontend/lib/blockchain-explorers.ts +75 -0
  94. package/frontend/lib/blockchain-loader.ts +112 -0
  95. package/frontend/lib/cargo-template.ts +64 -0
  96. package/frontend/lib/compilation.ts +529 -0
  97. package/frontend/lib/constants.ts +31 -0
  98. package/frontend/lib/deployment.ts +176 -0
  99. package/frontend/lib/file-utils.ts +83 -0
  100. package/frontend/lib/github-api.ts +246 -0
  101. package/frontend/lib/github-loader.ts +369 -0
  102. package/frontend/lib/ml-contract-template.txt +900 -0
  103. package/frontend/lib/orbit-chains.ts +181 -0
  104. package/frontend/lib/output-formatter.ts +68 -0
  105. package/frontend/lib/project-manager.ts +632 -0
  106. package/frontend/lib/ray-tracing-abi.ts +206 -0
  107. package/frontend/lib/storage.ts +189 -0
  108. package/frontend/lib/templates.ts +1662 -0
  109. package/frontend/lib/url-parser.ts +188 -0
  110. package/frontend/lib/utils.ts +6 -0
  111. package/frontend/lib/wagmi-config.ts +24 -0
  112. package/frontend/next.config.ts +7 -0
  113. package/frontend/package-lock.json +16259 -0
  114. package/frontend/package.json +60 -0
  115. package/frontend/postcss.config.mjs +7 -0
  116. package/frontend/public/file.svg +1 -0
  117. package/frontend/public/globe.svg +1 -0
  118. package/frontend/public/ml-weights/.gitkeep +0 -0
  119. package/frontend/public/ml-weights/model.pkl +0 -0
  120. package/frontend/public/ml-weights/model_weights.json +27102 -0
  121. package/frontend/public/ml-weights/test_samples.json +7888 -0
  122. package/frontend/public/next.svg +1 -0
  123. package/frontend/public/vercel.svg +1 -0
  124. package/frontend/public/window.svg +1 -0
  125. package/frontend/scripts/check-env.js +52 -0
  126. package/frontend/scripts/setup.js +285 -0
  127. package/frontend/tailwind.config.ts +64 -0
  128. package/frontend/tsconfig.json +34 -0
  129. package/frontend/types/blockchain.ts +63 -0
  130. package/frontend/types/github.ts +54 -0
  131. package/frontend/types/project.ts +106 -0
  132. package/ml-training/README.md +56 -0
  133. package/ml-training/train_tiny_model.py +325 -0
  134. package/ml-training/update_template.py +59 -0
  135. package/package.json +30 -0
@@ -0,0 +1,276 @@
1
+ "use client";
2
+
3
+ import { useState, useCallback, useEffect, useRef } from "react";
4
+ import { ProjectState, FileNode } from "@/types/project";
5
+ import {
6
+ createProject,
7
+ addFile,
8
+ addFolder,
9
+ deleteFile,
10
+ deleteFolder,
11
+ renameFile,
12
+ updateFileContent,
13
+ setActiveFile,
14
+ toggleFileOpen,
15
+ getFileByPath,
16
+ } from "@/lib/project-manager";
17
+ import { saveProject, loadProject } from "@/lib/storage";
18
+
19
+ export function useProjectState(initialName: string = "my-stylus-project") {
20
+ // ✅ FIXED: Always start with default project (server + client match)
21
+ const [project, setProject] = useState<ProjectState>(() =>
22
+ createProject(initialName)
23
+ );
24
+
25
+ // ✅ FIXED: Track if we've loaded from localStorage
26
+ const [isHydrated, setIsHydrated] = useState(false);
27
+
28
+ // ✅ FIXED: Load from localStorage AFTER mount (client-only)
29
+ useEffect(() => {
30
+ if (typeof window !== "undefined" && !isHydrated) {
31
+ const savedProject = loadProject();
32
+ if (savedProject) {
33
+ setProject(savedProject);
34
+ }
35
+ setIsHydrated(true);
36
+ }
37
+ }, [isHydrated]);
38
+
39
+ // Auto-save timer refs
40
+ const saveTimerRef = useRef<NodeJS.Timeout | null>(null);
41
+ const lastSaveRef = useRef<string>("");
42
+
43
+ // ✅ FIXED: Auto-save only after hydration
44
+ useEffect(() => {
45
+ // Skip if running on server OR not hydrated yet
46
+ if (typeof window === "undefined" || !isHydrated) return;
47
+
48
+ // Serialize project for comparison
49
+ const projectSnapshot = JSON.stringify(project);
50
+
51
+ // Only save if project actually changed
52
+ if (projectSnapshot !== lastSaveRef.current) {
53
+ // Clear existing timer
54
+ if (saveTimerRef.current) {
55
+ clearTimeout(saveTimerRef.current);
56
+ }
57
+
58
+ // Set new timer (debounce for 2 seconds)
59
+ saveTimerRef.current = setTimeout(() => {
60
+ saveProject(project);
61
+ lastSaveRef.current = projectSnapshot;
62
+ console.log("Project auto-saved");
63
+ }, 2000);
64
+ }
65
+
66
+ // Cleanup on unmount
67
+ return () => {
68
+ if (saveTimerRef.current) {
69
+ clearTimeout(saveTimerRef.current);
70
+ }
71
+ };
72
+ }, [project, isHydrated]);
73
+
74
+ // Create new file
75
+ const createNewFile = useCallback((path: string, content?: string) => {
76
+ try {
77
+ setProject((prev) => addFile(prev, { path, content }));
78
+ return true;
79
+ } catch (error) {
80
+ console.error("Failed to create file:", error);
81
+ return false;
82
+ }
83
+ }, []);
84
+
85
+ // Create new folder
86
+ const createNewFolder = useCallback((path: string) => {
87
+ try {
88
+ setProject((prev) => addFolder(prev, { path }));
89
+ return true;
90
+ } catch (error) {
91
+ console.error("Failed to create folder:", error);
92
+ return false;
93
+ }
94
+ }, []);
95
+
96
+ // Delete file
97
+ const removeFile = useCallback((path: string) => {
98
+ try {
99
+ setProject((prev) => deleteFile(prev, path));
100
+ return true;
101
+ } catch (error) {
102
+ console.error("Failed to delete file:", error);
103
+ return false;
104
+ }
105
+ }, []);
106
+
107
+ // Delete folder
108
+ const removeFolder = useCallback((path: string) => {
109
+ try {
110
+ setProject((prev) => deleteFolder(prev, path));
111
+ return true;
112
+ } catch (error) {
113
+ console.error("Failed to delete folder:", error);
114
+ return false;
115
+ }
116
+ }, []);
117
+
118
+ // Rename file/folder
119
+ const rename = useCallback((oldPath: string, newPath: string) => {
120
+ try {
121
+ setProject((prev) => renameFile(prev, { oldPath, newPath }));
122
+ return true;
123
+ } catch (error) {
124
+ console.error("Failed to rename:", error);
125
+ return false;
126
+ }
127
+ }, []);
128
+
129
+ // Update file content
130
+ const updateContent = useCallback((path: string, content: string) => {
131
+ setProject((prev) => updateFileContent(prev, path, content));
132
+ }, []);
133
+
134
+ // Set active file
135
+ const setActive = useCallback((path: string | null) => {
136
+ setProject((prev) => {
137
+ let updated = setActiveFile(prev, path);
138
+
139
+ if (path) {
140
+ updated = toggleFileOpen(updated, path, true);
141
+ }
142
+
143
+ return updated;
144
+ });
145
+ }, []);
146
+
147
+ // Close file (remove from tabs)
148
+ const closeFile = useCallback((path: string) => {
149
+ setProject((prev) => {
150
+ let updated = toggleFileOpen(prev, path, false);
151
+
152
+ if (prev.activeFilePath === path) {
153
+ updated = setActiveFile(updated, null);
154
+ }
155
+
156
+ return updated;
157
+ });
158
+ }, []);
159
+
160
+ // Toggle folder expansion
161
+ const toggleFolder = useCallback((path: string, expanded: boolean) => {
162
+ setProject((prev) => ({
163
+ ...prev,
164
+ structure: updateFolderExpansion(prev.structure, path, expanded),
165
+ }));
166
+ }, []);
167
+
168
+ // Duplicate file
169
+ const duplicateFile = useCallback((path: string) => {
170
+ try {
171
+ setProject((prev) => {
172
+ const file = getFileByPath(prev, path);
173
+ if (!file) {
174
+ console.error("File not found:", path);
175
+ return prev;
176
+ }
177
+
178
+ const pathParts = path.split("/");
179
+ const fileName = pathParts.pop()!;
180
+ const fileDir = pathParts.join("/");
181
+
182
+ const nameParts = fileName.split(".");
183
+ const ext = nameParts.length > 1 ? nameParts.pop() : "";
184
+ const baseName = nameParts.join(".");
185
+
186
+ let counter = 1;
187
+ let newName = ext ? `${baseName}_copy.${ext}` : `${baseName}_copy`;
188
+ let newPath = fileDir ? `${fileDir}/${newName}` : newName;
189
+
190
+ while (getFileByPath(prev, newPath)) {
191
+ counter++;
192
+ newName = ext
193
+ ? `${baseName}_copy${counter}.${ext}`
194
+ : `${baseName}_copy${counter}`;
195
+ newPath = fileDir ? `${fileDir}/${newName}` : newName;
196
+ }
197
+
198
+ return addFile(prev, {
199
+ path: newPath,
200
+ content: file.content,
201
+ });
202
+ });
203
+
204
+ return true;
205
+ } catch (error) {
206
+ console.error("Failed to duplicate file:", error);
207
+ return false;
208
+ }
209
+ }, []);
210
+
211
+ // Get current file content
212
+ const getCurrentFile = useCallback(() => {
213
+ if (!project.activeFilePath) return null;
214
+ return getFileByPath(project, project.activeFilePath);
215
+ }, [project]);
216
+
217
+ // Get all open files
218
+ const getOpenFiles = useCallback(() => {
219
+ return project.files.filter((f) => f.isOpen);
220
+ }, [project.files]);
221
+
222
+ // Manual save function
223
+ const manualSave = useCallback(() => {
224
+ saveProject(project);
225
+ console.log("Project manually saved");
226
+ }, [project]);
227
+
228
+ // Reset to new project
229
+ const resetProject = useCallback(() => {
230
+ const newProject = createProject(initialName);
231
+ setProject(newProject);
232
+ saveProject(newProject);
233
+ }, [initialName]);
234
+
235
+ return {
236
+ project,
237
+ setProject,
238
+ createNewFile,
239
+ createNewFolder,
240
+ removeFile,
241
+ removeFolder,
242
+ rename,
243
+ updateContent,
244
+ setActive,
245
+ closeFile,
246
+ toggleFolder,
247
+ duplicateFile,
248
+ getCurrentFile,
249
+ getOpenFiles,
250
+ manualSave,
251
+ resetProject,
252
+ isHydrated, // ✅ NEW: Export for debugging
253
+ };
254
+ }
255
+
256
+ // Helper to update folder expansion in tree
257
+ function updateFolderExpansion(
258
+ structure: FileNode[],
259
+ path: string,
260
+ expanded: boolean
261
+ ): FileNode[] {
262
+ return structure.map((node) => {
263
+ if (node.path === path && node.type === "folder") {
264
+ return { ...node, expanded };
265
+ }
266
+
267
+ if (node.type === "folder" && node.children) {
268
+ return {
269
+ ...node,
270
+ children: updateFolderExpansion(node.children, path, expanded),
271
+ };
272
+ }
273
+
274
+ return node;
275
+ });
276
+ }
@@ -0,0 +1,29 @@
1
+ 'use client';
2
+
3
+ import { useState, useEffect } from 'react';
4
+
5
+ export function useResponsive() {
6
+ const [isMobile, setIsMobile] = useState(false);
7
+ const [isTablet, setIsTablet] = useState(false);
8
+ const [isDesktop, setIsDesktop] = useState(false);
9
+
10
+ useEffect(() => {
11
+ const checkScreenSize = () => {
12
+ const width = window.innerWidth;
13
+ setIsMobile(width < 768);
14
+ setIsTablet(width >= 768 && width < 1024);
15
+ setIsDesktop(width >= 1024);
16
+ };
17
+
18
+ // Initial check
19
+ checkScreenSize();
20
+
21
+ // Add event listener
22
+ window.addEventListener('resize', checkScreenSize);
23
+
24
+ // Cleanup
25
+ return () => window.removeEventListener('resize', checkScreenSize);
26
+ }, []);
27
+
28
+ return { isMobile, isTablet, isDesktop };
29
+ }
@@ -0,0 +1,58 @@
1
+ export interface ParsedFunction {
2
+ name: string;
3
+ type: "function";
4
+ stateMutability: "view" | "pure" | "nonpayable" | "payable";
5
+ inputs: Array<{
6
+ name: string;
7
+ type: string;
8
+ internalType?: string;
9
+ }>;
10
+ outputs: Array<{
11
+ name: string;
12
+ type: string;
13
+ internalType?: string;
14
+ }>;
15
+ }
16
+
17
+ export function parseABI(abiString: string): ParsedFunction[] {
18
+ try {
19
+ const abi = JSON.parse(abiString);
20
+ return abi.filter(
21
+ (item: any) => item.type === "function"
22
+ ) as ParsedFunction[];
23
+ } catch (error) {
24
+ console.error("Failed to parse ABI:", error);
25
+ return [];
26
+ }
27
+ }
28
+
29
+ export function isReadFunction(func: ParsedFunction): boolean {
30
+ return func.stateMutability === "view" || func.stateMutability === "pure";
31
+ }
32
+
33
+ export function isWriteFunction(func: ParsedFunction): boolean {
34
+ return (
35
+ func.stateMutability === "nonpayable" || func.stateMutability === "payable"
36
+ );
37
+ }
38
+
39
+ export function groupFunctionsByType(functions: ParsedFunction[]): {
40
+ read: ParsedFunction[];
41
+ write: ParsedFunction[];
42
+ } {
43
+ return {
44
+ read: functions.filter(isReadFunction),
45
+ write: functions.filter(isWriteFunction),
46
+ };
47
+ }
48
+
49
+ export function formatFunctionSignature(func: ParsedFunction): string {
50
+ const params = func.inputs
51
+ .map((input) => `${input.type} ${input.name || ""}`)
52
+ .join(", ");
53
+ const returns =
54
+ func.outputs.length > 0
55
+ ? ` returns (${func.outputs.map((output) => output.type).join(", ")})`
56
+ : "";
57
+ return `${func.name}(${params})${returns}`;
58
+ }