xoxohp 1.0.5 → 1.0.6
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 +105 -172
- package/package.json +2 -2
package/index.js
CHANGED
|
@@ -1,180 +1,113 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
//
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// // --- This is the new, "smarter" prompt ---
|
|
20
|
-
// // We are asking the AI to act as a file structure generator
|
|
21
|
-
// // and return a specific JSON format.
|
|
22
|
-
// const newPrompt = `
|
|
23
|
-
// You are an expert software developer and project scaffolder.
|
|
24
|
-
// Based on the user's prompt, generate a complete file structure as a JSON array.
|
|
25
|
-
// Each object in the array must have two keys:
|
|
26
|
-
// 1. "filename": (string) The full relative path for the file (e.g., "index.html", "src/styles.css", "js/app.js").
|
|
27
|
-
// 2. "code": (string) The complete code for that file.
|
|
28
|
-
|
|
29
|
-
// Only return the raw JSON array, with no other text, explanations, or markdown fences.
|
|
30
|
-
|
|
31
|
-
// User Prompt: "${prompt}"
|
|
32
|
-
// `;
|
|
33
|
-
|
|
34
|
-
// const body = {
|
|
35
|
-
// contents: [{ parts: [{ text: newPrompt }] }]
|
|
36
|
-
// };
|
|
37
|
-
|
|
38
|
-
// try {
|
|
39
|
-
// console.log(`Code Running in Expresss`);
|
|
40
|
-
|
|
41
|
-
// const response = await fetch(url, {
|
|
42
|
-
// method: 'POST',
|
|
43
|
-
// headers: { 'Content-Type': 'application/json' },
|
|
44
|
-
// body: JSON.stringify(body),
|
|
45
|
-
// });
|
|
46
|
-
|
|
47
|
-
// if (!response.ok) {
|
|
48
|
-
// const errorData = await response.json();
|
|
49
|
-
// console.error('❌ API Error Details:', JSON.stringify(errorData.error, null, 2));
|
|
50
|
-
// throw new Error(`API request failed with status ${response.status}`);
|
|
51
|
-
// }
|
|
52
|
-
|
|
53
|
-
// const data = await response.json();
|
|
54
|
-
// let responseText = data.candidates[0].content.parts[0].text;
|
|
55
|
-
|
|
56
|
-
// // --- NEW JSON PARSING & FILE CREATION LOGIC ---
|
|
57
|
-
// // console.log("Building project...");
|
|
58
|
-
|
|
59
|
-
// // Clean up potential markdown fences from the AI's response
|
|
60
|
-
// if (responseText.startsWith("```json")) {
|
|
61
|
-
// responseText = responseText.substring(7, responseText.length - 3).trim();
|
|
62
|
-
// }
|
|
63
|
-
|
|
64
|
-
// let files;
|
|
65
|
-
// try {
|
|
66
|
-
// files = JSON.parse(responseText);
|
|
67
|
-
// if (!Array.isArray(files)) throw new Error("AI did not return a JSON array.");
|
|
68
|
-
// } catch (parseError) {
|
|
69
|
-
// console.error("❌ ERROR: Failed to parse the AI's response. The response was not valid JSON.");
|
|
70
|
-
// console.error("Raw AI Response:", responseText);
|
|
71
|
-
// return;
|
|
72
|
-
// }
|
|
73
|
-
|
|
74
|
-
// // Create the main project directory
|
|
75
|
-
// fs.mkdirSync(directoryName, { recursive: true });
|
|
76
|
-
// console.log(``);
|
|
77
|
-
|
|
78
|
-
// // Loop through the files array and create each file
|
|
79
|
-
// for (const file of files) {
|
|
80
|
-
// const filePath = path.join(directoryName, file.filename);
|
|
81
|
-
// const fileDir = path.dirname(filePath);
|
|
82
|
-
|
|
83
|
-
// // Create subdirectories if they don't exist
|
|
84
|
-
// if (!fs.existsSync(fileDir)) {
|
|
85
|
-
// fs.mkdirSync(fileDir, { recursive: true });
|
|
86
|
-
// }
|
|
87
|
-
|
|
88
|
-
// // Write the code to the file
|
|
89
|
-
// fs.writeFileSync(filePath, file.code);
|
|
90
|
-
// //console.log(`Created file: ${filePath}`);
|
|
91
|
-
// }
|
|
92
|
-
|
|
93
|
-
// // console.log(`\n🎉 Project "${directoryName}" created successfully!`);
|
|
94
|
-
|
|
95
|
-
// } catch (error) {
|
|
96
|
-
// console.error('❌ An error occurred:', error.message);
|
|
97
|
-
// }
|
|
98
|
-
// }
|
|
99
|
-
|
|
100
|
-
// // --- NEW YARGS SETUP ---
|
|
101
|
-
// yargs(hideBin(process.argv))
|
|
102
|
-
// .command(
|
|
103
|
-
// '$0 <prompt>', // The default command
|
|
104
|
-
// 'Generates a full project structure from a text prompt.',
|
|
105
|
-
// (yargs) => {
|
|
106
|
-
// return yargs
|
|
107
|
-
// .positional('prompt', {
|
|
108
|
-
// describe: 'The project you want to generate',
|
|
109
|
-
// type: 'string',
|
|
110
|
-
// })
|
|
111
|
-
// .option('directory', { // Replaces the old 'output' flag
|
|
112
|
-
// alias: 'd',
|
|
113
|
-
// describe: 'The name of the new directory to create the project in',
|
|
114
|
-
// type: 'string',
|
|
115
|
-
// demandOption: true, // This flag is now required
|
|
116
|
-
// });
|
|
117
|
-
// },
|
|
118
|
-
// (argv) => {
|
|
119
|
-
// if (!API_KEY || API_KEY === "YOUR_GEMINI_API_KEY_HERE") {
|
|
120
|
-
// console.error('❌ ERROR: Please add your API key to the index.js file.');
|
|
121
|
-
// return;
|
|
122
|
-
// }
|
|
123
|
-
// generateProject(argv.prompt, argv.directory);
|
|
124
|
-
// }
|
|
125
|
-
// )
|
|
126
|
-
// .demandCommand(1, 'Please provide a prompt.')
|
|
127
|
-
// .parse();
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
// #!/usr/bin/env node
|
|
131
|
-
const fs = require("fs");
|
|
132
|
-
const path = require("path");
|
|
133
|
-
const yargs = require("yargs/yargs");
|
|
134
|
-
const { hideBin } = require("yargs/helpers");
|
|
135
|
-
|
|
136
|
-
const fetch = (...args) =>
|
|
137
|
-
import("node-fetch").then(({ default: fetch }) => fetch(...args));
|
|
138
|
-
|
|
139
|
-
const API_KEY = "sk-REPLACE_Wsk-proj-5C2jXi-puM9lM9wBlm4njzPxEpdPrIv840zAYfcVdhEZqes1ZrXht8mmJv_KraMV8N4B49gDbcT3BlbkFJyUcZobGhM7KXL80Cmueh3X-ZyPmNA_fY2tCUknWEGbHPSpkGco0vzVBdZCPzgp8vjp8X_OyfgAITH_YOUR_NEW_KEY";
|
|
140
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const yargs = require('yargs/yargs');
|
|
6
|
+
const { hideBin } = require('yargs/helpers');
|
|
7
|
+
const OpenAI = require('openai');
|
|
8
|
+
|
|
9
|
+
// 🔴 PASTE YOUR OPENAI API KEY HERE (starts with sk-)
|
|
10
|
+
const client = new OpenAI({
|
|
11
|
+
apiKey: "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"
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Generates a full project structure based on a prompt
|
|
16
|
+
* @param {string} prompt
|
|
17
|
+
* @param {string} directoryName
|
|
18
|
+
*/
|
|
141
19
|
async function generateProject(prompt, directoryName) {
|
|
142
|
-
const response = await fetch("https://api.openai.com/v1/responses", {
|
|
143
|
-
method: "POST",
|
|
144
|
-
headers: {
|
|
145
|
-
"Authorization": `Bearer ${API_KEY}`,
|
|
146
|
-
"Content-Type": "application/json"
|
|
147
|
-
},
|
|
148
|
-
body: JSON.stringify({
|
|
149
|
-
model: "gpt-4.1-mini",
|
|
150
|
-
input: `Return ONLY a JSON array.\nPrompt: ${prompt}`
|
|
151
|
-
})
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
if (!response.ok) {
|
|
155
|
-
console.error(await response.text());
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
20
|
|
|
159
|
-
const
|
|
21
|
+
const systemPrompt = `
|
|
22
|
+
You are an expert software developer and project scaffolder.
|
|
23
|
+
|
|
24
|
+
Generate a COMPLETE project structure as a JSON array.
|
|
25
|
+
Each object MUST have:
|
|
26
|
+
1. "filename" → string (relative path, e.g. "src/index.js")
|
|
27
|
+
2. "code" → string (full file content)
|
|
28
|
+
|
|
29
|
+
IMPORTANT RULES:
|
|
30
|
+
- Return ONLY raw JSON
|
|
31
|
+
- NO markdown
|
|
32
|
+
- NO explanation
|
|
33
|
+
- NO backticks
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
try {
|
|
37
|
+
console.log("🚀 Generating project with OpenAI...");
|
|
38
|
+
|
|
39
|
+
const response = await client.chat.completions.create({
|
|
40
|
+
model: "gpt-4o-mini",
|
|
41
|
+
temperature: 0.2,
|
|
42
|
+
messages: [
|
|
43
|
+
{ role: "system", content: systemPrompt },
|
|
44
|
+
{ role: "user", content: prompt }
|
|
45
|
+
]
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
let text = response.choices[0].message.content.trim();
|
|
49
|
+
|
|
50
|
+
// Cleanup (extra safety)
|
|
51
|
+
if (text.startsWith("```")) {
|
|
52
|
+
text = text.replace(/```json|```/g, "").trim();
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
let files;
|
|
56
|
+
try {
|
|
57
|
+
files = JSON.parse(text);
|
|
58
|
+
if (!Array.isArray(files)) throw new Error();
|
|
59
|
+
} catch {
|
|
60
|
+
console.error("❌ ERROR: Invalid JSON returned by OpenAI");
|
|
61
|
+
console.error(text);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
// Create main directory
|
|
66
|
+
fs.mkdirSync(directoryName, { recursive: true });
|
|
160
67
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
68
|
+
// Create files
|
|
69
|
+
for (const file of files) {
|
|
70
|
+
const filePath = path.join(directoryName, file.filename);
|
|
71
|
+
const fileDir = path.dirname(filePath);
|
|
72
|
+
|
|
73
|
+
if (!fs.existsSync(fileDir)) {
|
|
74
|
+
fs.mkdirSync(fileDir, { recursive: true });
|
|
166
75
|
}
|
|
76
|
+
|
|
77
|
+
fs.writeFileSync(filePath, file.code);
|
|
167
78
|
}
|
|
168
|
-
}
|
|
169
79
|
|
|
170
|
-
|
|
80
|
+
console.log(`✅ Project "${directoryName}" created successfully!`);
|
|
171
81
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
const filePath = path.join(directoryName, f.filename);
|
|
175
|
-
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
176
|
-
fs.writeFileSync(filePath, f.code);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.error("❌ OpenAI API Error:", error.message);
|
|
177
84
|
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// CLI setup
|
|
88
|
+
yargs(hideBin(process.argv))
|
|
89
|
+
.command(
|
|
90
|
+
'$0 <prompt>',
|
|
91
|
+
'Generate a full project structure from a text prompt',
|
|
92
|
+
(yargs) =>
|
|
93
|
+
yargs
|
|
94
|
+
.positional('prompt', {
|
|
95
|
+
describe: 'Describe the project',
|
|
96
|
+
type: 'string',
|
|
97
|
+
})
|
|
98
|
+
.option('directory', {
|
|
99
|
+
alias: 'd',
|
|
100
|
+
describe: 'Output directory name',
|
|
101
|
+
type: 'string',
|
|
102
|
+
demandOption: true,
|
|
103
|
+
}),
|
|
104
|
+
(argv) => {
|
|
105
|
+
if (!client.apiKey || client.apiKey.startsWith("sk-") === false) {
|
|
106
|
+
console.error("❌ ERROR: Invalid OpenAI API key");
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
generateProject(argv.prompt, argv.directory);
|
|
110
|
+
}
|
|
111
|
+
)
|
|
112
|
+
.demandCommand(1, 'Please provide a prompt')
|
|
113
|
+
.parse();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "xoxohp",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"bin":{
|
|
6
6
|
"xoxohp":"./index.js"
|
|
@@ -14,6 +14,6 @@
|
|
|
14
14
|
"type": "commonjs",
|
|
15
15
|
"description": "",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"yargs": "^
|
|
17
|
+
"yargs": "^17.7.2"
|
|
18
18
|
}
|
|
19
19
|
}
|