@vatzzza/botintern 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/.github/workflows/npm-publish.yml +33 -0
- package/README.md +15 -0
- package/bun.lock +80 -0
- package/index.js +425 -0
- package/lib/ai.js +531 -0
- package/lib/aiFileParser.js +54 -0
- package/lib/fileTreeParser.js +105 -0
- package/lib/loop.js +174 -0
- package/lib/registerAndFetchKey.js +75 -0
- package/lib/runPlaywright.js +39 -0
- package/lib/runTests.js +418 -0
- package/lib/scan.js +58 -0
- package/package.json +29 -0
- package/tsconfig.json +29 -0
- package/utils/errorExtractor.js +33 -0
- package/utils/setupPlaywright.js +29 -0
- package/utils/yaml-example.txt +21 -0
- package/utils/yamlGuardrails.js +130 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
|
|
2
|
+
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
|
|
3
|
+
|
|
4
|
+
name: Node.js Package
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
# only trigger on branches, not on tags
|
|
9
|
+
branches: 'main'
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
build:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
- uses: actions/setup-node@v4
|
|
17
|
+
with:
|
|
18
|
+
node-version: 20
|
|
19
|
+
- run: npm ci
|
|
20
|
+
|
|
21
|
+
publish-npm:
|
|
22
|
+
needs: build
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v4
|
|
26
|
+
- uses: actions/setup-node@v4
|
|
27
|
+
with:
|
|
28
|
+
node-version: 20
|
|
29
|
+
registry-url: https://registry.npmjs.org/
|
|
30
|
+
- run: npm ci
|
|
31
|
+
- run: npm publish --access=public
|
|
32
|
+
env:
|
|
33
|
+
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# botintern
|
|
2
|
+
|
|
3
|
+
To install dependencies:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
bun install
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
To run:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
bun run index.ts
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This project was created using `bun init` in bun v1.3.5. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
|
package/bun.lock
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "botintern",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@google/generative-ai": "^0.24.1",
|
|
9
|
+
"chalk": "^5.6.2",
|
|
10
|
+
"commander": "^14.0.2",
|
|
11
|
+
"dotenv": "^17.2.3",
|
|
12
|
+
"ora": "^9.0.0",
|
|
13
|
+
"playwright": "^1.57.0",
|
|
14
|
+
},
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@types/bun": "latest",
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"typescript": "^5",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
"packages": {
|
|
24
|
+
"@google/generative-ai": ["@google/generative-ai@0.24.1", "", {}, "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q=="],
|
|
25
|
+
|
|
26
|
+
"@types/bun": ["@types/bun@1.3.6", "", { "dependencies": { "bun-types": "1.3.6" } }, "sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA=="],
|
|
27
|
+
|
|
28
|
+
"@types/node": ["@types/node@25.0.9", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw=="],
|
|
29
|
+
|
|
30
|
+
"ansi-regex": ["ansi-regex@6.2.2", "", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
|
|
31
|
+
|
|
32
|
+
"bun-types": ["bun-types@1.3.6", "", { "dependencies": { "@types/node": "*" } }, "sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ=="],
|
|
33
|
+
|
|
34
|
+
"chalk": ["chalk@5.6.2", "", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
|
|
35
|
+
|
|
36
|
+
"cli-cursor": ["cli-cursor@5.0.0", "", { "dependencies": { "restore-cursor": "^5.0.0" } }, "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw=="],
|
|
37
|
+
|
|
38
|
+
"cli-spinners": ["cli-spinners@3.4.0", "", {}, "sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw=="],
|
|
39
|
+
|
|
40
|
+
"commander": ["commander@14.0.2", "", {}, "sha512-TywoWNNRbhoD0BXs1P3ZEScW8W5iKrnbithIl0YH+uCmBd0QpPOA8yc82DS3BIE5Ma6FnBVUsJ7wVUDz4dvOWQ=="],
|
|
41
|
+
|
|
42
|
+
"dotenv": ["dotenv@17.2.3", "", {}, "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w=="],
|
|
43
|
+
|
|
44
|
+
"fsevents": ["fsevents@2.3.2", "", { "os": "darwin" }, "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA=="],
|
|
45
|
+
|
|
46
|
+
"get-east-asian-width": ["get-east-asian-width@1.4.0", "", {}, "sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q=="],
|
|
47
|
+
|
|
48
|
+
"is-interactive": ["is-interactive@2.0.0", "", {}, "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ=="],
|
|
49
|
+
|
|
50
|
+
"is-unicode-supported": ["is-unicode-supported@2.1.0", "", {}, "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ=="],
|
|
51
|
+
|
|
52
|
+
"log-symbols": ["log-symbols@7.0.1", "", { "dependencies": { "is-unicode-supported": "^2.0.0", "yoctocolors": "^2.1.1" } }, "sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg=="],
|
|
53
|
+
|
|
54
|
+
"mimic-function": ["mimic-function@5.0.1", "", {}, "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA=="],
|
|
55
|
+
|
|
56
|
+
"onetime": ["onetime@7.0.0", "", { "dependencies": { "mimic-function": "^5.0.0" } }, "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ=="],
|
|
57
|
+
|
|
58
|
+
"ora": ["ora@9.0.0", "", { "dependencies": { "chalk": "^5.6.2", "cli-cursor": "^5.0.0", "cli-spinners": "^3.2.0", "is-interactive": "^2.0.0", "is-unicode-supported": "^2.1.0", "log-symbols": "^7.0.1", "stdin-discarder": "^0.2.2", "string-width": "^8.1.0", "strip-ansi": "^7.1.2" } }, "sha512-m0pg2zscbYgWbqRR6ABga5c3sZdEon7bSgjnlXC64kxtxLOyjRcbbUkLj7HFyy/FTD+P2xdBWu8snGhYI0jc4A=="],
|
|
59
|
+
|
|
60
|
+
"playwright": ["playwright@1.57.0", "", { "dependencies": { "playwright-core": "1.57.0" }, "optionalDependencies": { "fsevents": "2.3.2" }, "bin": { "playwright": "cli.js" } }, "sha512-ilYQj1s8sr2ppEJ2YVadYBN0Mb3mdo9J0wQ+UuDhzYqURwSoW4n1Xs5vs7ORwgDGmyEh33tRMeS8KhdkMoLXQw=="],
|
|
61
|
+
|
|
62
|
+
"playwright-core": ["playwright-core@1.57.0", "", { "bin": { "playwright-core": "cli.js" } }, "sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ=="],
|
|
63
|
+
|
|
64
|
+
"restore-cursor": ["restore-cursor@5.1.0", "", { "dependencies": { "onetime": "^7.0.0", "signal-exit": "^4.1.0" } }, "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA=="],
|
|
65
|
+
|
|
66
|
+
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
|
|
67
|
+
|
|
68
|
+
"stdin-discarder": ["stdin-discarder@0.2.2", "", {}, "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ=="],
|
|
69
|
+
|
|
70
|
+
"string-width": ["string-width@8.1.0", "", { "dependencies": { "get-east-asian-width": "^1.3.0", "strip-ansi": "^7.1.0" } }, "sha512-Kxl3KJGb/gxkaUMOjRsQ8IrXiGW75O4E3RPjFIINOVH8AMl2SQ/yWdTzWwF3FevIX9LcMAjJW+GRwAlAbTSXdg=="],
|
|
71
|
+
|
|
72
|
+
"strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],
|
|
73
|
+
|
|
74
|
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
75
|
+
|
|
76
|
+
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
|
|
77
|
+
|
|
78
|
+
"yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="],
|
|
79
|
+
}
|
|
80
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// Use bun run index.js to run this file single time.
|
|
4
|
+
// Use bun run dev to run this file in watch mode.
|
|
5
|
+
|
|
6
|
+
import { Command } from "commander";
|
|
7
|
+
import chalk from "chalk";
|
|
8
|
+
import exec from "child_process";
|
|
9
|
+
import ora from "ora";
|
|
10
|
+
import { fixBuild, generateYaml } from "./lib/ai.js";
|
|
11
|
+
import fs from "fs";
|
|
12
|
+
import { extractErrorFile } from "./utils/errorExtractor.js";
|
|
13
|
+
import path from "path";
|
|
14
|
+
import { getCriticalSourceCode, getProjectStructure } from "./lib/fileTreeParser.js";
|
|
15
|
+
import { runTests } from "./lib/runTests.js";
|
|
16
|
+
import { runPlaywright } from "./lib/runPlaywright.js";
|
|
17
|
+
import { loop } from "./lib/loop.js";
|
|
18
|
+
import { saveApiKey } from "./lib/registerAndFetchKey.js";
|
|
19
|
+
import readline from "readline";
|
|
20
|
+
|
|
21
|
+
const banner = `
|
|
22
|
+
${chalk.bold.cyan('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ')}
|
|
23
|
+
${chalk.cyan('โ')} ${chalk.bold.white('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ')} ${chalk.cyan('โ')}
|
|
24
|
+
${chalk.cyan('โ')} ${chalk.cyan('โ')} ${chalk.bold.white('โโโโโโ โโโโโโ โโโโโโ โโ โโโ โโ โโโโโโ โโโโโโ โโโโโโ โโโ โโ ')} ${chalk.cyan('โ')} ${chalk.cyan('โ')}
|
|
25
|
+
${chalk.cyan('โ')} ${chalk.cyan('โ')} ${chalk.bold.white('โโโโโโ โโ โโ โโ โโ โโ โโโโ โโ โโโโ โโโโโโโ โโ โโโโ ')} ${chalk.cyan('โ')} ${chalk.cyan('โ')}
|
|
26
|
+
${chalk.cyan('โ')} ${chalk.cyan('โ')} ${chalk.bold.white('โโโโโโ โโโโโโ โโ โโ โโ โโ โโ โโโโโโ โโ โโ โโ โโ ')} ${chalk.cyan('โ')} ${chalk.cyan('โ')}
|
|
27
|
+
${chalk.cyan('โ')} ${chalk.cyan('โ')} ${chalk.gray(' ' + chalk.italic.blue('AI-Powered Code Testing & Validation') + ' ')} ${chalk.cyan('โ')} ${chalk.cyan('โ')}
|
|
28
|
+
${chalk.cyan('โ')} ${chalk.cyan('โ')} ${chalk.dim(' ' + chalk.yellow('โก') + ' The intern that fixes more bugs than it creates ' + chalk.yellow('โก') + ' ')} ${chalk.cyan('โ')} ${chalk.cyan('โ')}
|
|
29
|
+
${chalk.cyan('โ')} ${chalk.cyan('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ')} ${chalk.cyan('โ')}
|
|
30
|
+
${chalk.cyan('โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ')}
|
|
31
|
+
|
|
32
|
+
${chalk.cyan.bold('๐ Ready to validate your AI-generated code? ๐')}
|
|
33
|
+
|
|
34
|
+
${chalk.dim('โจ Scan โข Fix โข Test โข Generate โข Loop')}
|
|
35
|
+
${chalk.dim('')}
|
|
36
|
+
|
|
37
|
+
`;
|
|
38
|
+
|
|
39
|
+
const program = new Command();
|
|
40
|
+
|
|
41
|
+
program
|
|
42
|
+
.name('botintern')
|
|
43
|
+
.description(chalk.gray('Advanced CLI to validate and fix AI-generated code with intelligent testing.'))
|
|
44
|
+
.version('1.0.0')
|
|
45
|
+
.configureOutput({
|
|
46
|
+
writeErr: (str) => process.stderr.write(chalk.red(str)),
|
|
47
|
+
writeOut: (str) => process.stdout.write(str)
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
program
|
|
51
|
+
.command('login')
|
|
52
|
+
.description('Authenticate BotIntern with your Gemini API Key')
|
|
53
|
+
.action(() => {
|
|
54
|
+
const rl = readline.createInterface({
|
|
55
|
+
input: process.stdin,
|
|
56
|
+
output: process.stdout
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
console.log(chalk.cyan('๐ค BotIntern Login'));
|
|
60
|
+
console.log(chalk.dim('Get your free key at: https://aistudio.google.com/app/apikey'));
|
|
61
|
+
|
|
62
|
+
rl.question('\n๐ Paste your Gemini API Key: ', (key) => {
|
|
63
|
+
if (!key || key.trim().length === 0) {
|
|
64
|
+
console.log(chalk.red('โ Invalid key.'));
|
|
65
|
+
rl.close();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
saveApiKey(key.trim());
|
|
70
|
+
console.log(chalk.green('\nโจ Success! Key saved globally. You can now use "botintern test" and "botintern loop" commands.'));
|
|
71
|
+
rl.close();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
program.command('scan')
|
|
76
|
+
.description('๐ Scan a codebase for errors')
|
|
77
|
+
.action(() => {
|
|
78
|
+
console.log(chalk.cyan('โโ ') + chalk.bold.white('SCAN MODE') + chalk.cyan(' โโโโโโโโโโโโโโโโโโโโโโโโโโโ'));
|
|
79
|
+
console.log(chalk.cyan('โ') + ' ' + chalk.blue('๐ Initializing AI code scanner...'));
|
|
80
|
+
console.log(chalk.cyan('โ') + ' ' + chalk.yellow('โก Analyzing codebase for potential issues...'));
|
|
81
|
+
console.log(chalk.cyan('โโ') + chalk.cyan('โ'.repeat(45)));
|
|
82
|
+
|
|
83
|
+
const spinner = ora({
|
|
84
|
+
text: chalk.yellow('๐ Scanning for AI hallucinations...'),
|
|
85
|
+
spinner: 'dots',
|
|
86
|
+
color: 'yellow'
|
|
87
|
+
}).start();
|
|
88
|
+
|
|
89
|
+
exec.exec("npm run build", function (error, stdout, stderr) {
|
|
90
|
+
if (error) {
|
|
91
|
+
spinner.fail({
|
|
92
|
+
text: chalk.red('โ BUILD FAILED'),
|
|
93
|
+
symbol: 'โ'
|
|
94
|
+
});
|
|
95
|
+
console.log('');
|
|
96
|
+
console.log(chalk.red('โโ ') + chalk.bold.white('ERROR DETAILS') + chalk.red(' โโโโโโโโโโโโโโโโโโโโโโ'));
|
|
97
|
+
console.log(chalk.red('โ') + ' ' + chalk.gray('Build output detected issues:'));
|
|
98
|
+
console.log(chalk.red('โ') + chalk.dim('โโ STDOUT:'));
|
|
99
|
+
console.log(chalk.red('โ') + chalk.dim('โ ' + stdout.trim()));
|
|
100
|
+
console.log(chalk.red('โ') + chalk.dim('โโ STDERR:'));
|
|
101
|
+
console.log(chalk.red('โ') + chalk.dim('โ ' + stderr.trim()));
|
|
102
|
+
console.log(chalk.red('โโ') + chalk.red('โ'.repeat(45)));
|
|
103
|
+
} else {
|
|
104
|
+
spinner.succeed({
|
|
105
|
+
text: chalk.green('โ
BUILD PASSED'),
|
|
106
|
+
symbol: 'โ'
|
|
107
|
+
});
|
|
108
|
+
console.log(chalk.green('โโ ') + chalk.white('SCAN RESULTS') + chalk.green(' โโโโโโโโโโโโโโโโโโโโโโโ'));
|
|
109
|
+
console.log(chalk.green('โ') + ' ' + chalk.white('โจ No errors detected! Code looks clean.'));
|
|
110
|
+
console.log(chalk.green('โ') + ' ' + chalk.gray('๐ฏ AI code quality: EXCELLENT'));
|
|
111
|
+
console.log(chalk.green('โโ') + chalk.green('โ'.repeat(45)));
|
|
112
|
+
}
|
|
113
|
+
})
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
program.command('fix')
|
|
118
|
+
.description('๐ง Automatically fix errors in a codebase')
|
|
119
|
+
.action(() => {
|
|
120
|
+
console.log(chalk.magenta('โโ ') + chalk.bold.white('AUTO-FIX MODE') + chalk.magenta(' โโโโโโโโโโโโโโโโโโโโโโ'));
|
|
121
|
+
console.log(chalk.magenta('โ') + ' ' + chalk.blue('๐ง Initializing intelligent code repair...'));
|
|
122
|
+
console.log(chalk.magenta('โ') + ' ' + chalk.yellow('โก AI-powered error fixing enabled...'));
|
|
123
|
+
console.log(chalk.magenta('โโ') + chalk.magenta('โ'.repeat(45)));
|
|
124
|
+
|
|
125
|
+
const spinner = ora({
|
|
126
|
+
text: chalk.yellow('๐ Detecting and analyzing build errors...'),
|
|
127
|
+
spinner: 'line',
|
|
128
|
+
color: 'yellow'
|
|
129
|
+
}).start();
|
|
130
|
+
|
|
131
|
+
exec.exec("npm run build", async function (error, stdout, stderr) {
|
|
132
|
+
if (error) {
|
|
133
|
+
spinner.fail({
|
|
134
|
+
text: chalk.red('โ BUILD ERRORS FOUND'),
|
|
135
|
+
symbol: 'โ'
|
|
136
|
+
});
|
|
137
|
+
console.log('');
|
|
138
|
+
console.log(chalk.red('โโ ') + chalk.bold.white('ERROR ANALYSIS') + chalk.red(' โโโโโโโโโโโโโโโโโโโโโโ'));
|
|
139
|
+
console.log(chalk.red('โ') + ' ' + chalk.gray('๐ Processing build output...'));
|
|
140
|
+
console.log(chalk.red('โ') + chalk.dim('โโ BUILD LOGS:'));
|
|
141
|
+
console.log(chalk.red('โ') + chalk.dim('โ ' + (stdout + stderr).trim()));
|
|
142
|
+
|
|
143
|
+
const combinedLogs = stdout + "\n" + stderr;
|
|
144
|
+
let brokenFilePath = extractErrorFile(combinedLogs);
|
|
145
|
+
|
|
146
|
+
if (!brokenFilePath) {
|
|
147
|
+
console.log(chalk.yellow('โ') + chalk.dim('โโ ') + chalk.yellow('โ ๏ธ No specific file detected, using default: app/page.tsx'));
|
|
148
|
+
brokenFilePath = "app/page.tsx";
|
|
149
|
+
} else {
|
|
150
|
+
console.log(chalk.blue('โ') + chalk.dim('โโ ') + chalk.blue(`๐ฏ Target identified: ${chalk.bold(brokenFilePath)}`));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
console.log(chalk.magenta('โ') + chalk.dim('โโ ') + chalk.magenta('๐ค AI attempting fix...'));
|
|
154
|
+
console.log(chalk.magenta('โโ') + chalk.magenta('โ'.repeat(45)));
|
|
155
|
+
|
|
156
|
+
try {
|
|
157
|
+
const absolutePath = path.resolve(process.cwd(), brokenFilePath);
|
|
158
|
+
|
|
159
|
+
if (fs.existsSync(absolutePath)) {
|
|
160
|
+
const fixSpinner = ora({
|
|
161
|
+
text: chalk.cyan('๐ง AI generating solution...'),
|
|
162
|
+
spinner: 'bouncingBar',
|
|
163
|
+
color: 'cyan'
|
|
164
|
+
}).start();
|
|
165
|
+
|
|
166
|
+
const pageContent = fs.readFileSync(absolutePath, "utf-8");
|
|
167
|
+
const packageContent = fs.readFileSync(path.join(process.cwd(), "package.json"), "utf-8");
|
|
168
|
+
|
|
169
|
+
const finalCode = await fixBuild([combinedLogs, pageContent, packageContent]);
|
|
170
|
+
fixSpinner.succeed({
|
|
171
|
+
text: chalk.green('โ
SOLUTION GENERATED'),
|
|
172
|
+
symbol: 'โจ'
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
const applySpinner = ora({
|
|
176
|
+
text: chalk.blue('๐ Applying fixes...'),
|
|
177
|
+
spinner: 'dots',
|
|
178
|
+
color: 'blue'
|
|
179
|
+
}).start();
|
|
180
|
+
|
|
181
|
+
fs.writeFileSync(absolutePath, finalCode);
|
|
182
|
+
applySpinner.succeed({
|
|
183
|
+
text: chalk.green('โจ FIXES APPLIED SUCCESSFULLY'),
|
|
184
|
+
symbol: 'โ'
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
console.log(chalk.green('โโ ') + chalk.white('FIX SUMMARY') + chalk.green(' โโโโโโโโโโโโโโโโโโโโโโโ'));
|
|
188
|
+
console.log(chalk.green('โ') + ' ' + chalk.white(`๐ File: ${chalk.gray(brokenFilePath)}`));
|
|
189
|
+
console.log(chalk.green('โ') + ' ' + chalk.white('๐ง Status: ') + chalk.green('FIXED'));
|
|
190
|
+
console.log(chalk.green('โ') + ' ' + chalk.gray('๐ก Run "botintern scan" to verify fixes'));
|
|
191
|
+
console.log(chalk.green('โโ') + chalk.green('โ'.repeat(45)));
|
|
192
|
+
} else {
|
|
193
|
+
console.log(chalk.red(`โ File not found: ${brokenFilePath}`));
|
|
194
|
+
}
|
|
195
|
+
} catch (err) {
|
|
196
|
+
console.log(chalk.red(`๐ฅ Fix failed: ${err.message}`));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
} else {
|
|
200
|
+
spinner.succeed({
|
|
201
|
+
text: chalk.green('โ
NO ERRORS TO FIX'),
|
|
202
|
+
symbol: 'โจ'
|
|
203
|
+
});
|
|
204
|
+
console.log(chalk.green('โโ ') + chalk.white('CODE STATUS') + chalk.green(' โโโโโโโโโโโโโโโโโโโโโโโ'));
|
|
205
|
+
console.log(chalk.green('โ') + ' ' + chalk.white('๐ Codebase is already error-free!'));
|
|
206
|
+
console.log(chalk.green('โ') + ' ' + chalk.gray('๐ Quality: PERFECT'));
|
|
207
|
+
console.log(chalk.green('โโ') + chalk.green('โ'.repeat(45)));
|
|
208
|
+
}
|
|
209
|
+
})
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
program.command("test")
|
|
215
|
+
.description("๐งช Run comprehensive playwright tests")
|
|
216
|
+
.action(async () => {
|
|
217
|
+
console.log(chalk.blue('โโ ') + chalk.bold.white('TEST MODE') + chalk.blue(' โโโโโโโโโโโโโโโโโโโโโโโโ'));
|
|
218
|
+
console.log(chalk.blue('โ') + ' ' + chalk.cyan('๐งช Initializing test environment...'));
|
|
219
|
+
console.log(chalk.blue('โ') + ' ' + chalk.yellow('โก Launching browser automation...'));
|
|
220
|
+
console.log(chalk.blue('โโ') + chalk.blue('โ'.repeat(45)));
|
|
221
|
+
|
|
222
|
+
const spinner = ora({
|
|
223
|
+
text: chalk.cyan('๐ Setting up test browser...'),
|
|
224
|
+
spinner: 'toggle',
|
|
225
|
+
color: 'cyan'
|
|
226
|
+
}).start();
|
|
227
|
+
|
|
228
|
+
try {
|
|
229
|
+
const { browser, page } = await runPlaywright();
|
|
230
|
+
spinner.succeed({
|
|
231
|
+
text: chalk.green('๐ Browser ready'),
|
|
232
|
+
symbol: 'โจ'
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
const testSpinner = ora({
|
|
236
|
+
text: chalk.yellow('๐งช Running automated tests...'),
|
|
237
|
+
spinner: 'dots2',
|
|
238
|
+
color: 'yellow'
|
|
239
|
+
}).start();
|
|
240
|
+
|
|
241
|
+
const testResult = await runTests(page);
|
|
242
|
+
testSpinner.stop();
|
|
243
|
+
|
|
244
|
+
const cleanupSpinner = ora({
|
|
245
|
+
text: chalk.blue('๐งน Cleaning up...'),
|
|
246
|
+
spinner: 'pipe',
|
|
247
|
+
color: 'blue'
|
|
248
|
+
}).start();
|
|
249
|
+
|
|
250
|
+
await browser.close();
|
|
251
|
+
cleanupSpinner.succeed({
|
|
252
|
+
text: chalk.green('โจ Test session complete'),
|
|
253
|
+
symbol: 'โ'
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
// Display results based on actual test outcome
|
|
257
|
+
if (testResult.success) {
|
|
258
|
+
console.log(chalk.green('โโ ') + chalk.white('TEST RESULTS') + chalk.green(' โโโโโโโโโโโโโโโโโโโโโโ'));
|
|
259
|
+
console.log(chalk.green('โ') + ' ' + chalk.white('๐ฏ Status: ') + chalk.green('PASSED'));
|
|
260
|
+
console.log(chalk.green('โ') + ' ' + chalk.white('๐ Tests: ') + chalk.gray(`${testResult.passedTests}/${testResult.totalTests} passed`));
|
|
261
|
+
console.log(chalk.green('โ') + ' ' + chalk.gray('๐ก All checks passed successfully'));
|
|
262
|
+
console.log(chalk.green('โโ') + chalk.green('โ'.repeat(45)));
|
|
263
|
+
} else {
|
|
264
|
+
console.log(chalk.red('โโ ') + chalk.white('TEST RESULTS') + chalk.red(' โโโโโโโโโโโโโโโโโโโโโโ'));
|
|
265
|
+
console.log(chalk.red('โ') + ' ' + chalk.white('๐ฏ Status: ') + chalk.red('FAILED'));
|
|
266
|
+
if (testResult.totalTests) {
|
|
267
|
+
console.log(chalk.red('โ') + ' ' + chalk.white('๐ Tests: ') + chalk.yellow(`${testResult.passedTests}/${testResult.totalTests} passed`));
|
|
268
|
+
console.log(chalk.red('โ') + ' ' + chalk.white('โ Failures: ') + chalk.red(`${testResult.failures?.length || 0}`));
|
|
269
|
+
} else if (testResult.error) {
|
|
270
|
+
console.log(chalk.red('โ') + ' ' + chalk.white('โ Error: ') + chalk.red(testResult.error));
|
|
271
|
+
}
|
|
272
|
+
console.log(chalk.red('โโ') + chalk.red('โ'.repeat(45)));
|
|
273
|
+
process.exit(1);
|
|
274
|
+
}
|
|
275
|
+
} catch (error) {
|
|
276
|
+
spinner.fail({
|
|
277
|
+
text: chalk.red('โ Test execution failed'),
|
|
278
|
+
symbol: 'โ'
|
|
279
|
+
});
|
|
280
|
+
console.log(chalk.red(`๐ฅ Error: ${error.message}`));
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
program.command("generate-yaml")
|
|
285
|
+
.description("๐ Generate intelligent YAML test cases")
|
|
286
|
+
.action(async () => {
|
|
287
|
+
console.log(chalk.yellow('โโ ') + chalk.bold.white('YAML GENERATOR') + chalk.yellow(' โโโโโโโโโโโโโโโโโโโ'));
|
|
288
|
+
console.log(chalk.yellow('โ') + ' ' + chalk.cyan('๐ Creating intelligent test configurations...'));
|
|
289
|
+
console.log(chalk.yellow('โ') + ' ' + chalk.gray('๐ Analyzing codebase structure...'));
|
|
290
|
+
console.log(chalk.yellow('โโ') + chalk.yellow('โ'.repeat(45)));
|
|
291
|
+
|
|
292
|
+
const analyzeSpinner = ora({
|
|
293
|
+
text: chalk.blue('๐ Scanning project structure...'),
|
|
294
|
+
spinner: 'dots12',
|
|
295
|
+
color: 'blue'
|
|
296
|
+
}).start();
|
|
297
|
+
|
|
298
|
+
const cwd = process.cwd();
|
|
299
|
+
const fileTree = getProjectStructure(cwd);
|
|
300
|
+
const sourceCode = getCriticalSourceCode(cwd);
|
|
301
|
+
|
|
302
|
+
analyzeSpinner.succeed({
|
|
303
|
+
text: chalk.green('๐ Analysis complete'),
|
|
304
|
+
symbol: 'โจ'
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
const yamlSpinner = ora({
|
|
308
|
+
text: chalk.magenta('๐ค AI generating YAML configurations...'),
|
|
309
|
+
spinner: 'growHorizontal',
|
|
310
|
+
color: 'magenta'
|
|
311
|
+
}).start();
|
|
312
|
+
|
|
313
|
+
const yamlPath = `${cwd}/vibe.yaml`;
|
|
314
|
+
let currentYaml = "";
|
|
315
|
+
if (fs.existsSync(yamlPath)) {
|
|
316
|
+
currentYaml = fs.readFileSync(yamlPath, 'utf-8');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const yaml = await generateYaml([fileTree, sourceCode, currentYaml, ""]);
|
|
320
|
+
fs.writeFileSync(yamlPath, yaml);
|
|
321
|
+
|
|
322
|
+
yamlSpinner.succeed({
|
|
323
|
+
text: chalk.green('โจ YAML test cases generated'),
|
|
324
|
+
symbol: '๐'
|
|
325
|
+
});
|
|
326
|
+
|
|
327
|
+
console.log(chalk.green('โโ ') + chalk.white('GENERATION SUMMARY') + chalk.green(' โโโโโโโโโโโโโโโ'));
|
|
328
|
+
console.log(chalk.green('โ') + ' ' + chalk.white('๐ Output: ') + chalk.gray('vibe.yaml'));
|
|
329
|
+
console.log(chalk.green('โ') + ' ' + chalk.white('๐งช Test cases: ') + chalk.blue('Generated'));
|
|
330
|
+
console.log(chalk.green('โ') + ' ' + chalk.gray('๐ก Ready for automated testing'));
|
|
331
|
+
console.log(chalk.green('โโ') + chalk.green('โ'.repeat(45)));
|
|
332
|
+
});
|
|
333
|
+
|
|
334
|
+
program.command("loop")
|
|
335
|
+
.description("๐ AI-powered iterative development loop")
|
|
336
|
+
.argument('<string>', 'Custom prompt for AI generation')
|
|
337
|
+
.option("-p", "Prompt mode")
|
|
338
|
+
.action(async (prompt, options) => {
|
|
339
|
+
console.log(chalk.cyan('โโ ') + chalk.bold.white('AI LOOP MODE') + chalk.cyan(' โโโโโโโโโโโโโโโโโโโ'));
|
|
340
|
+
console.log(chalk.cyan('โ') + ' ' + chalk.blue('๐ Initializing iterative development...'));
|
|
341
|
+
console.log(chalk.cyan('โ') + ' ' + chalk.yellow('๐ค AI agent ready for continuous improvement...'));
|
|
342
|
+
console.log(chalk.cyan('โโ') + chalk.cyan('โ'.repeat(45)));
|
|
343
|
+
|
|
344
|
+
if (prompt) {
|
|
345
|
+
console.log(chalk.blue('โโ ') + chalk.white('CUSTOM PROMPT') + chalk.blue(' โโโโโโโโโโโโโโโโโโโโโโ'));
|
|
346
|
+
console.log(chalk.blue('โ') + ' ' + chalk.gray(`๐ ${prompt}`));
|
|
347
|
+
console.log(chalk.blue('โโ') + chalk.blue('โ'.repeat(45)));
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const setupSpinner = ora({
|
|
351
|
+
text: chalk.cyan('๐ Setting up development environment...'),
|
|
352
|
+
spinner: 'bouncingBall',
|
|
353
|
+
color: 'cyan'
|
|
354
|
+
}).start();
|
|
355
|
+
|
|
356
|
+
try {
|
|
357
|
+
const { browser, page } = await runPlaywright();
|
|
358
|
+
setupSpinner.succeed({
|
|
359
|
+
text: chalk.green('๐ Environment ready'),
|
|
360
|
+
symbol: 'โจ'
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
const testSpinner = ora({
|
|
364
|
+
text: chalk.yellow('๐งช Running initial tests...'),
|
|
365
|
+
spinner: 'flip',
|
|
366
|
+
color: 'yellow'
|
|
367
|
+
}).start();
|
|
368
|
+
|
|
369
|
+
const testResult = await runTests(page);
|
|
370
|
+
testSpinner.succeed({
|
|
371
|
+
text: testResult.success ? chalk.green('โ
Tests passed') : chalk.yellow('โ ๏ธ Tests need improvement'),
|
|
372
|
+
symbol: testResult.success ? '๐' : '๐'
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
if (testResult.success && !prompt) {
|
|
376
|
+
console.log(chalk.green('โโ ') + chalk.white('LOOP STATUS') + chalk.green(' โโโโโโโโโโโโโโโโโโโโโโ'));
|
|
377
|
+
console.log(chalk.green('โ') + ' ' + chalk.white('๐ All tests passed!'));
|
|
378
|
+
console.log(chalk.green('โ') + ' ' + chalk.gray('โจ No iterations needed'));
|
|
379
|
+
console.log(chalk.green('โโ') + chalk.green('โ'.repeat(45)));
|
|
380
|
+
process.exit(0);
|
|
381
|
+
} else {
|
|
382
|
+
const loopSpinner = ora({
|
|
383
|
+
text: chalk.magenta('๐ค AI improvement loop starting...'),
|
|
384
|
+
spinner: 'toggle8',
|
|
385
|
+
color: 'magenta'
|
|
386
|
+
}).start();
|
|
387
|
+
|
|
388
|
+
if (prompt) {
|
|
389
|
+
await loop(page, prompt);
|
|
390
|
+
} else {
|
|
391
|
+
await loop(page);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
loopSpinner.succeed({
|
|
395
|
+
text: chalk.green('๐ฏ Loop completed'),
|
|
396
|
+
symbol: 'โจ'
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
await browser.close();
|
|
401
|
+
} catch (error) {
|
|
402
|
+
setupSpinner.fail({
|
|
403
|
+
text: chalk.red('โ Loop initialization failed'),
|
|
404
|
+
symbol: 'โ'
|
|
405
|
+
});
|
|
406
|
+
console.log(chalk.red(`๐ฅ Error: ${error.message}`));
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
|
|
410
|
+
// Show welcome banner and help when no arguments provided
|
|
411
|
+
if (process.argv.length <= 2) {
|
|
412
|
+
console.log(banner);
|
|
413
|
+
console.log(chalk.cyan.bold('๐ Getting Started:'));
|
|
414
|
+
console.log(chalk.gray(' botintern scan') + chalk.dim(' โข Scan codebase for errors'));
|
|
415
|
+
console.log(chalk.gray(' botintern fix') + chalk.dim(' โข Auto-fix detected errors'));
|
|
416
|
+
console.log(chalk.gray(' botintern test') + chalk.dim(' โข Run automated tests'));
|
|
417
|
+
console.log(chalk.gray(' botintern generate-yaml') + chalk.dim(' โข Generate test configurations'));
|
|
418
|
+
console.log(chalk.gray(' botintern loop <prompt>') + chalk.dim(' โข AI-powered iterative improvement'));
|
|
419
|
+
console.log('');
|
|
420
|
+
console.log(chalk.blue.bold('๐ค Need help?') + chalk.dim(' Run ' + chalk.gray('botintern --help')));
|
|
421
|
+
console.log(chalk.dim('โ'.repeat(67)));
|
|
422
|
+
process.exit(0);
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
program.parse();
|