shark-ai 0.4.14 → 0.4.16
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
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
t,
|
|
10
10
|
tokenStorage,
|
|
11
11
|
tui
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-H6S7DYRG.js";
|
|
13
13
|
|
|
14
14
|
// src/core/error/crash-handler.ts
|
|
15
15
|
import fs from "fs";
|
|
@@ -422,6 +422,7 @@ var AgentActionSchema = z2.object({
|
|
|
422
422
|
"modify_file",
|
|
423
423
|
"list_files",
|
|
424
424
|
"search_file",
|
|
425
|
+
"search_code",
|
|
425
426
|
"read_file",
|
|
426
427
|
"delete_file",
|
|
427
428
|
"list_structure",
|
|
@@ -429,6 +430,7 @@ var AgentActionSchema = z2.object({
|
|
|
429
430
|
"search_ast",
|
|
430
431
|
"run_command",
|
|
431
432
|
"talk_with_user",
|
|
433
|
+
"use_mcp_tool",
|
|
432
434
|
"ast_list_structure",
|
|
433
435
|
"ast_get_method",
|
|
434
436
|
"ast_add_method",
|
|
@@ -457,6 +459,9 @@ var AgentActionSchema = z2.object({
|
|
|
457
459
|
tool_name: z2.string().nullable().optional(),
|
|
458
460
|
tool_args: z2.string().nullable().optional(),
|
|
459
461
|
// JSON string argument
|
|
462
|
+
// search_code fields
|
|
463
|
+
query: z2.string().nullable().optional(),
|
|
464
|
+
is_regex: z2.boolean().nullable().optional(),
|
|
460
465
|
// AST-Grep fields
|
|
461
466
|
pattern: z2.string().nullable().optional(),
|
|
462
467
|
fix: z2.string().nullable().optional(),
|
|
@@ -704,6 +709,12 @@ function getAgentId(overrideId) {
|
|
|
704
709
|
if (config.agents?.ba) return config.agents.ba;
|
|
705
710
|
return process.env.STACKSPOT_BA_AGENT_ID || "01KEJ95G304TNNAKGH5XNEEBVD";
|
|
706
711
|
}
|
|
712
|
+
function getAgentVersion(overrideVersion) {
|
|
713
|
+
if (overrideVersion) return overrideVersion;
|
|
714
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
715
|
+
if (config.agentVersions?.ba) return config.agentVersions.ba;
|
|
716
|
+
return process.env.STACKSPOT_BA_AGENT_VERSION;
|
|
717
|
+
}
|
|
707
718
|
async function runBusinessAnalystAgent(prompt, options = {}) {
|
|
708
719
|
const { agentId, onChunk, onComplete } = options;
|
|
709
720
|
const realm = await getActiveRealm();
|
|
@@ -721,6 +732,10 @@ async function runBusinessAnalystAgent(prompt, options = {}) {
|
|
|
721
732
|
deep_search_ks: false,
|
|
722
733
|
conversation_id: existingConversationId
|
|
723
734
|
};
|
|
735
|
+
const agentVersion = getAgentVersion();
|
|
736
|
+
if (agentVersion) {
|
|
737
|
+
requestPayload.agent_version_number = agentVersion;
|
|
738
|
+
}
|
|
724
739
|
const effectiveAgentId = getAgentId(options.agentId);
|
|
725
740
|
const agentUrl = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${effectiveAgentId}/chat`;
|
|
726
741
|
const headers = {
|
|
@@ -1349,6 +1364,49 @@ function handleSearchFile(pattern) {
|
|
|
1349
1364
|
return `Error searching files: ${e.message}`;
|
|
1350
1365
|
}
|
|
1351
1366
|
}
|
|
1367
|
+
function handleSearchCode(globPattern, query, isRegex = false) {
|
|
1368
|
+
const MAX_MATCHES = 50;
|
|
1369
|
+
const MAX_FILE_SIZE_BYTES = 500 * 1024;
|
|
1370
|
+
try {
|
|
1371
|
+
const files = fg.sync(globPattern, { dot: true, absolute: false });
|
|
1372
|
+
if (files.length === 0) return `No files found matching pattern: "${globPattern}"`;
|
|
1373
|
+
let searchRegex;
|
|
1374
|
+
try {
|
|
1375
|
+
searchRegex = isRegex ? new RegExp(query, "gi") : new RegExp(query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "gi");
|
|
1376
|
+
} catch {
|
|
1377
|
+
return `Error: Invalid regex pattern: "${query}"`;
|
|
1378
|
+
}
|
|
1379
|
+
const results = [];
|
|
1380
|
+
let totalMatches = 0;
|
|
1381
|
+
for (const filePath of files) {
|
|
1382
|
+
if (totalMatches >= MAX_MATCHES) break;
|
|
1383
|
+
try {
|
|
1384
|
+
const fullPath = path5.resolve(process.cwd(), filePath);
|
|
1385
|
+
const stats = fs4.statSync(fullPath);
|
|
1386
|
+
if (stats.size > MAX_FILE_SIZE_BYTES) continue;
|
|
1387
|
+
const content = fs4.readFileSync(fullPath, "utf-8");
|
|
1388
|
+
const lines = content.split("\n");
|
|
1389
|
+
for (let i = 0; i < lines.length; i++) {
|
|
1390
|
+
if (totalMatches >= MAX_MATCHES) break;
|
|
1391
|
+
searchRegex.lastIndex = 0;
|
|
1392
|
+
if (searchRegex.test(lines[i])) {
|
|
1393
|
+
results.push(`${filePath}:${i + 1}: ${lines[i].trim()}`);
|
|
1394
|
+
totalMatches++;
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
} catch {
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
if (results.length === 0) {
|
|
1401
|
+
return `No matches found for "${query}" in files matching "${globPattern}"`;
|
|
1402
|
+
}
|
|
1403
|
+
const limited = totalMatches >= MAX_MATCHES ? ` (limited to ${MAX_MATCHES})` : "";
|
|
1404
|
+
return `Found ${totalMatches} match(es) for "${query}" in "${globPattern}"${limited}:
|
|
1405
|
+
${results.join("\n")}`;
|
|
1406
|
+
} catch (e) {
|
|
1407
|
+
return `Error searching code: ${e.message}`;
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1352
1410
|
function startSmartReplace(filePath, newContent, targetContent, tui2) {
|
|
1353
1411
|
if (!fs4.existsSync(filePath)) {
|
|
1354
1412
|
tui2.log.error(`\u274C File not found for modification: ${filePath}`);
|
|
@@ -1715,6 +1773,12 @@ function getAgentId2(overrideId) {
|
|
|
1715
1773
|
if (config.agents?.spec) return config.agents.spec;
|
|
1716
1774
|
return process.env.STACKSPOT_SPEC_AGENT_ID || "01KEPXTX37FTB4N672TZST4SGP";
|
|
1717
1775
|
}
|
|
1776
|
+
function getAgentVersion2(overrideVersion) {
|
|
1777
|
+
if (overrideVersion) return overrideVersion;
|
|
1778
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
1779
|
+
if (config.agentVersions?.spec) return config.agentVersions.spec;
|
|
1780
|
+
return process.env.STACKSPOT_SPEC_AGENT_VERSION;
|
|
1781
|
+
}
|
|
1718
1782
|
async function interactiveSpecificationAgent(options = {}) {
|
|
1719
1783
|
FileLogger.init();
|
|
1720
1784
|
tui.intro("\u{1F3D7}\uFE0F Specification Agent (Template-Based)");
|
|
@@ -1726,22 +1790,22 @@ async function interactiveSpecificationAgent(options = {}) {
|
|
|
1726
1790
|
let initialContent = `# Technical Specification: {{PROJECT_NAME}}
|
|
1727
1791
|
|
|
1728
1792
|
## 1. Technology Stack
|
|
1729
|
-
[TO BE ANALYZED]
|
|
1793
|
+
[TO BE ANALYZED - STACK]
|
|
1730
1794
|
- Language: [e.g. TypeScript]
|
|
1731
1795
|
- Framework: [e.g. Node.js / React]
|
|
1732
1796
|
- Database: [e.g. SQLite / PostgreSQL]
|
|
1733
1797
|
- Key Libraries: [Top 5 dependencies]
|
|
1734
1798
|
|
|
1735
1799
|
## 2. Architecture Overview
|
|
1736
|
-
[TO BE ANALYZED]
|
|
1800
|
+
[TO BE ANALYZED - ARCHITECTURE]
|
|
1737
1801
|
[Brief description of architectural pattern]
|
|
1738
1802
|
|
|
1739
1803
|
## 3. Data Model
|
|
1740
|
-
[TO BE ANALYZED]
|
|
1804
|
+
[TO BE ANALYZED - DATA MODEL]
|
|
1741
1805
|
[Schema/ERD definitions]
|
|
1742
1806
|
|
|
1743
1807
|
## 4. API / Interface Contracts
|
|
1744
|
-
[TO BE ANALYZED]
|
|
1808
|
+
[TO BE ANALYZED - API]
|
|
1745
1809
|
[Main endpoints or CLI commands]
|
|
1746
1810
|
|
|
1747
1811
|
## 5. Implementation Steps
|
|
@@ -1774,31 +1838,17 @@ async function interactiveSpecificationAgent(options = {}) {
|
|
|
1774
1838
|
}
|
|
1775
1839
|
let initialPrompt = `
|
|
1776
1840
|
Voc\xEA \xE9 o **Shark Spec**, um Arquiteto de Software S\xEAnior e Tech Lead.
|
|
1777
|
-
Seu objetivo \xE9 produzir uma especifica\xE7\xE3o t\xE9cnica precisa
|
|
1841
|
+
Seu objetivo final \xE9 produzir uma especifica\xE7\xE3o t\xE9cnica precisa para a tarefa no arquivo \`_sharkrc/tech-spec.md\`.
|
|
1778
1842
|
|
|
1779
|
-
\u26A0\uFE0F
|
|
1843
|
+
\u26A0\uFE0F O SEU WORKFLOW \xC9 GUIADO POR FASES.
|
|
1844
|
+
N\xC3O TENTE ADIANTAR O TRABALHO (ex: investigar c\xF3digo ou preencher template agora).
|
|
1780
1845
|
|
|
1781
|
-
**FASE 1
|
|
1846
|
+
**VOC\xCA EST\xC1 NA FASE 1: ENTENDIMENTO DA TAREFA**
|
|
1782
1847
|
- Use \`talk_with_user\` para perguntar ao usu\xE1rio qual tarefa espec\xEDfica, funcionalidade ou bug ele precisa especificar.
|
|
1783
|
-
-
|
|
1784
|
-
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
- Use \`list_files\` e \`read_file\` APENAS em arquivos diretamente relevantes para a tarefa confirmada.
|
|
1788
|
-
- N\xC3O leia o projeto de forma gen\xE9rica.
|
|
1789
|
-
- REGRA DE LEITURA PR\xC9VIA: Voc\xEA N\xC3O PODE adicionar uma tarefa referenciando um arquivo que voc\xEA n\xE3o leu nesta sess\xE3o (exce\xE7\xE3o: novos arquivos a serem criados).
|
|
1790
|
-
|
|
1791
|
-
**FASE 3 \u2013 PREENCHA O TEMPLATE:**
|
|
1792
|
-
- Use \`modify_file\` em \`_sharkrc/tech-spec.md\` para substituir os placeholders com conte\xFAdo real e espec\xEDfico da tarefa.
|
|
1793
|
-
- As Se\xE7\xF5es 1-4 (Stack, Arquitetura, Modelo de Dados, API) devem descrever o contexto da TAREFA, n\xE3o do projeto como um todo.
|
|
1794
|
-
- Passos de Implementa\xE7\xE3o: APENAS checkboxes markdown: \`- [ ] [Verbo de A\xE7\xE3o] [O Que] em [Caminho Relativo]\`. SEM listas numeradas, SEM subn\xEDveis.
|
|
1795
|
-
- Quando todos os placeholders acabarem e voc\xEA estiver satisfeito, retorne: \`SPEC_UPDATED: Complete\`.
|
|
1796
|
-
|
|
1797
|
-
**REGRAS CR\xCDTICAS:**
|
|
1798
|
-
- NUNCA preencha a Technology Stack ou Architecture com informa\xE7\xF5es gen\xE9ricas do projeto. Essas se\xE7\xF5es devem refletir o que a tarefa ir\xE1 usar ou alterar.
|
|
1799
|
-
- Use \`talk_with_user\` sempre que os requisitos forem amb\xEDguos.
|
|
1800
|
-
- N\xC3O tente escrever todas as se\xE7\xF5es de uma vez. Trabalhe de forma incremental, uma se\xE7\xE3o por vez.
|
|
1801
|
-
- IMPORTANTE: Toda a sua comunica\xE7\xE3o e a especifica\xE7\xE3o gerada DEVEM ser em Portugu\xEAs.
|
|
1848
|
+
- Confirme o escopo e os limites com o usu\xE1rio.
|
|
1849
|
+
- Se o escopo estiver perfeitamente claro e confirmado (com o usu\xE1rio), emita "PHASE_COMPLETED" no campo "summary" do JSON para avan\xE7ar.
|
|
1850
|
+
|
|
1851
|
+
IMPORTANTE: Toda a sua comunica\xE7\xE3o DEVE ser em Portugu\xEAs.
|
|
1802
1852
|
`;
|
|
1803
1853
|
if (briefingContent) {
|
|
1804
1854
|
initialPrompt += `
|
|
@@ -1836,6 +1886,7 @@ async function runSpecLoop(initialMessage, targetPath, overrideAgentId) {
|
|
|
1836
1886
|
let nextPrompt = initialMessage;
|
|
1837
1887
|
let keepGoing = true;
|
|
1838
1888
|
let stepCount = 0;
|
|
1889
|
+
let currentPhase = 1;
|
|
1839
1890
|
const MAX_STEPS = 30;
|
|
1840
1891
|
while (keepGoing && stepCount < MAX_STEPS) {
|
|
1841
1892
|
stepCount++;
|
|
@@ -1860,23 +1911,6 @@ async function runSpecLoop(initialMessage, targetPath, overrideAgentId) {
|
|
|
1860
1911
|
let executionResults = "";
|
|
1861
1912
|
let waitingForUser = false;
|
|
1862
1913
|
let specUpdated = false;
|
|
1863
|
-
if (lastResponse.message && lastResponse.message.includes("SPEC_UPDATED:")) {
|
|
1864
|
-
const content = fs5.existsSync(targetPath) ? fs5.readFileSync(targetPath, "utf-8") : "";
|
|
1865
|
-
if (content.includes("[TO BE")) {
|
|
1866
|
-
const pendingMatches = [...content.matchAll(/## ([^\n]+)[\s\S]*?\[TO BE/g)].map((m) => m[1]);
|
|
1867
|
-
let missing = pendingMatches.length > 0 ? pendingMatches.join(", ") : "algumas se\xE7\xF5es";
|
|
1868
|
-
tui.log.warning(`O agente tentou concluir prematuramente, mas h\xE1 placeholders pendentes. For\xE7ando retorno...`);
|
|
1869
|
-
nextPrompt = `[System Error]: A valida\xE7\xE3o falhou e o bloqueio autom\xE1tico foi acionado.
|
|
1870
|
-
Voc\xEA tentou concluir a tarefa, mas o arquivo AINDA possui placeholders '[TO BE ANALYZED]' ou '[TO BE FILLED]'.
|
|
1871
|
-
As seguintes se\xE7\xF5es ainda cont\xEAm estes placeholders: ${missing}.
|
|
1872
|
-
Voc\xEA \xE9 OBRIGADO a usar a action \`modify_file\` para preencher o conte\xFAdo de cada uma dessas se\xE7\xF5es. Use o placeholder exato no campo \`target_content\`. N\xC3O repita a conclus\xE3o da tarefa at\xE9 corrigir todas as pend\xEAncias.`;
|
|
1873
|
-
continue;
|
|
1874
|
-
} else {
|
|
1875
|
-
const updateSummary = lastResponse.message.split("SPEC_UPDATED:")[1].trim();
|
|
1876
|
-
tui.log.success(`\u2705 Spec Finalized: ${updateSummary}`);
|
|
1877
|
-
return;
|
|
1878
|
-
}
|
|
1879
|
-
}
|
|
1880
1914
|
for (const action of lastResponse.actions) {
|
|
1881
1915
|
if (action.type === "talk_with_user") {
|
|
1882
1916
|
tui.log.info(colors.primary("\u{1F916} Architect:"));
|
|
@@ -1902,6 +1936,16 @@ ${result}
|
|
|
1902
1936
|
executionResults += `[Action search_file(${action.path}) Result]:
|
|
1903
1937
|
${result}
|
|
1904
1938
|
|
|
1939
|
+
`;
|
|
1940
|
+
} else if (action.type === "search_code") {
|
|
1941
|
+
const glob = action.path || "src/**/*";
|
|
1942
|
+
const query = action.query || "";
|
|
1943
|
+
const isRegex = action.is_regex === true;
|
|
1944
|
+
tui.log.info(`\u{1F50E} Search code: ${colors.dim(`"${query}" in ${glob}`)}`);
|
|
1945
|
+
const result = handleSearchCode(glob, query, isRegex);
|
|
1946
|
+
executionResults += `[Action search_code("${query}" in "${glob}") Result]:
|
|
1947
|
+
${result}
|
|
1948
|
+
|
|
1905
1949
|
`;
|
|
1906
1950
|
} else if (["create_file", "modify_file"].includes(action.type)) {
|
|
1907
1951
|
let actionPath = path6.resolve(action.path || "");
|
|
@@ -1936,7 +1980,7 @@ ${result}
|
|
|
1936
1980
|
`;
|
|
1937
1981
|
specUpdated = true;
|
|
1938
1982
|
} else {
|
|
1939
|
-
executionResults += `[Action modify_file]: Failed. Target content not found.
|
|
1983
|
+
executionResults += `[Action modify_file]: Failed. Target content not found or ambiguous.
|
|
1940
1984
|
`;
|
|
1941
1985
|
}
|
|
1942
1986
|
} else {
|
|
@@ -1950,6 +1994,62 @@ ${result}
|
|
|
1950
1994
|
}
|
|
1951
1995
|
}
|
|
1952
1996
|
}
|
|
1997
|
+
if (lastResponse.message && lastResponse.message.includes("PHASE_COMPLETED")) {
|
|
1998
|
+
const extraContext = executionResults ? `
|
|
1999
|
+
|
|
2000
|
+
Resultados das \xFAltimas a\xE7\xF5es executadas antes da conclus\xE3o:
|
|
2001
|
+
${executionResults}` : "";
|
|
2002
|
+
if (currentPhase === 1) {
|
|
2003
|
+
currentPhase = 2;
|
|
2004
|
+
tui.log.success(`\u2705 Fase 1 Conclu\xEDda. Iniciando Fase 2 (Investiga\xE7\xE3o).`);
|
|
2005
|
+
nextPrompt = `[System Message]
|
|
2006
|
+
Voc\xEA completou a FASE 1 com sucesso.
|
|
2007
|
+
|
|
2008
|
+
**VOC\xCA AGORA EST\xC1 NA FASE 2: INVESTIGA\xC7\xC3O**
|
|
2009
|
+
- Use \`search_code\` e \`list_files\` para explorar os arquivos relevantes \xE0 tarefa.
|
|
2010
|
+
- Prefira \`search_code\` em vez de \`read_file\` para buscar c\xF3digo sem inflar o contexto.
|
|
2011
|
+
- N\xC3O leia o projeto inteiro de forma gen\xE9rica.
|
|
2012
|
+
- REGRA DE OURO (READ-FIRST): Voc\xEA N\xC3O PODE referenciar um arquivo na especifica\xE7\xE3o t\xE9cnica que n\xE3o tenha investigado nesta fase.
|
|
2013
|
+
- Quando achar que possui toda a clareza t\xE9cnica sobre onde e o que deve ser feito no c\xF3digo, emita "PHASE_COMPLETED" no summary.${extraContext}`;
|
|
2014
|
+
continue;
|
|
2015
|
+
} else if (currentPhase === 2) {
|
|
2016
|
+
currentPhase = 3;
|
|
2017
|
+
tui.log.success(`\u2705 Fase 2 Conclu\xEDda. Iniciando Fase 3 (Preenchimento).`);
|
|
2018
|
+
nextPrompt = `[System Message]
|
|
2019
|
+
Voc\xEA completou a FASE 2 com sucesso.
|
|
2020
|
+
|
|
2021
|
+
**VOC\xCA AGORA EST\xC1 NA FASE 3: PREENCHIMENTO DO TEMPLATE**
|
|
2022
|
+
- Use \`modify_file\` no arquivo \`${targetPath}\` para substituir os placeholders pelo conte\xFAdo real levantado na fase de investiga\xE7\xE3o.
|
|
2023
|
+
- As se\xE7\xF5es 1-4 devem descrever o contexto da TAREFA, e n\xE3o o projeto como um todo.
|
|
2024
|
+
- Passos de Implementa\xE7\xE3o (Implementation Steps): APENAS checkboxes markdown: \`- [ ] [Verbo de A\xE7\xE3o] [O Que] em [Caminho Relativo]\`.
|
|
2025
|
+
- Quando TODOS os placeholders ([TO BE ANALYZED...] ou [TO BE FILLED]) forem substitu\xEDdos e o trabalho conclu\xEDdo, emita "SPEC_UPDATED: Complete" no summary para finalizar.${extraContext}`;
|
|
2026
|
+
continue;
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
if (lastResponse.message && lastResponse.message.includes("SPEC_UPDATED:")) {
|
|
2030
|
+
if (currentPhase < 3) {
|
|
2031
|
+
tui.log.warning(`O agente tentou finalizar prematuramente. For\xE7ando retorno para a fase atual...`);
|
|
2032
|
+
nextPrompt = `[System Error]: Voc\xEA tentou finalizar a especifica\xE7\xE3o prematuramente emitindo SPEC_UPDATED, mas ainda est\xE1 na Fase ${currentPhase}. Voc\xEA s\xF3 pode finalizar quando estiver na Fase 3.
|
|
2033
|
+
|
|
2034
|
+
Continue seu trabalho na Fase ${currentPhase} ou emita "PHASE_COMPLETED" se terminou esta etapa atual.`;
|
|
2035
|
+
continue;
|
|
2036
|
+
}
|
|
2037
|
+
const content = fs5.existsSync(targetPath) ? fs5.readFileSync(targetPath, "utf-8") : "";
|
|
2038
|
+
if (content.includes("[TO BE")) {
|
|
2039
|
+
const pendingMatches = [...content.matchAll(/## ([^\n]+)[\s\S]*?\[TO BE/g)].map((m) => m[1]);
|
|
2040
|
+
let missing = pendingMatches.length > 0 ? pendingMatches.join(", ") : "algumas se\xE7\xF5es";
|
|
2041
|
+
tui.log.warning(`O agente tentou concluir prematuramente, mas h\xE1 placeholders pendentes. For\xE7ando retorno...`);
|
|
2042
|
+
nextPrompt = `[System Error]: A valida\xE7\xE3o falhou e o bloqueio autom\xE1tico foi acionado.
|
|
2043
|
+
Voc\xEA tentou concluir a tarefa, mas o arquivo AINDA possui placeholders '[TO BE ANALYZED...]' ou '[TO BE FILLED]'.
|
|
2044
|
+
As seguintes se\xE7\xF5es ainda cont\xEAm estes placeholders: ${missing}.
|
|
2045
|
+
Voc\xEA \xE9 OBRIGADO a usar a action \`modify_file\` para preencher o conte\xFAdo de cada uma dessas se\xE7\xF5es. Use o placeholder exato no campo \`target_content\`. N\xC3O repita a conclus\xE3o da tarefa at\xE9 corrigir todas as pend\xEAncias.`;
|
|
2046
|
+
continue;
|
|
2047
|
+
} else {
|
|
2048
|
+
const updateSummary = lastResponse.message.split("SPEC_UPDATED:")[1].trim();
|
|
2049
|
+
tui.log.success(`\u2705 Spec Finalized: ${updateSummary}`);
|
|
2050
|
+
return;
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
1953
2053
|
if (waitingForUser) {
|
|
1954
2054
|
const userReply = await tui.text({ message: "Your answer", placeholder: "Type your answer..." });
|
|
1955
2055
|
if (tui.isCancel(userReply)) {
|
|
@@ -1972,6 +2072,8 @@ Por favor, envie uma nova action \`modify_file\` focada em uma destas se\xE7\xF5
|
|
|
1972
2072
|
} else {
|
|
1973
2073
|
systemMsg += "\n[System]: O arquivo parece completo! Se estiver satisfeito e possuir TODAS as implementa\xE7\xF5es descritas, retorne 'SPEC_UPDATED: Complete'.";
|
|
1974
2074
|
}
|
|
2075
|
+
} else {
|
|
2076
|
+
systemMsg += "\n[System]: A modifica\xE7\xE3o do arquivo falhou. Verifique se o `target_content` que voc\xEA usou existe EXATAMENTE como no arquivo e se ele \xE9 \xDANICO na hora de usar a action `modify_file`.";
|
|
1975
2077
|
}
|
|
1976
2078
|
nextPrompt = `${executionResults}
|
|
1977
2079
|
|
|
@@ -2013,6 +2115,10 @@ async function callSpecAgentApi(prompt, onChunk, agentId) {
|
|
|
2013
2115
|
use_conversation: true,
|
|
2014
2116
|
conversation_id: conversationId
|
|
2015
2117
|
};
|
|
2118
|
+
const agentVersion = getAgentVersion2();
|
|
2119
|
+
if (agentVersion) {
|
|
2120
|
+
payload.agent_version_number = agentVersion;
|
|
2121
|
+
}
|
|
2016
2122
|
const effectiveAgentId = getAgentId2(agentId);
|
|
2017
2123
|
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${effectiveAgentId}/chat`;
|
|
2018
2124
|
let fullMsg = "";
|
|
@@ -2050,6 +2156,11 @@ function getAgentId3() {
|
|
|
2050
2156
|
if (config.agents?.scan) return config.agents.scan;
|
|
2051
2157
|
return process.env.STACKSPOT_SCAN_AGENT_ID || "01KEQ9AHWB550J2244YBH3QATN";
|
|
2052
2158
|
}
|
|
2159
|
+
function getAgentVersion3() {
|
|
2160
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
2161
|
+
if (config.agentVersions?.scan) return config.agentVersions.scan;
|
|
2162
|
+
return process.env.STACKSPOT_SCAN_AGENT_VERSION;
|
|
2163
|
+
}
|
|
2053
2164
|
async function interactiveScanAgent(options = {}) {
|
|
2054
2165
|
FileLogger.init();
|
|
2055
2166
|
const config = ConfigManager.getInstance().getConfig();
|
|
@@ -2515,6 +2626,10 @@ async function callScanAgentApi(prompt, onChunk) {
|
|
|
2515
2626
|
use_conversation: true,
|
|
2516
2627
|
conversation_id: conversationId
|
|
2517
2628
|
};
|
|
2629
|
+
const agentVersion = getAgentVersion3();
|
|
2630
|
+
if (agentVersion) {
|
|
2631
|
+
payload.agent_version_number = agentVersion;
|
|
2632
|
+
}
|
|
2518
2633
|
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${getAgentId3()}/chat`;
|
|
2519
2634
|
let fullMsg = "";
|
|
2520
2635
|
let raw = {};
|
|
@@ -2577,6 +2692,13 @@ function getAgentId4(overrideId) {
|
|
|
2577
2692
|
if (process.env.STACKSPOT_DEV_AGENT_ID) return process.env.STACKSPOT_DEV_AGENT_ID;
|
|
2578
2693
|
return "01KEQCGJ65YENRA4QBXVN1YFFX";
|
|
2579
2694
|
}
|
|
2695
|
+
function getAgentVersion4(overrideVersion) {
|
|
2696
|
+
if (overrideVersion) return overrideVersion;
|
|
2697
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
2698
|
+
if (config.agentVersions?.dev) return config.agentVersions.dev;
|
|
2699
|
+
if (process.env.STACKSPOT_DEV_AGENT_VERSION) return process.env.STACKSPOT_DEV_AGENT_VERSION;
|
|
2700
|
+
return void 0;
|
|
2701
|
+
}
|
|
2580
2702
|
async function interactiveDeveloperAgent(options = {}) {
|
|
2581
2703
|
FileLogger.init();
|
|
2582
2704
|
const agentId = getAgentId4();
|
|
@@ -2886,6 +3008,10 @@ async function callDevAgentApi(prompt, onChunk, conversationKey = AGENT_TYPE4) {
|
|
|
2886
3008
|
conversation_id: conversationId,
|
|
2887
3009
|
stackspot_knowledge: false
|
|
2888
3010
|
};
|
|
3011
|
+
const agentVersion = getAgentVersion4();
|
|
3012
|
+
if (agentVersion) {
|
|
3013
|
+
payload.agent_version_number = agentVersion;
|
|
3014
|
+
}
|
|
2889
3015
|
const url = `${STACKSPOT_AGENT_API_BASE}/v1/agent/${getAgentId4()}/chat`;
|
|
2890
3016
|
let fullMsg = "";
|
|
2891
3017
|
let raw = {};
|
|
@@ -3168,6 +3294,11 @@ function getAgentId5() {
|
|
|
3168
3294
|
if (config.agents?.qa) return config.agents.qa;
|
|
3169
3295
|
return process.env.STACKSPOT_QA_AGENT_ID || "01KEQFJZ3Q3JER11NH22HEZX9X";
|
|
3170
3296
|
}
|
|
3297
|
+
function getAgentVersion5() {
|
|
3298
|
+
const config = ConfigManager.getInstance().getConfig();
|
|
3299
|
+
if (config.agentVersions?.qa) return config.agentVersions.qa;
|
|
3300
|
+
return process.env.STACKSPOT_QA_AGENT_VERSION;
|
|
3301
|
+
}
|
|
3171
3302
|
var ChromeDevToolsClient = class {
|
|
3172
3303
|
client = null;
|
|
3173
3304
|
transport = null;
|
|
@@ -3263,7 +3394,8 @@ ${projectContext}
|
|
|
3263
3394
|
user_prompt: userMessage,
|
|
3264
3395
|
streaming: true,
|
|
3265
3396
|
use_conversation: true,
|
|
3266
|
-
conversation_id: existingConversationId
|
|
3397
|
+
conversation_id: existingConversationId,
|
|
3398
|
+
...getAgentVersion5() ? { agent_version_number: getAgentVersion5() } : {}
|
|
3267
3399
|
},
|
|
3268
3400
|
{
|
|
3269
3401
|
"Authorization": `Bearer ${token}`
|
|
@@ -3295,11 +3427,12 @@ ${projectContext}
|
|
|
3295
3427
|
keepRunning = false;
|
|
3296
3428
|
break;
|
|
3297
3429
|
}
|
|
3298
|
-
|
|
3299
|
-
if (
|
|
3300
|
-
|
|
3430
|
+
const currentResponse = agentResponse;
|
|
3431
|
+
if (!currentResponse) continue;
|
|
3432
|
+
if (currentResponse.summary) {
|
|
3433
|
+
tui.log.info(colors.primary(`\u{1F4CB} Plan: ${currentResponse.summary}`));
|
|
3301
3434
|
}
|
|
3302
|
-
if (
|
|
3435
|
+
if (currentResponse.actions.length === 0) {
|
|
3303
3436
|
const reply = await tui.text({
|
|
3304
3437
|
message: "\u{1F916} Shark QA:",
|
|
3305
3438
|
placeholder: "Your reply..."
|
|
@@ -3311,7 +3444,7 @@ ${projectContext}
|
|
|
3311
3444
|
}
|
|
3312
3445
|
continue;
|
|
3313
3446
|
}
|
|
3314
|
-
for (const action of
|
|
3447
|
+
for (const action of currentResponse.actions) {
|
|
3315
3448
|
tui.log.info(colors.dim(`Executing: ${action.type}`));
|
|
3316
3449
|
let result = "";
|
|
3317
3450
|
try {
|