kyawthiha-nextjs-agent-cli 1.0.2 ā 1.0.4
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/README.md +23 -0
- package/dist/agent/agent.js +23 -10
- package/dist/agent/tools/code-tools.js +15 -1
- package/package.json +52 -52
package/README.md
CHANGED
|
@@ -26,6 +26,29 @@
|
|
|
26
26
|
- **Gemini API Key** - Get one from [Google AI Studio](https://aistudio.google.com/)
|
|
27
27
|
- **PostgreSQL** (optional) - Only if your project uses a database
|
|
28
28
|
|
|
29
|
+
### Search Tools (Recommended)
|
|
30
|
+
|
|
31
|
+
For enhanced code search capabilities, install these CLI tools:
|
|
32
|
+
|
|
33
|
+
| Tool | Description | Install Guide |
|
|
34
|
+
| ---- | ----------- | ------------- |
|
|
35
|
+
| **ripgrep (rg)** | Fast regex search | [Installation Guide](https://github.com/BurntSushi/ripgrep#installation) |
|
|
36
|
+
| **fd** | Fast file finder | [Installation Guide](https://github.com/sharkdp/fd#installation) |
|
|
37
|
+
|
|
38
|
+
**Quick Install:**
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Windows (winget)
|
|
42
|
+
winget install BurntSushi.ripgrep.MSVC
|
|
43
|
+
winget install sharkdp.fd
|
|
44
|
+
|
|
45
|
+
# macOS (Homebrew)
|
|
46
|
+
brew install ripgrep fd
|
|
47
|
+
|
|
48
|
+
# Ubuntu/Debian
|
|
49
|
+
sudo apt install ripgrep fd-find
|
|
50
|
+
```
|
|
51
|
+
|
|
29
52
|
---
|
|
30
53
|
|
|
31
54
|
## š Quick Start
|
package/dist/agent/agent.js
CHANGED
|
@@ -87,35 +87,48 @@ export class Agent {
|
|
|
87
87
|
async executeTaskLoop(contextId) {
|
|
88
88
|
let iteration = 0;
|
|
89
89
|
let isComplete = false;
|
|
90
|
+
let consecutiveEmptyResponses = 0;
|
|
90
91
|
const maxIterations = this.config.maxIterations;
|
|
92
|
+
const MAX_EMPTY_RESPONSES = 3;
|
|
91
93
|
while (!isComplete && iteration < maxIterations) {
|
|
92
94
|
iteration++;
|
|
93
95
|
logger.step(`[${contextId}] Iteration ${iteration}/${maxIterations}`);
|
|
94
|
-
// Check and compress conversation if needed
|
|
95
96
|
await this.checkAndCompressConversation();
|
|
96
97
|
try {
|
|
97
98
|
const response = await this.callAIWithRetry();
|
|
98
|
-
// Track actual token usage from SDK response
|
|
99
99
|
this.updateTokenCount(response);
|
|
100
|
+
const finishReason = response.candidates?.[0]?.finishReason;
|
|
100
101
|
const { text, toolCalls, functionResponseParts } = this.parseResponse(response);
|
|
102
|
+
// Handle empty response
|
|
103
|
+
if (!text && toolCalls.length === 0) {
|
|
104
|
+
consecutiveEmptyResponses++;
|
|
105
|
+
logger.warn(`Empty response (${consecutiveEmptyResponses}/${MAX_EMPTY_RESPONSES})`);
|
|
106
|
+
if (consecutiveEmptyResponses >= MAX_EMPTY_RESPONSES) {
|
|
107
|
+
logger.info(`[${contextId}] Stopping after ${MAX_EMPTY_RESPONSES} consecutive empty responses`);
|
|
108
|
+
isComplete = true;
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
consecutiveEmptyResponses = 0;
|
|
101
114
|
if (text) {
|
|
102
|
-
logger.dim('AI: ' + text.substring(0,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
logger.success(`[${contextId}] Task Complete!`);
|
|
115
|
+
logger.dim('AI: ' + text.substring(0, 300) + (text.length > 300 ? '...' : ''));
|
|
116
|
+
if (text.toUpperCase().includes('TASK COMPLETE')) {
|
|
117
|
+
logger.success(`[${contextId}] Task Complete signal detected!`);
|
|
106
118
|
isComplete = true;
|
|
107
119
|
continue;
|
|
108
120
|
}
|
|
109
121
|
}
|
|
122
|
+
// No tool calls = model finished or needs more info
|
|
110
123
|
if (toolCalls.length === 0) {
|
|
111
|
-
if (
|
|
112
|
-
logger.
|
|
124
|
+
if (finishReason === 'STOP') {
|
|
125
|
+
logger.success(`[${contextId}] Task Complete signal detected!`);
|
|
126
|
+
isComplete = true;
|
|
113
127
|
continue;
|
|
114
128
|
}
|
|
115
|
-
// AI just responded with text, ask it to continue
|
|
116
129
|
this.conversation.push({
|
|
117
130
|
role: 'user',
|
|
118
|
-
parts: [{ text: 'Continue with the task. Use tools as needed.' }]
|
|
131
|
+
parts: [{ text: 'Continue with the task. Use tools as needed. When finished, say "TASK COMPLETE".' }]
|
|
119
132
|
});
|
|
120
133
|
continue;
|
|
121
134
|
}
|
|
@@ -525,6 +525,8 @@ Use this output to determine next actions. Each failed check includes fixCommand
|
|
|
525
525
|
required: ['projectPath']
|
|
526
526
|
},
|
|
527
527
|
execute: async (input) => {
|
|
528
|
+
console.log(`\nš [verify_project] Starting verification for: ${input.projectPath}`);
|
|
529
|
+
console.log(` Options: autoFix=${input.autoFix || 'false'}, skipBuild=${input.skipBuild || 'false'}, skipPrismaTest=${input.skipPrismaTest || 'false'}`);
|
|
528
530
|
const result = {
|
|
529
531
|
success: true,
|
|
530
532
|
projectPath: input.projectPath,
|
|
@@ -536,13 +538,17 @@ Use this output to determine next actions. Each failed check includes fixCommand
|
|
|
536
538
|
const addCheck = (check) => {
|
|
537
539
|
result.checks.push(check);
|
|
538
540
|
result.summary.total++;
|
|
541
|
+
const statusIcon = check.status === 'pass' ? 'ā
' : check.status === 'fail' ? 'ā' : check.status === 'warn' ? 'ā ļø' : 'āļø';
|
|
542
|
+
console.log(` ${statusIcon} [${check.name}] ${check.message}`);
|
|
543
|
+
if (check.details) {
|
|
544
|
+
console.log(` Details: ${check.details.substring(0, 200)}${check.details.length > 200 ? '...' : ''}`);
|
|
545
|
+
}
|
|
539
546
|
switch (check.status) {
|
|
540
547
|
case 'pass':
|
|
541
548
|
result.summary.passed++;
|
|
542
549
|
break;
|
|
543
550
|
case 'fail':
|
|
544
551
|
result.summary.failed++;
|
|
545
|
-
result.success = false;
|
|
546
552
|
break;
|
|
547
553
|
case 'warn':
|
|
548
554
|
result.summary.warnings++;
|
|
@@ -1027,6 +1033,14 @@ main()
|
|
|
1027
1033
|
details: error.message
|
|
1028
1034
|
});
|
|
1029
1035
|
}
|
|
1036
|
+
// Determine success: only fail on critical checks (build, typescript, project_root, prisma_config)
|
|
1037
|
+
const criticalChecks = ['project_root', 'typescript', 'build', 'prisma_config'];
|
|
1038
|
+
const criticalFailures = result.checks.filter(c => c.status === 'fail' && criticalChecks.includes(c.name));
|
|
1039
|
+
result.success = criticalFailures.length === 0;
|
|
1040
|
+
console.log(`\nš [verify_project] Summary:`);
|
|
1041
|
+
console.log(` Total: ${result.summary.total}, Passed: ${result.summary.passed}, Failed: ${result.summary.failed}, Warnings: ${result.summary.warnings}, Skipped: ${result.summary.skipped}`);
|
|
1042
|
+
console.log(` Critical failures: ${criticalFailures.length}`);
|
|
1043
|
+
console.log(` Overall success: ${result.success}\n`);
|
|
1030
1044
|
return JSON.stringify(result, null, 2);
|
|
1031
1045
|
}
|
|
1032
1046
|
catch (error) {
|
package/package.json
CHANGED
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "kyawthiha-nextjs-agent-cli",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Next.js Fullstack Agent CLI",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"nextjs",
|
|
7
|
-
"agent",
|
|
8
|
-
"ai",
|
|
9
|
-
"cli",
|
|
10
|
-
"fullstack"
|
|
11
|
-
],
|
|
12
|
-
"type": "module",
|
|
13
|
-
"main": "dist/cli/index.js",
|
|
14
|
-
"bin": {
|
|
15
|
-
"next-agent": "dist/cli/index.js"
|
|
16
|
-
},
|
|
17
|
-
"files": [
|
|
18
|
-
"dist",
|
|
19
|
-
"README.md"
|
|
20
|
-
],
|
|
21
|
-
"scripts": {
|
|
22
|
-
"build": "npx rimraf dist && tsc",
|
|
23
|
-
"dev": "npx rimraf dist && tsc && node dist/cli/index.js start",
|
|
24
|
-
"start": "node dist/cli/index.js start",
|
|
25
|
-
"prepublishOnly": "npm run build"
|
|
26
|
-
},
|
|
27
|
-
"engines": {
|
|
28
|
-
"node": ">=18.0.0"
|
|
29
|
-
},
|
|
30
|
-
"author": "",
|
|
31
|
-
"license": "MIT",
|
|
32
|
-
"repository": {
|
|
33
|
-
"type": "git",
|
|
34
|
-
"url": "https://github.com/kywthiha/nextjs-agent-cli.git"
|
|
35
|
-
},
|
|
36
|
-
"dependencies": {
|
|
37
|
-
"@google/genai": "^1.34.0",
|
|
38
|
-
"chalk": "^5.0.0",
|
|
39
|
-
"commander": "^12.0.0",
|
|
40
|
-
"dotenv": "^16.0.0",
|
|
41
|
-
"inquirer": "^13.2.1",
|
|
42
|
-
"ora": "^8.2.0",
|
|
43
|
-
"typescript": "^5.0.0",
|
|
44
|
-
"zod": "^4.3.5",
|
|
45
|
-
"zod-to-json-schema": "^3.25.1"
|
|
46
|
-
},
|
|
47
|
-
"devDependencies": {
|
|
48
|
-
"@types/node": "^20.0.0",
|
|
49
|
-
"tsx": "^4.0.0"
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "kyawthiha-nextjs-agent-cli",
|
|
3
|
+
"version": "1.0.4",
|
|
4
|
+
"description": "Next.js Fullstack Agent CLI",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"nextjs",
|
|
7
|
+
"agent",
|
|
8
|
+
"ai",
|
|
9
|
+
"cli",
|
|
10
|
+
"fullstack"
|
|
11
|
+
],
|
|
12
|
+
"type": "module",
|
|
13
|
+
"main": "dist/cli/index.js",
|
|
14
|
+
"bin": {
|
|
15
|
+
"next-agent": "dist/cli/index.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "npx rimraf dist && tsc",
|
|
23
|
+
"dev": "npx rimraf dist && tsc && node dist/cli/index.js start",
|
|
24
|
+
"start": "node dist/cli/index.js start",
|
|
25
|
+
"prepublishOnly": "npm run build"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18.0.0"
|
|
29
|
+
},
|
|
30
|
+
"author": "",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://github.com/kywthiha/nextjs-agent-cli.git"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@google/genai": "^1.34.0",
|
|
38
|
+
"chalk": "^5.0.0",
|
|
39
|
+
"commander": "^12.0.0",
|
|
40
|
+
"dotenv": "^16.0.0",
|
|
41
|
+
"inquirer": "^13.2.1",
|
|
42
|
+
"ora": "^8.2.0",
|
|
43
|
+
"typescript": "^5.0.0",
|
|
44
|
+
"zod": "^4.3.5",
|
|
45
|
+
"zod-to-json-schema": "^3.25.1"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/node": "^20.0.0",
|
|
49
|
+
"tsx": "^4.0.0"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|