shark-ai 0.2.0 → 0.3.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/dist/bin/shark.js +101 -108
- package/dist/bin/shark.js.map +1 -1
- package/dist/{chunk-4UPBRJYA.js → chunk-HJYP3WB3.js} +411 -174
- package/dist/chunk-HJYP3WB3.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-4UPBRJYA.js.map +0 -1
package/dist/bin/shark.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ConfigManager,
|
|
4
|
+
FileLogger,
|
|
4
5
|
colors,
|
|
5
6
|
configCommand,
|
|
6
7
|
loginCommand,
|
|
7
8
|
tokenStorage,
|
|
8
9
|
tui
|
|
9
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-HJYP3WB3.js";
|
|
10
11
|
|
|
11
12
|
// src/core/error/crash-handler.ts
|
|
12
13
|
import fs from "fs";
|
|
@@ -267,41 +268,6 @@ var initCommand = new Command("init").description("Initialize a new Shark projec
|
|
|
267
268
|
// src/core/api/stackspot-client.ts
|
|
268
269
|
var STACKSPOT_AGENT_API_BASE = "https://genai-inference-app.stackspot.com";
|
|
269
270
|
|
|
270
|
-
// src/core/debug/file-logger.ts
|
|
271
|
-
import fs3 from "fs";
|
|
272
|
-
import path3 from "path";
|
|
273
|
-
var FileLogger = class {
|
|
274
|
-
static logPath = path3.resolve(process.cwd(), "shark-debug.log");
|
|
275
|
-
static enabled = true;
|
|
276
|
-
// Enabled by default for this debugging session
|
|
277
|
-
static init() {
|
|
278
|
-
try {
|
|
279
|
-
fs3.writeFileSync(this.logPath, `--- Shark CLI Debug Log Started at ${(/* @__PURE__ */ new Date()).toISOString()} ---
|
|
280
|
-
`);
|
|
281
|
-
} catch (e) {
|
|
282
|
-
console.error("Failed to initialize debug log:", e);
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
static log(category, message, data) {
|
|
286
|
-
if (!this.enabled) return;
|
|
287
|
-
try {
|
|
288
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
289
|
-
let logEntry = `[${timestamp}] [${category.toUpperCase()}] ${message}
|
|
290
|
-
`;
|
|
291
|
-
if (data !== void 0) {
|
|
292
|
-
if (typeof data === "object") {
|
|
293
|
-
logEntry += JSON.stringify(data, null, 2) + "\n";
|
|
294
|
-
} else {
|
|
295
|
-
logEntry += String(data) + "\n";
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
logEntry += "-".repeat(40) + "\n";
|
|
299
|
-
fs3.appendFileSync(this.logPath, logEntry);
|
|
300
|
-
} catch (e) {
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
};
|
|
304
|
-
|
|
305
271
|
// src/core/api/sse-client.ts
|
|
306
272
|
var SSEClient = class {
|
|
307
273
|
/**
|
|
@@ -628,7 +594,12 @@ async function getActiveRealm() {
|
|
|
628
594
|
|
|
629
595
|
// src/core/agents/business-analyst-agent.ts
|
|
630
596
|
var AGENT_TYPE = "business_analyst";
|
|
631
|
-
|
|
597
|
+
function getAgentId(overrideId) {
|
|
598
|
+
if (overrideId) return overrideId;
|
|
599
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
600
|
+
if (config.agents?.ba) return config.agents.ba;
|
|
601
|
+
return process.env.STACKSPOT_BA_AGENT_ID || "01KEJ95G304TNNAKGH5XNEEBVD";
|
|
602
|
+
}
|
|
632
603
|
async function runBusinessAnalystAgent(prompt, options = {}) {
|
|
633
604
|
const { agentId, onChunk, onComplete } = options;
|
|
634
605
|
const realm = await getActiveRealm();
|
|
@@ -646,8 +617,8 @@ async function runBusinessAnalystAgent(prompt, options = {}) {
|
|
|
646
617
|
deep_search_ks: false,
|
|
647
618
|
conversation_id: existingConversationId
|
|
648
619
|
};
|
|
649
|
-
const
|
|
650
|
-
const agentUrl = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${
|
|
620
|
+
const effectiveAgentId = getAgentId(options.agentId);
|
|
621
|
+
const agentUrl = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${effectiveAgentId}/chat`;
|
|
651
622
|
const headers = {
|
|
652
623
|
"Authorization": `Bearer ${token}`,
|
|
653
624
|
"Content-Type": "application/json"
|
|
@@ -760,17 +731,17 @@ async function interactiveBusinessAnalyst() {
|
|
|
760
731
|
}
|
|
761
732
|
|
|
762
733
|
// src/core/agents/specification-agent.ts
|
|
763
|
-
import
|
|
734
|
+
import fs4 from "fs";
|
|
764
735
|
|
|
765
736
|
// src/core/agents/agent-tools.ts
|
|
766
|
-
import
|
|
767
|
-
import
|
|
737
|
+
import fs3 from "fs";
|
|
738
|
+
import path3 from "path";
|
|
768
739
|
import fg from "fast-glob";
|
|
769
740
|
function handleListFiles(dirPath) {
|
|
770
741
|
try {
|
|
771
|
-
const fullPath =
|
|
772
|
-
if (!
|
|
773
|
-
const items =
|
|
742
|
+
const fullPath = path3.resolve(process.cwd(), dirPath);
|
|
743
|
+
if (!fs3.existsSync(fullPath)) return `Error: Directory ${dirPath} does not exist.`;
|
|
744
|
+
const items = fs3.readdirSync(fullPath, { withFileTypes: true });
|
|
774
745
|
return items.map((item) => {
|
|
775
746
|
return `${item.isDirectory() ? "[DIR]" : "[FILE]"} ${item.name}`;
|
|
776
747
|
}).join("\n");
|
|
@@ -780,11 +751,11 @@ function handleListFiles(dirPath) {
|
|
|
780
751
|
}
|
|
781
752
|
function handleReadFile(filePath) {
|
|
782
753
|
try {
|
|
783
|
-
const fullPath =
|
|
784
|
-
if (!
|
|
785
|
-
const stats =
|
|
754
|
+
const fullPath = path3.resolve(process.cwd(), filePath);
|
|
755
|
+
if (!fs3.existsSync(fullPath)) return `Error: File ${filePath} does not exist.`;
|
|
756
|
+
const stats = fs3.statSync(fullPath);
|
|
786
757
|
if (stats.size > 100 * 1024) return `Error: File too large to read (${stats.size} bytes). Limit is 100KB.`;
|
|
787
|
-
return
|
|
758
|
+
return fs3.readFileSync(fullPath, "utf-8");
|
|
788
759
|
} catch (e) {
|
|
789
760
|
return `Error reading file: ${e.message}`;
|
|
790
761
|
}
|
|
@@ -799,11 +770,11 @@ function handleSearchFile(pattern) {
|
|
|
799
770
|
}
|
|
800
771
|
}
|
|
801
772
|
function startSmartReplace(filePath, newContent, targetContent, tui2) {
|
|
802
|
-
if (!
|
|
773
|
+
if (!fs3.existsSync(filePath)) {
|
|
803
774
|
tui2.log.error(`\u274C File not found for modification: ${filePath}`);
|
|
804
775
|
return false;
|
|
805
776
|
}
|
|
806
|
-
const currentFileContent =
|
|
777
|
+
const currentFileContent = fs3.readFileSync(filePath, "utf-8");
|
|
807
778
|
if (!currentFileContent.includes(targetContent)) {
|
|
808
779
|
tui2.log.error(`\u274C Target content not found in ${filePath}. Modification aborted.`);
|
|
809
780
|
console.log(colors.dim("--- Target Content Expected ---"));
|
|
@@ -816,7 +787,7 @@ function startSmartReplace(filePath, newContent, targetContent, tui2) {
|
|
|
816
787
|
return false;
|
|
817
788
|
}
|
|
818
789
|
const updatedContent = currentFileContent.replace(targetContent, newContent);
|
|
819
|
-
|
|
790
|
+
fs3.writeFileSync(filePath, updatedContent);
|
|
820
791
|
tui2.log.success(`\u2705 Smart Replace Applied: ${filePath}`);
|
|
821
792
|
return true;
|
|
822
793
|
}
|
|
@@ -870,28 +841,33 @@ ${stdout}`);
|
|
|
870
841
|
|
|
871
842
|
// src/core/agents/specification-agent.ts
|
|
872
843
|
var AGENT_TYPE2 = "specification_agent";
|
|
873
|
-
|
|
844
|
+
function getAgentId2(overrideId) {
|
|
845
|
+
if (overrideId) return overrideId;
|
|
846
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
847
|
+
if (config.agents?.spec) return config.agents.spec;
|
|
848
|
+
return process.env.STACKSPOT_SPEC_AGENT_ID || "01KEPXTX37FTB4N672TZST4SGP";
|
|
849
|
+
}
|
|
874
850
|
async function interactiveSpecificationAgent(options = {}) {
|
|
875
851
|
FileLogger.init();
|
|
876
852
|
tui.intro("\u{1F3D7}\uFE0F Specification Agent");
|
|
877
853
|
let briefingContent = "";
|
|
878
854
|
let briefingPath = options.briefingPath;
|
|
879
855
|
if (!briefingPath) {
|
|
880
|
-
const files =
|
|
856
|
+
const files = fs4.readdirSync(process.cwd());
|
|
881
857
|
const defaultBriefing = files.find((f) => f.endsWith("_briefing.md"));
|
|
882
858
|
briefingPath = await tui.text({
|
|
883
859
|
message: "Path to Briefing file (Leave empty to skip)",
|
|
884
860
|
initialValue: defaultBriefing || "",
|
|
885
861
|
placeholder: "e.g., todo-list_briefing.md",
|
|
886
862
|
validate: (val) => {
|
|
887
|
-
if (val && !
|
|
863
|
+
if (val && !fs4.existsSync(val)) return "File not found";
|
|
888
864
|
}
|
|
889
865
|
});
|
|
890
866
|
}
|
|
891
867
|
if (tui.isCancel(briefingPath)) return;
|
|
892
868
|
if (briefingPath) {
|
|
893
869
|
try {
|
|
894
|
-
briefingContent =
|
|
870
|
+
briefingContent = fs4.readFileSync(briefingPath, "utf-8");
|
|
895
871
|
tui.log.info(`Loaded briefing: ${colors.bold(briefingPath)}`);
|
|
896
872
|
} catch (e) {
|
|
897
873
|
tui.log.error(`Failed to read briefing: ${e}`);
|
|
@@ -980,7 +956,7 @@ ${result}
|
|
|
980
956
|
if (action.path) {
|
|
981
957
|
try {
|
|
982
958
|
if (action.type === "create_file") {
|
|
983
|
-
|
|
959
|
+
fs4.writeFileSync(action.path, action.content || "");
|
|
984
960
|
tui.log.success(`\u2705 Created: ${action.path}`);
|
|
985
961
|
executionResults += `[Action create_file(${action.path})]: Success
|
|
986
962
|
|
|
@@ -992,14 +968,14 @@ ${result}
|
|
|
992
968
|
|
|
993
969
|
`;
|
|
994
970
|
} else {
|
|
995
|
-
|
|
971
|
+
fs4.writeFileSync(action.path, action.content || "");
|
|
996
972
|
tui.log.success(`\u2705 Overwritten: ${action.path}`);
|
|
997
973
|
executionResults += `[Action modify_file(${action.path})]: Success (Overwrite)
|
|
998
974
|
|
|
999
975
|
`;
|
|
1000
976
|
}
|
|
1001
977
|
} else if (action.type === "delete_file") {
|
|
1002
|
-
|
|
978
|
+
fs4.unlinkSync(action.path);
|
|
1003
979
|
tui.log.success(`\u2705 Deleted: ${action.path}`);
|
|
1004
980
|
executionResults += `[Action delete_file(${action.path})]: Success
|
|
1005
981
|
|
|
@@ -1077,12 +1053,12 @@ async function callSpecAgentApi(prompt, onChunk, agentId) {
|
|
|
1077
1053
|
use_conversation: true,
|
|
1078
1054
|
conversation_id: conversationId
|
|
1079
1055
|
};
|
|
1080
|
-
const
|
|
1081
|
-
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${
|
|
1056
|
+
const effectiveAgentId = getAgentId2(agentId);
|
|
1057
|
+
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${effectiveAgentId}/chat`;
|
|
1082
1058
|
let fullMsg = "";
|
|
1083
1059
|
let raw = {};
|
|
1084
1060
|
FileLogger.log("AGENT", "Calling Agent API", {
|
|
1085
|
-
agentId:
|
|
1061
|
+
agentId: effectiveAgentId,
|
|
1086
1062
|
conversationId,
|
|
1087
1063
|
prompt: prompt.substring(0, 500)
|
|
1088
1064
|
// Log summary of prompt
|
|
@@ -1119,10 +1095,14 @@ async function callSpecAgentApi(prompt, onChunk, agentId) {
|
|
|
1119
1095
|
import { Command as Command2 } from "commander";
|
|
1120
1096
|
|
|
1121
1097
|
// src/core/agents/scan-agent.ts
|
|
1122
|
-
import
|
|
1123
|
-
import
|
|
1098
|
+
import fs5 from "fs";
|
|
1099
|
+
import path4 from "path";
|
|
1124
1100
|
var AGENT_TYPE3 = "scan_agent";
|
|
1125
|
-
|
|
1101
|
+
function getAgentId3() {
|
|
1102
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
1103
|
+
if (config.agents?.scan) return config.agents.scan;
|
|
1104
|
+
return process.env.STACKSPOT_SCAN_AGENT_ID || "01KEQ9AHWB550J2244YBH3QATN";
|
|
1105
|
+
}
|
|
1126
1106
|
async function interactiveScanAgent(options = {}) {
|
|
1127
1107
|
FileLogger.init();
|
|
1128
1108
|
tui.intro("\u{1F575}\uFE0F\u200D\u2642\uFE0F Scan Agent");
|
|
@@ -1131,29 +1111,29 @@ async function interactiveScanAgent(options = {}) {
|
|
|
1131
1111
|
const projectRoot = process.cwd();
|
|
1132
1112
|
let outputFile;
|
|
1133
1113
|
if (options.output) {
|
|
1134
|
-
outputFile =
|
|
1114
|
+
outputFile = path4.resolve(process.cwd(), options.output);
|
|
1135
1115
|
} else {
|
|
1136
|
-
const outputDir =
|
|
1137
|
-
if (!
|
|
1138
|
-
const stat =
|
|
1116
|
+
const outputDir = path4.resolve(projectRoot, "_sharkrc");
|
|
1117
|
+
if (!fs5.existsSync(outputDir)) {
|
|
1118
|
+
const stat = fs5.existsSync(outputDir) ? fs5.statSync(outputDir) : null;
|
|
1139
1119
|
if (stat && stat.isFile()) {
|
|
1140
1120
|
tui.log.warning(`Warning: '_sharkrc' exists as a file. Using '_bmad/project-context' instead to avoid overwrite.`);
|
|
1141
|
-
const fallbackDir =
|
|
1142
|
-
if (!
|
|
1143
|
-
outputFile =
|
|
1121
|
+
const fallbackDir = path4.resolve(projectRoot, "_bmad/project-context");
|
|
1122
|
+
if (!fs5.existsSync(fallbackDir)) fs5.mkdirSync(fallbackDir, { recursive: true });
|
|
1123
|
+
outputFile = path4.join(fallbackDir, "project-context.md");
|
|
1144
1124
|
} else {
|
|
1145
|
-
|
|
1146
|
-
outputFile =
|
|
1125
|
+
fs5.mkdirSync(outputDir, { recursive: true });
|
|
1126
|
+
outputFile = path4.join(outputDir, "project-context.md");
|
|
1147
1127
|
}
|
|
1148
1128
|
} else {
|
|
1149
|
-
|
|
1150
|
-
outputFile =
|
|
1129
|
+
fs5.mkdirSync(outputDir, { recursive: true });
|
|
1130
|
+
outputFile = path4.join(outputDir, "project-context.md");
|
|
1151
1131
|
}
|
|
1152
1132
|
}
|
|
1153
1133
|
tui.log.info(`Scanning project at: ${colors.bold(projectRoot)}`);
|
|
1154
1134
|
tui.log.info(`Output targeted at: ${colors.bold(outputFile)}`);
|
|
1155
1135
|
tui.log.info(`Language: ${colors.bold(language)}`);
|
|
1156
|
-
const configFileRelative =
|
|
1136
|
+
const configFileRelative = path4.relative(projectRoot, outputFile);
|
|
1157
1137
|
const superPrompt = `
|
|
1158
1138
|
You are the **Scan Agent**, an expert software architect and analyst.
|
|
1159
1139
|
Your mission is to explore this project's codebase 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.
|
|
@@ -1247,22 +1227,22 @@ ${result}
|
|
|
1247
1227
|
|
|
1248
1228
|
`;
|
|
1249
1229
|
} else if (action.type === "create_file" || action.type === "modify_file") {
|
|
1250
|
-
const resolvedActionPath =
|
|
1251
|
-
const resolvedTargetPath =
|
|
1230
|
+
const resolvedActionPath = path4.resolve(action.path || "");
|
|
1231
|
+
const resolvedTargetPath = path4.resolve(targetPath);
|
|
1252
1232
|
let isTarget = resolvedActionPath === resolvedTargetPath;
|
|
1253
|
-
if (!isTarget &&
|
|
1254
|
-
tui.log.warning(`Agent targeted '${action.path}' but we enforce '${
|
|
1233
|
+
if (!isTarget && path4.basename(action.path || "") === "project-context.md") {
|
|
1234
|
+
tui.log.warning(`Agent targeted '${action.path}' but we enforce '${path4.relative(process.cwd(), targetPath)}'. Redirecting write.`);
|
|
1255
1235
|
isTarget = true;
|
|
1256
1236
|
action.path = targetPath;
|
|
1257
1237
|
}
|
|
1258
1238
|
if (isTarget) {
|
|
1259
1239
|
const finalPath = targetPath;
|
|
1260
1240
|
if (action.type === "create_file") {
|
|
1261
|
-
|
|
1241
|
+
fs5.writeFileSync(finalPath, action.content || "");
|
|
1262
1242
|
tui.log.success(`\u2705 Generated Context: ${finalPath}`);
|
|
1263
1243
|
fileCreated = true;
|
|
1264
1244
|
} else {
|
|
1265
|
-
|
|
1245
|
+
fs5.writeFileSync(finalPath, action.content || "");
|
|
1266
1246
|
tui.log.success(`\u2705 Updated Context: ${finalPath}`);
|
|
1267
1247
|
fileCreated = true;
|
|
1268
1248
|
}
|
|
@@ -1315,7 +1295,7 @@ async function callScanAgentApi(prompt, onChunk) {
|
|
|
1315
1295
|
use_conversation: true,
|
|
1316
1296
|
conversation_id: conversationId
|
|
1317
1297
|
};
|
|
1318
|
-
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${
|
|
1298
|
+
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${getAgentId3()}/chat`;
|
|
1319
1299
|
let fullMsg = "";
|
|
1320
1300
|
let raw = {};
|
|
1321
1301
|
FileLogger.log("SCAN", "Calling API", { promptLength: prompt.length });
|
|
@@ -1356,25 +1336,32 @@ var scanCommand = new Command2("scan").description("Analyze the project and gene
|
|
|
1356
1336
|
import { Command as Command3 } from "commander";
|
|
1357
1337
|
|
|
1358
1338
|
// src/core/agents/developer-agent.ts
|
|
1359
|
-
import
|
|
1360
|
-
import
|
|
1339
|
+
import fs6 from "fs";
|
|
1340
|
+
import path5 from "path";
|
|
1361
1341
|
var AGENT_TYPE4 = "developer_agent";
|
|
1362
|
-
|
|
1342
|
+
function getAgentId4(overrideId) {
|
|
1343
|
+
if (overrideId) return overrideId;
|
|
1344
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
1345
|
+
if (config.agents?.dev) return config.agents.dev;
|
|
1346
|
+
if (process.env.STACKSPOT_DEV_AGENT_ID) return process.env.STACKSPOT_DEV_AGENT_ID;
|
|
1347
|
+
return "01KEQCGJ65YENRA4QBXVN1YFFX";
|
|
1348
|
+
}
|
|
1363
1349
|
async function interactiveDeveloperAgent(options = {}) {
|
|
1364
1350
|
FileLogger.init();
|
|
1365
1351
|
tui.intro("\u{1F988} Shark Dev Agent");
|
|
1366
|
-
|
|
1352
|
+
const agentId = getAgentId4();
|
|
1353
|
+
if (agentId === "PENDING_CONFIGURATION") {
|
|
1367
1354
|
tui.log.error("\u274C STACKSPOT_DEV_AGENT_ID not configured in .env");
|
|
1368
1355
|
return;
|
|
1369
1356
|
}
|
|
1370
1357
|
const projectRoot = process.cwd();
|
|
1371
1358
|
let contextContent = "";
|
|
1372
|
-
const defaultContextPath =
|
|
1373
|
-
const specificContextPath = options.context ?
|
|
1374
|
-
if (
|
|
1359
|
+
const defaultContextPath = path5.resolve(projectRoot, "_sharkrc", "project-context.md");
|
|
1360
|
+
const specificContextPath = options.context ? path5.resolve(projectRoot, options.context) : defaultContextPath;
|
|
1361
|
+
if (fs6.existsSync(specificContextPath)) {
|
|
1375
1362
|
try {
|
|
1376
|
-
contextContent =
|
|
1377
|
-
tui.log.info(`\u{1F4D8} Context loaded from: ${colors.dim(
|
|
1363
|
+
contextContent = fs6.readFileSync(specificContextPath, "utf-8");
|
|
1364
|
+
tui.log.info(`\u{1F4D8} Context loaded from: ${colors.dim(path5.relative(projectRoot, specificContextPath))}`);
|
|
1378
1365
|
} catch (e) {
|
|
1379
1366
|
tui.log.warning(`Failed to read context file: ${e}`);
|
|
1380
1367
|
}
|
|
@@ -1466,11 +1453,11 @@ ${result}
|
|
|
1466
1453
|
});
|
|
1467
1454
|
if (confirm) {
|
|
1468
1455
|
if (filePath) {
|
|
1469
|
-
const targetPath =
|
|
1470
|
-
const dir =
|
|
1471
|
-
if (!
|
|
1456
|
+
const targetPath = path5.resolve(projectRoot, filePath);
|
|
1457
|
+
const dir = path5.dirname(targetPath);
|
|
1458
|
+
if (!fs6.existsSync(dir)) fs6.mkdirSync(dir, { recursive: true });
|
|
1472
1459
|
if (isCreate) {
|
|
1473
|
-
|
|
1460
|
+
fs6.writeFileSync(targetPath, action.content || "");
|
|
1474
1461
|
tui.log.success(`\u2705 Created: ${filePath}`);
|
|
1475
1462
|
executionResults += `[Action create_file(${filePath})]: Success
|
|
1476
1463
|
|
|
@@ -1540,6 +1527,7 @@ User Reply: ${userReply}`;
|
|
|
1540
1527
|
} catch (e) {
|
|
1541
1528
|
spinner.stop("Error");
|
|
1542
1529
|
tui.log.error(e.message);
|
|
1530
|
+
FileLogger.log("DEV_AGENT", "Main Loop Error", e);
|
|
1543
1531
|
keepGoing = false;
|
|
1544
1532
|
}
|
|
1545
1533
|
}
|
|
@@ -1558,7 +1546,7 @@ async function callDevAgentApi(prompt, onChunk) {
|
|
|
1558
1546
|
stackspot_knowledge: false
|
|
1559
1547
|
// Dev Agent focuses on project context
|
|
1560
1548
|
};
|
|
1561
|
-
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${
|
|
1549
|
+
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${getAgentId4()}/chat`;
|
|
1562
1550
|
let fullMsg = "";
|
|
1563
1551
|
let raw = {};
|
|
1564
1552
|
await sseClient.streamAgentResponse(url, payload, { "Authorization": `Bearer ${token}`, "Content-Type": "application/json" }, {
|
|
@@ -1593,12 +1581,16 @@ var devCommand = new Command3("dev").description("Starts the Shark Developer Age
|
|
|
1593
1581
|
import { Command as Command4 } from "commander";
|
|
1594
1582
|
|
|
1595
1583
|
// src/core/agents/qa-agent.ts
|
|
1596
|
-
import
|
|
1597
|
-
import
|
|
1584
|
+
import fs7 from "fs";
|
|
1585
|
+
import path6 from "path";
|
|
1598
1586
|
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
1599
1587
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
1600
1588
|
var AGENT_TYPE5 = "qa_agent";
|
|
1601
|
-
|
|
1589
|
+
function getAgentId5() {
|
|
1590
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
1591
|
+
if (config.agents?.qa) return config.agents.qa;
|
|
1592
|
+
return process.env.STACKSPOT_QA_AGENT_ID || "01KEQFJZ3Q3JER11NH22HEZX9X";
|
|
1593
|
+
}
|
|
1602
1594
|
var ChromeDevToolsClient = class {
|
|
1603
1595
|
client = null;
|
|
1604
1596
|
transport = null;
|
|
@@ -1642,7 +1634,8 @@ var ChromeDevToolsClient = class {
|
|
|
1642
1634
|
};
|
|
1643
1635
|
var mcpClient = new ChromeDevToolsClient();
|
|
1644
1636
|
async function runQAAgent(options) {
|
|
1645
|
-
|
|
1637
|
+
const agentId = getAgentId5();
|
|
1638
|
+
if (!agentId) {
|
|
1646
1639
|
tui.log.error("\u274C STACKSPOT_QA_AGENT_ID not configured.");
|
|
1647
1640
|
tui.log.info("Please run: set STACKSPOT_QA_AGENT_ID=<your-id>");
|
|
1648
1641
|
return;
|
|
@@ -1658,9 +1651,9 @@ async function runQAAgent(options) {
|
|
|
1658
1651
|
}
|
|
1659
1652
|
let projectContext = "";
|
|
1660
1653
|
try {
|
|
1661
|
-
const contextPath =
|
|
1662
|
-
if (
|
|
1663
|
-
projectContext =
|
|
1654
|
+
const contextPath = path6.join(process.cwd(), "_sharkrc", "project-context.md");
|
|
1655
|
+
if (fs7.existsSync(contextPath)) {
|
|
1656
|
+
projectContext = fs7.readFileSync(contextPath, "utf-8");
|
|
1664
1657
|
tui.log.info(`\u{1F4D8} Context loaded from: _sharkrc/project-context.md`);
|
|
1665
1658
|
}
|
|
1666
1659
|
} catch (e) {
|
|
@@ -1688,7 +1681,7 @@ ${projectContext}
|
|
|
1688
1681
|
try {
|
|
1689
1682
|
const existingConversationId = await conversationManager.getConversationId(AGENT_TYPE5);
|
|
1690
1683
|
await sseClient.streamAgentResponse(
|
|
1691
|
-
`https://genai-inference-app.stackspot.com/v1/agent/${
|
|
1684
|
+
`https://genai-inference-app.stackspot.com/v1/agent/${getAgentId5()}/chat`,
|
|
1692
1685
|
{
|
|
1693
1686
|
user_prompt: userMessage,
|
|
1694
1687
|
streaming: true,
|
|
@@ -1769,8 +1762,8 @@ ${projectContext}
|
|
|
1769
1762
|
break;
|
|
1770
1763
|
case "create_file":
|
|
1771
1764
|
if (action.path && action.content) {
|
|
1772
|
-
const fullPath =
|
|
1773
|
-
|
|
1765
|
+
const fullPath = path6.resolve(process.cwd(), action.path);
|
|
1766
|
+
fs7.writeFileSync(fullPath, action.content);
|
|
1774
1767
|
tui.log.success(`File created: ${action.path}`);
|
|
1775
1768
|
result = "File created successfully.";
|
|
1776
1769
|
}
|