jwtttt 1.6.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/index.js +128 -0
- package/package.json +16 -0
package/index.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
const fetch = require("node-fetch");
|
|
6
|
+
const yargs = require("yargs/yargs");
|
|
7
|
+
const { hideBin } = require("yargs/helpers");
|
|
8
|
+
|
|
9
|
+
const API_KEY = "AIzaSyDRz3iPghQilnCh9dpWzZU4XzKKBlf0dNI";
|
|
10
|
+
|
|
11
|
+
async function fetchWithRetry(url, options, retries = 3) {
|
|
12
|
+
try {
|
|
13
|
+
const res = await fetch(url, options);
|
|
14
|
+
if (!res.ok) throw new Error(`Status ${res.status}`);
|
|
15
|
+
return res;
|
|
16
|
+
} catch (err) {
|
|
17
|
+
if (retries === 0) throw err;
|
|
18
|
+
console.log("Gemini busy, retrying...");
|
|
19
|
+
await new Promise(r => setTimeout(r, 3000));
|
|
20
|
+
return fetchWithRetry(url, options, retries - 1);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function removeComments(code) {
|
|
25
|
+
return code
|
|
26
|
+
.replace(/\/\*[\s\S]*?\*\//g, "")
|
|
27
|
+
.replace(/\/\/.*$/gm, "")
|
|
28
|
+
.replace(/#.*$/gm, "")
|
|
29
|
+
.trim();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function safeJsonParse(text) {
|
|
33
|
+
try {
|
|
34
|
+
return JSON.parse(text);
|
|
35
|
+
} catch (err) {
|
|
36
|
+
const fixed = text
|
|
37
|
+
.replace(/\r/g, "")
|
|
38
|
+
.replace(/\n/g, "\\n")
|
|
39
|
+
.replace(/\t/g, "\\t");
|
|
40
|
+
|
|
41
|
+
return JSON.parse(fixed);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async function generateProject(prompt, directoryName) {
|
|
46
|
+
const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${API_KEY}`;
|
|
47
|
+
|
|
48
|
+
const aiPrompt = `
|
|
49
|
+
You are an expert software developer and project scaffolder.
|
|
50
|
+
Based on the user's prompt, generate a complete file structure as a JSON array.
|
|
51
|
+
|
|
52
|
+
Each object must contain:
|
|
53
|
+
- "filename": relative file path
|
|
54
|
+
- "code": full file code
|
|
55
|
+
|
|
56
|
+
Do not add any comments inside the code.
|
|
57
|
+
|
|
58
|
+
Only return raw JSON array.
|
|
59
|
+
|
|
60
|
+
User Prompt: "${prompt}"
|
|
61
|
+
`;
|
|
62
|
+
|
|
63
|
+
const body = {
|
|
64
|
+
contents: [{ parts: [{ text: aiPrompt }] }]
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
try {
|
|
68
|
+
console.log("loading...");
|
|
69
|
+
|
|
70
|
+
const response = await fetchWithRetry(url, {
|
|
71
|
+
method: "POST",
|
|
72
|
+
headers: { "Content-Type": "application/json" },
|
|
73
|
+
body: JSON.stringify(body)
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
const data = await response.json();
|
|
77
|
+
let responseText = data.candidates[0].content.parts[0].text;
|
|
78
|
+
|
|
79
|
+
if (responseText.startsWith("```")) {
|
|
80
|
+
responseText = responseText.replace(/```json|```/g, "").trim();
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const files = safeJsonParse(responseText);
|
|
84
|
+
|
|
85
|
+
fs.mkdirSync(directoryName, { recursive: true });
|
|
86
|
+
|
|
87
|
+
for (const file of files) {
|
|
88
|
+
const filePath = path.join(directoryName, file.filename);
|
|
89
|
+
const fileDir = path.dirname(filePath);
|
|
90
|
+
|
|
91
|
+
if (!fs.existsSync(fileDir)) {
|
|
92
|
+
fs.mkdirSync(fileDir, { recursive: true });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const cleanCode = removeComments(file.code);
|
|
96
|
+
fs.writeFileSync(filePath, cleanCode);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
console.log(`Project "${directoryName}" generated successfully!`);
|
|
100
|
+
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error("❌ Error:", error.message);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
yargs(hideBin(process.argv))
|
|
107
|
+
.command(
|
|
108
|
+
"$0 <prompt>",
|
|
109
|
+
"Generate project from prompt",
|
|
110
|
+
(yargs) => {
|
|
111
|
+
return yargs
|
|
112
|
+
.positional("prompt", {
|
|
113
|
+
describe: "Project description",
|
|
114
|
+
type: "string"
|
|
115
|
+
})
|
|
116
|
+
.option("directory", {
|
|
117
|
+
alias: "d",
|
|
118
|
+
describe: "Output directory name",
|
|
119
|
+
type: "string",
|
|
120
|
+
demandOption: true
|
|
121
|
+
});
|
|
122
|
+
},
|
|
123
|
+
(argv) => {
|
|
124
|
+
generateProject(argv.prompt, argv.directory);
|
|
125
|
+
}
|
|
126
|
+
)
|
|
127
|
+
.help()
|
|
128
|
+
.parse();
|
package/package.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "jwtttt",
|
|
3
|
+
"version": "1.6.1",
|
|
4
|
+
"main": "index.js",
|
|
5
|
+
"bin": {
|
|
6
|
+
"jwtttt": "index.js"
|
|
7
|
+
},
|
|
8
|
+
"type": "commonjs",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"No tests\""
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"node-fetch": "^2.6.9",
|
|
14
|
+
"yargs": "^17.7.2"
|
|
15
|
+
}
|
|
16
|
+
}
|