shark-ai 0.2.1 → 0.3.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/dist/bin/shark.js
CHANGED
|
@@ -5,9 +5,10 @@ import {
|
|
|
5
5
|
colors,
|
|
6
6
|
configCommand,
|
|
7
7
|
loginCommand,
|
|
8
|
+
t,
|
|
8
9
|
tokenStorage,
|
|
9
10
|
tui
|
|
10
|
-
} from "../chunk-
|
|
11
|
+
} from "../chunk-JQAVZJTG.js";
|
|
11
12
|
|
|
12
13
|
// src/core/error/crash-handler.ts
|
|
13
14
|
import fs from "fs";
|
|
@@ -594,7 +595,12 @@ async function getActiveRealm() {
|
|
|
594
595
|
|
|
595
596
|
// src/core/agents/business-analyst-agent.ts
|
|
596
597
|
var AGENT_TYPE = "business_analyst";
|
|
597
|
-
|
|
598
|
+
function getAgentId(overrideId) {
|
|
599
|
+
if (overrideId) return overrideId;
|
|
600
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
601
|
+
if (config.agents?.ba) return config.agents.ba;
|
|
602
|
+
return process.env.STACKSPOT_BA_AGENT_ID || "01KEJ95G304TNNAKGH5XNEEBVD";
|
|
603
|
+
}
|
|
598
604
|
async function runBusinessAnalystAgent(prompt, options = {}) {
|
|
599
605
|
const { agentId, onChunk, onComplete } = options;
|
|
600
606
|
const realm = await getActiveRealm();
|
|
@@ -612,8 +618,8 @@ async function runBusinessAnalystAgent(prompt, options = {}) {
|
|
|
612
618
|
deep_search_ks: false,
|
|
613
619
|
conversation_id: existingConversationId
|
|
614
620
|
};
|
|
615
|
-
const
|
|
616
|
-
const agentUrl = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${
|
|
621
|
+
const effectiveAgentId = getAgentId(options.agentId);
|
|
622
|
+
const agentUrl = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${effectiveAgentId}/chat`;
|
|
617
623
|
const headers = {
|
|
618
624
|
"Authorization": `Bearer ${token}`,
|
|
619
625
|
"Content-Type": "application/json"
|
|
@@ -689,7 +695,7 @@ async function interactiveBusinessAnalyst() {
|
|
|
689
695
|
if (response.actions && response.actions.length > 0) {
|
|
690
696
|
for (const action of response.actions) {
|
|
691
697
|
if (action.type === "talk_with_user") {
|
|
692
|
-
tui.log.info(colors.
|
|
698
|
+
tui.log.info(colors.success("\u{1F916} BA Agent:"));
|
|
693
699
|
console.log(action.content);
|
|
694
700
|
} else {
|
|
695
701
|
tui.log.warning(`
|
|
@@ -712,9 +718,6 @@ async function interactiveBusinessAnalyst() {
|
|
|
712
718
|
}
|
|
713
719
|
}
|
|
714
720
|
}
|
|
715
|
-
if (response.tokens) {
|
|
716
|
-
tui.log.info(`Tokens used: ${response.tokens.output || 0}`);
|
|
717
|
-
}
|
|
718
721
|
}
|
|
719
722
|
});
|
|
720
723
|
tui.outro("Session complete");
|
|
@@ -836,7 +839,12 @@ ${stdout}`);
|
|
|
836
839
|
|
|
837
840
|
// src/core/agents/specification-agent.ts
|
|
838
841
|
var AGENT_TYPE2 = "specification_agent";
|
|
839
|
-
|
|
842
|
+
function getAgentId2(overrideId) {
|
|
843
|
+
if (overrideId) return overrideId;
|
|
844
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
845
|
+
if (config.agents?.spec) return config.agents.spec;
|
|
846
|
+
return process.env.STACKSPOT_SPEC_AGENT_ID || "01KEPXTX37FTB4N672TZST4SGP";
|
|
847
|
+
}
|
|
840
848
|
async function interactiveSpecificationAgent(options = {}) {
|
|
841
849
|
FileLogger.init();
|
|
842
850
|
tui.intro("\u{1F3D7}\uFE0F Specification Agent");
|
|
@@ -1043,12 +1051,12 @@ async function callSpecAgentApi(prompt, onChunk, agentId) {
|
|
|
1043
1051
|
use_conversation: true,
|
|
1044
1052
|
conversation_id: conversationId
|
|
1045
1053
|
};
|
|
1046
|
-
const
|
|
1047
|
-
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${
|
|
1054
|
+
const effectiveAgentId = getAgentId2(agentId);
|
|
1055
|
+
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${effectiveAgentId}/chat`;
|
|
1048
1056
|
let fullMsg = "";
|
|
1049
1057
|
let raw = {};
|
|
1050
1058
|
FileLogger.log("AGENT", "Calling Agent API", {
|
|
1051
|
-
agentId:
|
|
1059
|
+
agentId: effectiveAgentId,
|
|
1052
1060
|
conversationId,
|
|
1053
1061
|
prompt: prompt.substring(0, 500)
|
|
1054
1062
|
// Log summary of prompt
|
|
@@ -1088,12 +1096,16 @@ import { Command as Command2 } from "commander";
|
|
|
1088
1096
|
import fs5 from "fs";
|
|
1089
1097
|
import path4 from "path";
|
|
1090
1098
|
var AGENT_TYPE3 = "scan_agent";
|
|
1091
|
-
|
|
1099
|
+
function getAgentId3() {
|
|
1100
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
1101
|
+
if (config.agents?.scan) return config.agents.scan;
|
|
1102
|
+
return process.env.STACKSPOT_SCAN_AGENT_ID || "01KEQ9AHWB550J2244YBH3QATN";
|
|
1103
|
+
}
|
|
1092
1104
|
async function interactiveScanAgent(options = {}) {
|
|
1093
1105
|
FileLogger.init();
|
|
1094
|
-
tui.intro("\u{1F575}\uFE0F\u200D\u2642\uFE0F Scan Agent");
|
|
1095
1106
|
const config = ConfigManager.getInstance().getConfig();
|
|
1096
1107
|
const language = config.language || "English";
|
|
1108
|
+
tui.intro(t("commands.scan.intro"));
|
|
1097
1109
|
const projectRoot = process.cwd();
|
|
1098
1110
|
let outputFile;
|
|
1099
1111
|
if (options.output) {
|
|
@@ -1116,58 +1128,295 @@ async function interactiveScanAgent(options = {}) {
|
|
|
1116
1128
|
outputFile = path4.join(outputDir, "project-context.md");
|
|
1117
1129
|
}
|
|
1118
1130
|
}
|
|
1119
|
-
tui.log.info(
|
|
1120
|
-
tui.log.info(
|
|
1121
|
-
tui.log.info(
|
|
1131
|
+
tui.log.info(`${t("commands.scan.scanningProject")} ${colors.bold(projectRoot)}`);
|
|
1132
|
+
tui.log.info(`${t("commands.scan.outputTarget")} ${colors.bold(outputFile)}`);
|
|
1133
|
+
tui.log.info(`${t("commands.scan.language")} ${colors.bold(language)}`);
|
|
1122
1134
|
const configFileRelative = path4.relative(projectRoot, outputFile);
|
|
1135
|
+
const initialTemplate = `# Project Context
|
|
1136
|
+
|
|
1137
|
+
## Overview
|
|
1138
|
+
[TO BE ANALYZED]
|
|
1139
|
+
|
|
1140
|
+
## Tech Stack
|
|
1141
|
+
[TO BE ANALYZED]
|
|
1142
|
+
|
|
1143
|
+
## Architecture
|
|
1144
|
+
[TO BE ANALYZED]
|
|
1145
|
+
|
|
1146
|
+
## Directory Structure
|
|
1147
|
+
[TO BE ANALYZED]
|
|
1148
|
+
|
|
1149
|
+
## Key Components
|
|
1150
|
+
[TO BE ANALYZED]
|
|
1151
|
+
|
|
1152
|
+
## API / Interfaces
|
|
1153
|
+
[TO BE ANALYZED]
|
|
1154
|
+
|
|
1155
|
+
## Data Layer
|
|
1156
|
+
[TO BE ANALYZED]
|
|
1157
|
+
|
|
1158
|
+
## Configuration & Environment
|
|
1159
|
+
[TO BE ANALYZED]
|
|
1160
|
+
|
|
1161
|
+
## Build & Development
|
|
1162
|
+
[TO BE ANALYZED]
|
|
1163
|
+
|
|
1164
|
+
## Key Patterns & Conventions
|
|
1165
|
+
[TO BE ANALYZED]
|
|
1166
|
+
`;
|
|
1167
|
+
if (!fs5.existsSync(outputFile)) {
|
|
1168
|
+
fs5.writeFileSync(outputFile, initialTemplate, { encoding: "utf-8" });
|
|
1169
|
+
tui.log.success(`${t("commands.scan.templateCreated")} ${outputFile}`);
|
|
1170
|
+
} else {
|
|
1171
|
+
tui.log.info(t("commands.scan.fileExists"));
|
|
1172
|
+
}
|
|
1123
1173
|
const superPrompt = `
|
|
1124
1174
|
You are the **Scan Agent**, an expert software architect and analyst.
|
|
1125
|
-
Your mission is to explore this project's codebase and generate a
|
|
1175
|
+
Your mission is to explore this project's codebase THOROUGHLY and generate a COMPREHENSIVE context file that will be used by other AI agents (specifically a Developer Agent) to understand how to work on this project.
|
|
1126
1176
|
|
|
1127
|
-
**
|
|
1177
|
+
**IMPORTANT**: The file \`${configFileRelative}\` has already been created with a template structure. Your job is to FILL IN each section by analyzing the project.
|
|
1128
1178
|
|
|
1129
1179
|
**LANGUAGE INSTRUCTION**:
|
|
1130
|
-
You MUST write the content
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
**
|
|
1140
|
-
|
|
1180
|
+
You MUST write the content in **${language}**.
|
|
1181
|
+
|
|
1182
|
+
**CRITICAL STRATEGY - INCREMENTAL UPDATES**:
|
|
1183
|
+
DO NOT try to rewrite the entire file at once! Instead:
|
|
1184
|
+
|
|
1185
|
+
1. **Explore** the project using \`list_files\`, \`read_file\`, \`search_file\`
|
|
1186
|
+
2. **Update** specific sections incrementally using \`modify_file\`
|
|
1187
|
+
3. **Benefit**: Build a MUCH MORE DETAILED document without context size limitations
|
|
1188
|
+
|
|
1189
|
+
**WORKFLOW - FILL EACH SECTION:**
|
|
1190
|
+
|
|
1191
|
+
**Step 1 - Analyze Tech Stack:**
|
|
1192
|
+
- \`list_files\` root directory to see project structure
|
|
1193
|
+
- \`read_file\` package.json (or pom.xml, go.mod, requirements.txt, etc.)
|
|
1194
|
+
- \`modify_file\` to replace:
|
|
1195
|
+
- \`target_content\`: "## Tech Stack\\n[TO BE ANALYZED]"
|
|
1196
|
+
- \`content\`: Detailed tech stack with versions, dependencies, and their purposes
|
|
1197
|
+
|
|
1198
|
+
**Step 2 - Analyze Directory Structure:**
|
|
1199
|
+
- \`list_files\` on ALL key directories (src, tests, config, docs, etc.)
|
|
1200
|
+
- Map the complete directory tree
|
|
1201
|
+
- \`modify_file\` to replace:
|
|
1202
|
+
- \`target_content\`: "## Directory Structure\\n[TO BE ANALYZED]"
|
|
1203
|
+
- \`content\`: Visual directory tree with purpose of each folder
|
|
1204
|
+
|
|
1205
|
+
**Step 3 - Analyze Architecture:**
|
|
1206
|
+
- \`read_file\` entry points (main.ts, index.js, app.py, etc.)
|
|
1207
|
+
- \`read_file\` 5-10 source files to understand code patterns and organization
|
|
1208
|
+
- Identify architectural pattern (Clean Arch, MVC, Microservices, etc.)
|
|
1209
|
+
- \`modify_file\` to replace:
|
|
1210
|
+
- \`target_content\`: "## Architecture\\n[TO BE ANALYZED]"
|
|
1211
|
+
- \`content\`: Comprehensive architectural description with patterns and module organization
|
|
1212
|
+
|
|
1213
|
+
**Step 4 - Document Components:**
|
|
1214
|
+
- Identify ALL major modules/components by reading source files
|
|
1215
|
+
- For each component: location, purpose, key files
|
|
1216
|
+
- \`modify_file\` to replace:
|
|
1217
|
+
- \`target_content\`: "## Key Components\\n[TO BE ANALYZED]"
|
|
1218
|
+
- \`content\`: Detailed list of components with their purposes
|
|
1219
|
+
|
|
1220
|
+
**Step 5 - Document APIs (if applicable):**
|
|
1221
|
+
- Search for route definitions, controllers, API endpoints
|
|
1222
|
+
- Document base URL, main endpoints, request/response patterns
|
|
1223
|
+
- \`modify_file\` to replace:
|
|
1224
|
+
- \`target_content\`: "## API / Interfaces\\n[TO BE ANALYZED]"
|
|
1225
|
+
- \`content\`: API documentation (or "Not applicable" if no API)
|
|
1226
|
+
|
|
1227
|
+
**Step 6 - Document Data Layer (if applicable):**
|
|
1228
|
+
- Search for database configs, ORM setup, model definitions
|
|
1229
|
+
- Document database type, ORM tool, key entities/tables
|
|
1230
|
+
- \`modify_file\` to replace:
|
|
1231
|
+
- \`target_content\`: "## Data Layer\\n[TO BE ANALYZED]"
|
|
1232
|
+
- \`content\`: Data layer details (or "Not applicable" if no database)
|
|
1233
|
+
|
|
1234
|
+
**Step 7 - Configuration & Environment:**
|
|
1235
|
+
- Read config files (.env.example, config/, etc.)
|
|
1236
|
+
- Identify environment variables and their purposes
|
|
1237
|
+
- \`modify_file\` to replace:
|
|
1238
|
+
- \`target_content\`: "## Configuration & Environment\\n[TO BE ANALYZED]"
|
|
1239
|
+
- \`content\`: List of env vars and config files
|
|
1240
|
+
|
|
1241
|
+
**Step 8 - Build & Development:**
|
|
1242
|
+
- Read package.json scripts, Makefile, build configs
|
|
1243
|
+
- Document dev, build, test, lint commands
|
|
1244
|
+
- \`modify_file\` to replace:
|
|
1245
|
+
- \`target_content\`: "## Build & Development\\n[TO BE ANALYZED]"
|
|
1246
|
+
- \`content\`: Commands for development workflow
|
|
1247
|
+
|
|
1248
|
+
**Step 9 - Patterns & Conventions:**
|
|
1249
|
+
- Based on files read, document naming conventions, code organization
|
|
1250
|
+
- Note error handling, logging strategies
|
|
1251
|
+
- \`modify_file\` to replace:
|
|
1252
|
+
- \`target_content\`: "## Key Patterns & Conventions\\n[TO BE ANALYZED]"
|
|
1253
|
+
- \`content\`: Observed patterns and conventions
|
|
1254
|
+
|
|
1255
|
+
**Step 10 - Overview (LAST):**
|
|
1256
|
+
- Synthesize all findings into a comprehensive overview
|
|
1257
|
+
- \`modify_file\` to replace:
|
|
1258
|
+
- \`target_content\`: "## Overview\\n[TO BE ANALYZED]"
|
|
1259
|
+
- \`content\`: Detailed project description with purpose and main functionality
|
|
1260
|
+
|
|
1261
|
+
**HOW TO USE modify_file:**
|
|
1262
|
+
\`\`\`json
|
|
1263
|
+
{
|
|
1264
|
+
"actions": [{
|
|
1265
|
+
"type": "modify_file",
|
|
1266
|
+
"path": "${configFileRelative}",
|
|
1267
|
+
"target_content": "## Tech Stack\\n[TO BE ANALYZED]",
|
|
1268
|
+
"content": "## Tech Stack\\n- **Language**: TypeScript 5.3\\n- **Runtime**: Node.js 20.x\\n..."
|
|
1269
|
+
}]
|
|
1270
|
+
}
|
|
1271
|
+
\`\`\`
|
|
1141
1272
|
|
|
1273
|
+
\`\`\`markdown
|
|
1142
1274
|
# Project Context
|
|
1143
1275
|
|
|
1144
1276
|
## Overview
|
|
1145
|
-
[
|
|
1277
|
+
[TO BE ANALYZED]
|
|
1146
1278
|
|
|
1147
1279
|
## Tech Stack
|
|
1148
|
-
|
|
1149
|
-
- **Framework**: [e.g. React, Express, NestJS]
|
|
1150
|
-
- **Build Tool**: [e.g. Vite, Webpack]
|
|
1151
|
-
- **Database**: [e.g. PostgreSQL, Prisma] (if detected)
|
|
1280
|
+
[TO BE ANALYZED]
|
|
1152
1281
|
|
|
1153
1282
|
## Architecture
|
|
1154
|
-
[
|
|
1283
|
+
[TO BE ANALYZED]
|
|
1155
1284
|
|
|
1156
|
-
##
|
|
1157
|
-
|
|
1158
|
-
- **Tests**: [path/to/tests]
|
|
1159
|
-
- **Config**: [path/to/config]
|
|
1285
|
+
## Directory Structure
|
|
1286
|
+
[TO BE ANALYZED]
|
|
1160
1287
|
|
|
1161
|
-
##
|
|
1162
|
-
[
|
|
1288
|
+
## Key Components
|
|
1289
|
+
[TO BE ANALYZED]
|
|
1163
1290
|
|
|
1164
|
-
|
|
1291
|
+
## API / Interfaces
|
|
1292
|
+
[TO BE ANALYZED]
|
|
1293
|
+
|
|
1294
|
+
## Data Layer
|
|
1295
|
+
[TO BE ANALYZED]
|
|
1296
|
+
|
|
1297
|
+
## Configuration & Environment
|
|
1298
|
+
[TO BE ANALYZED]
|
|
1299
|
+
|
|
1300
|
+
## Build & Development
|
|
1301
|
+
[TO BE ANALYZED]
|
|
1302
|
+
|
|
1303
|
+
## Key Patterns & Conventions
|
|
1304
|
+
[TO BE ANALYZED]
|
|
1305
|
+
\`\`\`
|
|
1306
|
+
|
|
1307
|
+
**Step 2 - Explore and Update Incrementally:**
|
|
1308
|
+
After creating the template, perform these analyses and UPDATE each section:
|
|
1309
|
+
|
|
1310
|
+
**2.1 - Analyze Tech Stack:**
|
|
1311
|
+
- \`list_files\` root directory
|
|
1312
|
+
- \`read_file\` package.json (or equivalent manifest)
|
|
1313
|
+
- \`modify_file\` to replace "## Tech Stack\\n[TO BE ANALYZED]" with detailed findings
|
|
1314
|
+
|
|
1315
|
+
**2.2 - Analyze Directory Structure:**
|
|
1316
|
+
- \`list_files\` on key directories (src, tests, config, etc.)
|
|
1317
|
+
- \`modify_file\` to replace "## Directory Structure\\n[TO BE ANALYZED]" with complete structure
|
|
1318
|
+
|
|
1319
|
+
**2.3 - Analyze Architecture:**
|
|
1320
|
+
- \`read_file\` entry points (main.ts, index.js, etc.)
|
|
1321
|
+
- \`read_file\` 5-10 source files to understand patterns
|
|
1322
|
+
- \`modify_file\` to replace "## Architecture\\n[TO BE ANALYZED]" with architectural insights
|
|
1165
1323
|
|
|
1166
|
-
**
|
|
1167
|
-
-
|
|
1168
|
-
-
|
|
1169
|
-
|
|
1170
|
-
-
|
|
1324
|
+
**2.4 - Document Components:**
|
|
1325
|
+
- Identify major modules/components
|
|
1326
|
+
- \`modify_file\` to replace "## Key Components\\n[TO BE ANALYZED]" with component details
|
|
1327
|
+
|
|
1328
|
+
**2.5 - Document APIs (if applicable):**
|
|
1329
|
+
- Search for route definitions, controllers, API endpoints
|
|
1330
|
+
- \`modify_file\` to replace "## API / Interfaces\\n[TO BE ANALYZED]"
|
|
1331
|
+
|
|
1332
|
+
**2.6 - Document Data Layer (if applicable):**
|
|
1333
|
+
- Search for database configs, ORM, models
|
|
1334
|
+
- \`modify_file\` to replace "## Data Layer\\n[TO BE ANALYZED]"
|
|
1335
|
+
|
|
1336
|
+
**2.7 - Final Touches:**
|
|
1337
|
+
- Update remaining sections (Config, Build, Patterns)
|
|
1338
|
+
- Ensure Overview is comprehensive
|
|
1339
|
+
|
|
1340
|
+
**HOW TO USE modify_file:**
|
|
1341
|
+
\`\`\`json
|
|
1342
|
+
{
|
|
1343
|
+
"actions": [{
|
|
1344
|
+
"type": "modify_file",
|
|
1345
|
+
"path": "${configFileRelative}",
|
|
1346
|
+
"target_content": "## Tech Stack\\n[TO BE ANALYZED]",
|
|
1347
|
+
"content": "## Tech Stack\\n- **Language**: TypeScript 5.3\\n- **Runtime**: Node.js 20.x\\n- **Framework**: Express 4.18\\n..."
|
|
1348
|
+
}]
|
|
1349
|
+
}
|
|
1350
|
+
\`\`\`
|
|
1351
|
+
|
|
1352
|
+
**SECTION TEMPLATES (For your updates):**
|
|
1353
|
+
|
|
1354
|
+
**Tech Stack:**
|
|
1355
|
+
\`\`\`markdown
|
|
1356
|
+
## Tech Stack
|
|
1357
|
+
- **Language**: [name + version]
|
|
1358
|
+
- **Runtime**: [name + version]
|
|
1359
|
+
- **Framework**: [name + version]
|
|
1360
|
+
- **Build Tool**: [name]
|
|
1361
|
+
- **Testing**: [framework]
|
|
1362
|
+
- **Key Dependencies**:
|
|
1363
|
+
- [dep-name]: [purpose]
|
|
1364
|
+
- [dep-name]: [purpose]
|
|
1365
|
+
\`\`\`
|
|
1366
|
+
|
|
1367
|
+
**Architecture:**
|
|
1368
|
+
\`\`\`markdown
|
|
1369
|
+
## Architecture
|
|
1370
|
+
[Comprehensive description]
|
|
1371
|
+
- **Pattern**: [Clean Arch, MVC, etc.]
|
|
1372
|
+
- **Module Organization**: [how modules are structured]
|
|
1373
|
+
- **Layer Separation**: [controllers, services, repos]
|
|
1374
|
+
- **Configuration**: [how config is managed]
|
|
1375
|
+
\`\`\`
|
|
1376
|
+
|
|
1377
|
+
**Directory Structure:**
|
|
1378
|
+
\`\`\`markdown
|
|
1379
|
+
## Directory Structure
|
|
1380
|
+
\\\`\\\`\\\`
|
|
1381
|
+
/src
|
|
1382
|
+
/core - [Purpose]
|
|
1383
|
+
/commands - [Purpose]
|
|
1384
|
+
/ui - [Purpose]
|
|
1385
|
+
/tests - [Purpose]
|
|
1386
|
+
/docs - [Purpose]
|
|
1387
|
+
\\\`\\\`\\\`
|
|
1388
|
+
\`\`\`
|
|
1389
|
+
|
|
1390
|
+
**Key Components:**
|
|
1391
|
+
\`\`\`markdown
|
|
1392
|
+
## Key Components
|
|
1393
|
+
|
|
1394
|
+
### [Component Name 1]
|
|
1395
|
+
- **Location**: \\\`path/to/component\\\`
|
|
1396
|
+
- **Purpose**: [What it does]
|
|
1397
|
+
- **Key Files**: [Important files]
|
|
1398
|
+
|
|
1399
|
+
### [Component Name 2]
|
|
1400
|
+
- **Location**: \\\`path/to/component\\\`
|
|
1401
|
+
- **Purpose**: [What it does]
|
|
1402
|
+
- **Key Files**: [Important files]
|
|
1403
|
+
\`\`\`
|
|
1404
|
+
|
|
1405
|
+
**DEPTH REQUIREMENT**:
|
|
1406
|
+
- Read MULTIPLE files (5-10 minimum) to understand patterns
|
|
1407
|
+
- Identify ALL major modules/components
|
|
1408
|
+
- Document API routes, database schemas if applicable
|
|
1409
|
+
- Note design patterns and architectural decisions
|
|
1410
|
+
- List important dependencies with their purposes
|
|
1411
|
+
|
|
1412
|
+
**RULES**:
|
|
1413
|
+
- Create template FIRST (step 1)
|
|
1414
|
+
- Update sections INCREMENTALLY (steps 2-7)
|
|
1415
|
+
- Do NOT wait to write everything at the end
|
|
1416
|
+
- Use \`modify_file\` to replace "[TO BE ANALYZED]" sections
|
|
1417
|
+
- Be DETAILED and COMPREHENSIVE
|
|
1418
|
+
- Take your time - you have up to 30 steps
|
|
1419
|
+
- Verify facts with \`read_file\` or \`search_file\` before documenting
|
|
1171
1420
|
`.trim();
|
|
1172
1421
|
await runScanLoop(superPrompt, outputFile);
|
|
1173
1422
|
}
|
|
@@ -1175,38 +1424,39 @@ async function runScanLoop(initialPrompt, targetPath) {
|
|
|
1175
1424
|
let nextPrompt = initialPrompt;
|
|
1176
1425
|
let keepGoing = true;
|
|
1177
1426
|
let stepCount = 0;
|
|
1178
|
-
const MAX_STEPS =
|
|
1427
|
+
const MAX_STEPS = 30;
|
|
1179
1428
|
while (keepGoing && stepCount < MAX_STEPS) {
|
|
1180
1429
|
stepCount++;
|
|
1181
1430
|
const spinner = tui.spinner();
|
|
1182
|
-
|
|
1431
|
+
const msg = t("commands.scan.analyzing").replace("{step}", stepCount.toString());
|
|
1432
|
+
spinner.start(msg);
|
|
1183
1433
|
let responseText = "";
|
|
1184
1434
|
let lastResponse = null;
|
|
1185
1435
|
try {
|
|
1186
1436
|
lastResponse = await callScanAgentApi(nextPrompt, (chunk) => {
|
|
1187
1437
|
responseText += chunk;
|
|
1188
1438
|
});
|
|
1189
|
-
spinner.stop("
|
|
1190
|
-
if (lastResponse && lastResponse.actions) {
|
|
1439
|
+
spinner.stop(t("commands.scan.stepComplete"));
|
|
1440
|
+
if (lastResponse && lastResponse.actions && lastResponse.actions.length > 0) {
|
|
1191
1441
|
let executionResults = "";
|
|
1192
1442
|
let fileCreated = false;
|
|
1193
1443
|
for (const action of lastResponse.actions) {
|
|
1194
1444
|
if (action.type === "list_files") {
|
|
1195
|
-
tui.log.info(
|
|
1445
|
+
tui.log.info(t("commands.scan.scanningDir").replace("{0}", colors.bold(action.path || ".")));
|
|
1196
1446
|
const result = handleListFiles(action.path || ".");
|
|
1197
1447
|
executionResults += `[Action list_files(${action.path}) Result]:
|
|
1198
1448
|
${result}
|
|
1199
1449
|
|
|
1200
1450
|
`;
|
|
1201
1451
|
} else if (action.type === "read_file") {
|
|
1202
|
-
tui.log.info(
|
|
1452
|
+
tui.log.info(t("commands.scan.readingFile").replace("{0}", colors.bold(action.path || "")));
|
|
1203
1453
|
const result = handleReadFile(action.path || "");
|
|
1204
1454
|
executionResults += `[Action read_file(${action.path}) Result]:
|
|
1205
1455
|
${result}
|
|
1206
1456
|
|
|
1207
1457
|
`;
|
|
1208
1458
|
} else if (action.type === "search_file") {
|
|
1209
|
-
tui.log.info(
|
|
1459
|
+
tui.log.info(t("commands.scan.searching").replace("{0}", colors.bold(action.path || "")));
|
|
1210
1460
|
const result = handleSearchFile(action.path || "");
|
|
1211
1461
|
executionResults += `[Action search_file(${action.path}) Result]:
|
|
1212
1462
|
${result}
|
|
@@ -1217,7 +1467,7 @@ ${result}
|
|
|
1217
1467
|
const resolvedTargetPath = path4.resolve(targetPath);
|
|
1218
1468
|
let isTarget = resolvedActionPath === resolvedTargetPath;
|
|
1219
1469
|
if (!isTarget && path4.basename(action.path || "") === "project-context.md") {
|
|
1220
|
-
tui.log.warning(
|
|
1470
|
+
tui.log.warning(t("commands.scan.targetRedirect").replace("{0}", action.path || "").replace("{1}", path4.relative(process.cwd(), targetPath)));
|
|
1221
1471
|
isTarget = true;
|
|
1222
1472
|
action.path = targetPath;
|
|
1223
1473
|
}
|
|
@@ -1225,44 +1475,75 @@ ${result}
|
|
|
1225
1475
|
const finalPath = targetPath;
|
|
1226
1476
|
if (action.type === "create_file") {
|
|
1227
1477
|
fs5.writeFileSync(finalPath, action.content || "");
|
|
1228
|
-
tui.log.success(
|
|
1478
|
+
tui.log.success(t("commands.scan.generated").replace("{0}", finalPath));
|
|
1229
1479
|
fileCreated = true;
|
|
1230
1480
|
} else {
|
|
1231
|
-
fs5.
|
|
1232
|
-
|
|
1233
|
-
|
|
1481
|
+
if (fs5.existsSync(finalPath)) {
|
|
1482
|
+
const currentContent = fs5.readFileSync(finalPath, "utf-8");
|
|
1483
|
+
if (action.target_content && currentContent.includes(action.target_content)) {
|
|
1484
|
+
const newContent = currentContent.replace(action.target_content, action.content || "");
|
|
1485
|
+
fs5.writeFileSync(finalPath, newContent, { encoding: "utf-8" });
|
|
1486
|
+
tui.log.success(t("commands.scan.updated").replace("{0}", finalPath));
|
|
1487
|
+
fileCreated = true;
|
|
1488
|
+
} else {
|
|
1489
|
+
tui.log.warning(t("commands.scan.error") + ": " + t("commands.scan.contentNotFound"));
|
|
1490
|
+
executionResults += `[Action ${action.type}]: Failed. Target content not found in file.
|
|
1491
|
+
`;
|
|
1492
|
+
fileCreated = false;
|
|
1493
|
+
}
|
|
1494
|
+
} else {
|
|
1495
|
+
tui.log.warning(t("commands.scan.error") + ": " + t("commands.scan.notFound"));
|
|
1496
|
+
}
|
|
1234
1497
|
}
|
|
1235
1498
|
executionResults += `[Action ${action.type}]: Success. Task Completed.
|
|
1236
1499
|
`;
|
|
1237
1500
|
} else {
|
|
1238
|
-
tui.log.warning(
|
|
1239
|
-
executionResults += `[Action ${action.type}]:
|
|
1501
|
+
tui.log.warning(t("commands.scan.error"));
|
|
1502
|
+
executionResults += `[Action ${action.type}]: ${t("commands.scan.skipped")}
|
|
1240
1503
|
`;
|
|
1241
1504
|
}
|
|
1242
1505
|
} else if (action.type === "talk_with_user") {
|
|
1243
|
-
tui.log.info(colors.primary("
|
|
1506
|
+
tui.log.info(colors.primary(t("commands.scan.agentAsks")));
|
|
1244
1507
|
console.log(action.content);
|
|
1245
|
-
const reply = await tui.text({ message: "
|
|
1508
|
+
const reply = await tui.text({ message: t("commands.scan.agentInput"), placeholder: t("commands.scan.replyPlaceholder") });
|
|
1246
1509
|
executionResults += `[User Reply]: ${reply}
|
|
1247
1510
|
`;
|
|
1248
1511
|
}
|
|
1249
1512
|
}
|
|
1250
1513
|
if (fileCreated) {
|
|
1251
|
-
|
|
1252
|
-
|
|
1514
|
+
const currentContent = fs5.readFileSync(targetPath, "utf-8");
|
|
1515
|
+
const pendingSections = [];
|
|
1516
|
+
const lines = currentContent.split("\n");
|
|
1517
|
+
let currentSection = "";
|
|
1518
|
+
for (const line of lines) {
|
|
1519
|
+
if (line.startsWith("## ")) {
|
|
1520
|
+
currentSection = line.substring(3).trim();
|
|
1521
|
+
}
|
|
1522
|
+
if (line.includes("[TO BE ANALYZED]")) {
|
|
1523
|
+
if (currentSection && !pendingSections.includes(currentSection)) {
|
|
1524
|
+
pendingSections.push(currentSection);
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
const pendingMsg = pendingSections.length > 0 ? `
|
|
1529
|
+
|
|
1530
|
+
[System Helper]: ${t("commands.scan.pendingSections").replace("{0}", pendingSections.join(", "))}` : `
|
|
1531
|
+
|
|
1532
|
+
[System Helper]: ${t("commands.scan.allPopulated")}`;
|
|
1533
|
+
nextPrompt = `${executionResults}
|
|
1534
|
+
|
|
1535
|
+
[System]: File updated successfully.${pendingMsg} Please continue with the next step of the analysis and focus on the pending sections.`;
|
|
1536
|
+
FileLogger.log("SCAN", "Section updated, continuing loop", { step: stepCount, pending: pendingSections.length });
|
|
1253
1537
|
} else {
|
|
1254
1538
|
nextPrompt = executionResults;
|
|
1255
1539
|
FileLogger.log("SCAN", "Auto-replying with results", { length: executionResults.length });
|
|
1256
1540
|
}
|
|
1257
1541
|
} else {
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
keepGoing = false;
|
|
1261
|
-
} else {
|
|
1262
|
-
}
|
|
1542
|
+
tui.log.success(t("commands.scan.completed"));
|
|
1543
|
+
keepGoing = false;
|
|
1263
1544
|
}
|
|
1264
1545
|
} catch (error) {
|
|
1265
|
-
spinner.stop("
|
|
1546
|
+
spinner.stop(t("common.error"));
|
|
1266
1547
|
tui.log.error(error.message);
|
|
1267
1548
|
keepGoing = false;
|
|
1268
1549
|
}
|
|
@@ -1281,7 +1562,7 @@ async function callScanAgentApi(prompt, onChunk) {
|
|
|
1281
1562
|
use_conversation: true,
|
|
1282
1563
|
conversation_id: conversationId
|
|
1283
1564
|
};
|
|
1284
|
-
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${
|
|
1565
|
+
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${getAgentId3()}/chat`;
|
|
1285
1566
|
let fullMsg = "";
|
|
1286
1567
|
let raw = {};
|
|
1287
1568
|
FileLogger.log("SCAN", "Calling API", { promptLength: prompt.length });
|
|
@@ -1325,11 +1606,18 @@ import { Command as Command3 } from "commander";
|
|
|
1325
1606
|
import fs6 from "fs";
|
|
1326
1607
|
import path5 from "path";
|
|
1327
1608
|
var AGENT_TYPE4 = "developer_agent";
|
|
1328
|
-
|
|
1609
|
+
function getAgentId4(overrideId) {
|
|
1610
|
+
if (overrideId) return overrideId;
|
|
1611
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
1612
|
+
if (config.agents?.dev) return config.agents.dev;
|
|
1613
|
+
if (process.env.STACKSPOT_DEV_AGENT_ID) return process.env.STACKSPOT_DEV_AGENT_ID;
|
|
1614
|
+
return "01KEQCGJ65YENRA4QBXVN1YFFX";
|
|
1615
|
+
}
|
|
1329
1616
|
async function interactiveDeveloperAgent(options = {}) {
|
|
1330
1617
|
FileLogger.init();
|
|
1331
1618
|
tui.intro("\u{1F988} Shark Dev Agent");
|
|
1332
|
-
|
|
1619
|
+
const agentId = getAgentId4();
|
|
1620
|
+
if (agentId === "PENDING_CONFIGURATION") {
|
|
1333
1621
|
tui.log.error("\u274C STACKSPOT_DEV_AGENT_ID not configured in .env");
|
|
1334
1622
|
return;
|
|
1335
1623
|
}
|
|
@@ -1525,7 +1813,7 @@ async function callDevAgentApi(prompt, onChunk) {
|
|
|
1525
1813
|
stackspot_knowledge: false
|
|
1526
1814
|
// Dev Agent focuses on project context
|
|
1527
1815
|
};
|
|
1528
|
-
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${
|
|
1816
|
+
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${getAgentId4()}/chat`;
|
|
1529
1817
|
let fullMsg = "";
|
|
1530
1818
|
let raw = {};
|
|
1531
1819
|
await sseClient.streamAgentResponse(url, payload, { "Authorization": `Bearer ${token}`, "Content-Type": "application/json" }, {
|
|
@@ -1565,7 +1853,11 @@ import path6 from "path";
|
|
|
1565
1853
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
1566
1854
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
1567
1855
|
var AGENT_TYPE5 = "qa_agent";
|
|
1568
|
-
|
|
1856
|
+
function getAgentId5() {
|
|
1857
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
1858
|
+
if (config.agents?.qa) return config.agents.qa;
|
|
1859
|
+
return process.env.STACKSPOT_QA_AGENT_ID || "01KEQFJZ3Q3JER11NH22HEZX9X";
|
|
1860
|
+
}
|
|
1569
1861
|
var ChromeDevToolsClient = class {
|
|
1570
1862
|
client = null;
|
|
1571
1863
|
transport = null;
|
|
@@ -1609,7 +1901,8 @@ var ChromeDevToolsClient = class {
|
|
|
1609
1901
|
};
|
|
1610
1902
|
var mcpClient = new ChromeDevToolsClient();
|
|
1611
1903
|
async function runQAAgent(options) {
|
|
1612
|
-
|
|
1904
|
+
const agentId = getAgentId5();
|
|
1905
|
+
if (!agentId) {
|
|
1613
1906
|
tui.log.error("\u274C STACKSPOT_QA_AGENT_ID not configured.");
|
|
1614
1907
|
tui.log.info("Please run: set STACKSPOT_QA_AGENT_ID=<your-id>");
|
|
1615
1908
|
return;
|
|
@@ -1655,7 +1948,7 @@ ${projectContext}
|
|
|
1655
1948
|
try {
|
|
1656
1949
|
const existingConversationId = await conversationManager.getConversationId(AGENT_TYPE5);
|
|
1657
1950
|
await sseClient.streamAgentResponse(
|
|
1658
|
-
`https://genai-inference-app.stackspot.com/v1/agent/${
|
|
1951
|
+
`https://genai-inference-app.stackspot.com/v1/agent/${getAgentId5()}/chat`,
|
|
1659
1952
|
{
|
|
1660
1953
|
user_prompt: userMessage,
|
|
1661
1954
|
streaming: true,
|