xoxohp 1.0.4 → 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.
Files changed (2) hide show
  1. package/index.js +71 -191
  2. package/package.json +2 -2
package/index.js CHANGED
@@ -1,233 +1,113 @@
1
- // #!/usr/bin/env node
2
-
3
- // const fs = require('fs'); // Node.js File System
4
- // const path = require('path'); // Node.js Path module
5
- // const yargs = require('yargs/yargs');
6
- // const { hideBin } = require('yargs/helpers');
7
-
8
- // // ⚠️ Paste your official Google Gemini API key here.
9
- // const API_KEY = "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";
10
-
11
- // /**
12
- // * Generates a full project structure based on a prompt.
13
- // * @param {string} prompt - The user's project request.
14
- // * @param {string} directoryName - The name of the folder to create the project in.
15
- // */
16
- // async function generateProject(prompt, directoryName) {
17
- // const url = `https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent?key=${API_KEY}`;
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
1
+ #!/usr/bin/env node
131
2
 
132
3
  const fs = require('fs');
133
4
  const path = require('path');
134
5
  const yargs = require('yargs/yargs');
135
6
  const { hideBin } = require('yargs/helpers');
7
+ const OpenAI = require('openai');
136
8
 
137
- // Fetch for Node.js
138
- const fetch = (...args) =>
139
- import('node-fetch').then(({ default: fetch }) => fetch(...args));
140
-
141
- // 🔐 Put your OpenAI API key here or use process.env.OPENAI_API_KEY
142
- const API_KEY = process.env.OPENAI_API_KEY || "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";
9
+ // 🔴 PASTE YOUR OPENAI API KEY HERE (starts with sk-)
10
+ const client = new OpenAI({
11
+ apiKey: "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"
12
+ });
143
13
 
144
14
  /**
145
- * Generates a full project structure based on a prompt.
15
+ * Generates a full project structure based on a prompt
16
+ * @param {string} prompt
17
+ * @param {string} directoryName
146
18
  */
147
19
  async function generateProject(prompt, directoryName) {
148
- const url = "https://api.openai.com/v1/responses";
149
20
 
150
- const newPrompt = `
21
+ const systemPrompt = `
151
22
  You are an expert software developer and project scaffolder.
152
- Return a JSON array of files.
153
- Each item must contain:
154
- - filename
155
- - code
156
23
 
157
- Return ONLY valid JSON. No markdown.
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)
158
28
 
159
- User Prompt: "${prompt}"
29
+ IMPORTANT RULES:
30
+ - Return ONLY raw JSON
31
+ - NO markdown
32
+ - NO explanation
33
+ - NO backticks
160
34
  `;
161
35
 
162
- const body = {
163
- model: "gpt-4.1-mini",
164
- input: newPrompt,
165
- max_output_tokens: 3000
166
- };
167
-
168
36
  try {
169
- console.log("Generating project...");
170
-
171
- const response = await fetch(url, {
172
- method: "POST",
173
- headers: {
174
- "Authorization": `Bearer ${API_KEY}`,
175
- "Content-Type": "application/json"
176
- },
177
- body: JSON.stringify(body)
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
+ ]
178
46
  });
179
47
 
180
- if (!response.ok) {
181
- throw new Error(await response.text());
182
- }
183
-
184
- const data = await response.json();
185
-
186
- let responseText =
187
- data.output_text ||
188
- data.output?.[0]?.content?.[0]?.text ||
189
- "";
48
+ let text = response.choices[0].message.content.trim();
190
49
 
191
- responseText = responseText
192
- .replace(/^```json/, "")
193
- .replace(/```$/, "")
194
- .trim();
50
+ // Cleanup (extra safety)
51
+ if (text.startsWith("```")) {
52
+ text = text.replace(/```json|```/g, "").trim();
53
+ }
195
54
 
196
- let files = JSON.parse(responseText);
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
+ }
197
64
 
65
+ // Create main directory
198
66
  fs.mkdirSync(directoryName, { recursive: true });
199
67
 
68
+ // Create files
200
69
  for (const file of files) {
201
70
  const filePath = path.join(directoryName, file.filename);
202
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
71
+ const fileDir = path.dirname(filePath);
72
+
73
+ if (!fs.existsSync(fileDir)) {
74
+ fs.mkdirSync(fileDir, { recursive: true });
75
+ }
76
+
203
77
  fs.writeFileSync(filePath, file.code);
204
78
  }
205
79
 
206
- console.log(`🎉 Project "${directoryName}" created successfully!`);
80
+ console.log(`✅ Project "${directoryName}" created successfully!`);
207
81
 
208
- } catch (err) {
209
- console.error("❌ Error:", err.message);
82
+ } catch (error) {
83
+ console.error("❌ OpenAI API Error:", error.message);
210
84
  }
211
85
  }
212
86
 
213
- // CLI
87
+ // CLI setup
214
88
  yargs(hideBin(process.argv))
215
89
  .command(
216
- "$0 <prompt>",
217
- "Generate a project from a prompt",
218
- (y) =>
219
- y.option("directory", {
220
- alias: "d",
221
- type: "string",
222
- demandOption: true
223
- }),
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
+ }),
224
104
  (argv) => {
225
- if (!API_KEY) {
226
- console.error("❌ Set OPENAI_API_KEY first");
105
+ if (!client.apiKey || client.apiKey.startsWith("sk-") === false) {
106
+ console.error("❌ ERROR: Invalid OpenAI API key");
227
107
  return;
228
108
  }
229
109
  generateProject(argv.prompt, argv.directory);
230
110
  }
231
111
  )
112
+ .demandCommand(1, 'Please provide a prompt')
232
113
  .parse();
233
-
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xoxohp",
3
- "version": "1.0.4",
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": "^18.0.0"
17
+ "yargs": "^17.7.2"
18
18
  }
19
19
  }