vigthoria-cli 1.6.45 → 1.6.48
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/commands/chat.d.ts +3 -2
- package/dist/commands/chat.js +78 -39
- package/dist/index.js +3 -2
- package/package.json +1 -1
package/dist/commands/chat.d.ts
CHANGED
|
@@ -150,8 +150,9 @@ export declare class ChatCommand {
|
|
|
150
150
|
private resolveDirectModeCompletion;
|
|
151
151
|
/**
|
|
152
152
|
* Strip system-prompt echoes, tool execution headers, grounding-rule
|
|
153
|
-
* parroting,
|
|
154
|
-
* --json output contains only the
|
|
153
|
+
* parroting, recovery banners, and multi-line tool output blocks from
|
|
154
|
+
* the model's final answer so that --json output contains only the
|
|
155
|
+
* substantive answer.
|
|
155
156
|
*/
|
|
156
157
|
private sanitizeDirectModeOutput;
|
|
157
158
|
private isDirectModeFollowUpQuestion;
|
package/dist/commands/chat.js
CHANGED
|
@@ -678,7 +678,9 @@ class ChatCommand {
|
|
|
678
678
|
return false;
|
|
679
679
|
}
|
|
680
680
|
async handleDirectPrompt(prompt) {
|
|
681
|
-
|
|
681
|
+
// Suppress all setup banners in direct-prompt mode so only the final
|
|
682
|
+
// answer reaches stdout. Interactive (REPL) mode still shows them.
|
|
683
|
+
if (!this.jsonOutput && !this.directPromptMode) {
|
|
682
684
|
console.log(chalk_1.default.cyan('Running single prompt in direct mode.'));
|
|
683
685
|
console.log(chalk_1.default.gray(`Model: ${this.currentModel}`));
|
|
684
686
|
console.log(chalk_1.default.gray(`Project: ${this.currentProjectPath}`));
|
|
@@ -1303,12 +1305,12 @@ class ChatCommand {
|
|
|
1303
1305
|
tool: 'read_file',
|
|
1304
1306
|
args: { path: targetFile },
|
|
1305
1307
|
};
|
|
1306
|
-
if (!this.jsonOutput) {
|
|
1308
|
+
if (!this.jsonOutput && !this.directPromptMode) {
|
|
1307
1309
|
console.log(chalk_1.default.cyan(`⚙ Executing: ${readCall.tool}`));
|
|
1308
1310
|
}
|
|
1309
1311
|
const readResult = await this.tools.execute(readCall);
|
|
1310
1312
|
const readSummary = this.formatToolResult(readCall, readResult);
|
|
1311
|
-
if (!this.jsonOutput) {
|
|
1313
|
+
if (!this.jsonOutput && !this.directPromptMode) {
|
|
1312
1314
|
console.log(readResult.success ? chalk_1.default.gray(readSummary) : chalk_1.default.red(readSummary));
|
|
1313
1315
|
}
|
|
1314
1316
|
this.messages.push({ role: 'system', content: readSummary });
|
|
@@ -1351,12 +1353,12 @@ class ChatCommand {
|
|
|
1351
1353
|
content: rewrittenContent,
|
|
1352
1354
|
},
|
|
1353
1355
|
};
|
|
1354
|
-
if (!this.jsonOutput) {
|
|
1356
|
+
if (!this.jsonOutput && !this.directPromptMode) {
|
|
1355
1357
|
console.log(chalk_1.default.cyan(`⚙ Executing: ${writeCall.tool}`));
|
|
1356
1358
|
}
|
|
1357
1359
|
const writeResult = await this.tools.execute(writeCall);
|
|
1358
1360
|
const writeSummary = this.formatToolResult(writeCall, writeResult);
|
|
1359
|
-
if (!this.jsonOutput) {
|
|
1361
|
+
if (!this.jsonOutput && !this.directPromptMode) {
|
|
1360
1362
|
console.log(writeResult.success ? chalk_1.default.gray(writeSummary) : chalk_1.default.red(writeSummary));
|
|
1361
1363
|
}
|
|
1362
1364
|
this.messages.push({ role: 'system', content: writeSummary });
|
|
@@ -1503,14 +1505,18 @@ class ChatCommand {
|
|
|
1503
1505
|
}, null, 2));
|
|
1504
1506
|
}
|
|
1505
1507
|
else if (response.content) {
|
|
1506
|
-
|
|
1508
|
+
if (!this.directPromptMode) {
|
|
1509
|
+
console.log(chalk_1.default.gray(`Agent routing: ${routingPolicy.cloudSelected ? 'Vigthoria Cloud' : 'V3 Agent'} via model ${routingPolicy.selectedModel}`));
|
|
1510
|
+
}
|
|
1507
1511
|
console.log(response.content);
|
|
1508
1512
|
}
|
|
1509
1513
|
else {
|
|
1510
|
-
|
|
1514
|
+
if (!this.directPromptMode) {
|
|
1515
|
+
console.log(chalk_1.default.gray(`Agent routing: ${routingPolicy.cloudSelected ? 'Vigthoria Cloud' : 'V3 Agent'} via model ${routingPolicy.selectedModel}`));
|
|
1516
|
+
}
|
|
1511
1517
|
console.log('V3 agent workflow completed.');
|
|
1512
1518
|
}
|
|
1513
|
-
if (!this.jsonOutput && previewGate?.required) {
|
|
1519
|
+
if (!this.jsonOutput && !this.directPromptMode && previewGate?.required) {
|
|
1514
1520
|
if (previewGate.passed) {
|
|
1515
1521
|
console.log(chalk_1.default.gray(`Template Service preview gate: passed via ${previewGate.backendUrl || 'unknown backend'}`));
|
|
1516
1522
|
}
|
|
@@ -2165,48 +2171,78 @@ class ChatCommand {
|
|
|
2165
2171
|
}
|
|
2166
2172
|
/**
|
|
2167
2173
|
* Strip system-prompt echoes, tool execution headers, grounding-rule
|
|
2168
|
-
* parroting,
|
|
2169
|
-
* --json output contains only the
|
|
2174
|
+
* parroting, recovery banners, and multi-line tool output blocks from
|
|
2175
|
+
* the model's final answer so that --json output contains only the
|
|
2176
|
+
* substantive answer.
|
|
2170
2177
|
*/
|
|
2171
2178
|
sanitizeDirectModeOutput(text) {
|
|
2172
|
-
|
|
2179
|
+
let cleaned = text;
|
|
2180
|
+
// ── Phase 1: Strip entire multi-line tool-output blocks ──
|
|
2181
|
+
// Pattern: "Tool <name> succeeded/FAILED." followed by optional
|
|
2182
|
+
// metadata lines (File:, Search status:, Output:) and then a
|
|
2183
|
+
// content block until the next double-newline or end-of-string.
|
|
2184
|
+
cleaned = cleaned.replace(/Tool (?:read_file|grep|list_dir|glob|bash|write_file) (?:succeeded|FAILED)\.[\s\S]*?(?=\n\n[A-Z_]+:|$)/g, '');
|
|
2185
|
+
// Fallback: simpler block pattern for any remaining tool headers
|
|
2186
|
+
cleaned = cleaned.replace(/Tool (?:read_file|grep|list_dir|glob|bash|write_file) (?:succeeded|FAILED)\.[\s\S]*?(?:\n\n|\s*$)/g, '');
|
|
2187
|
+
// ── Phase 2: Strip echoed system-prompt / grounding lines ──
|
|
2173
2188
|
const contaminationPatterns = [
|
|
2174
2189
|
/^\[Agent recovered from backend failure[^\]]*\]\s*/m,
|
|
2175
2190
|
/^Evidence gathered before backend failure:?\s*/m,
|
|
2176
|
-
/^MANDATORY CROSS-FILE EVIDENCE
|
|
2177
|
-
/^CONFIRMED CONFLICTING keys
|
|
2178
|
-
/^Keys found ONLY in
|
|
2179
|
-
/^CONSTRAINT: Your answer MUST
|
|
2180
|
-
/^GROUNDING CHECK
|
|
2181
|
-
/^VERIFICATION PROTOCOL
|
|
2182
|
-
/^Quality gate:
|
|
2183
|
-
/^Evidence collected:
|
|
2184
|
-
/^Warning: \d+ search tool
|
|
2185
|
-
/^Tool
|
|
2191
|
+
/^MANDATORY CROSS-FILE EVIDENCE[^\n]*\n?/m,
|
|
2192
|
+
/^CONFIRMED CONFLICTING keys[^\n]*/m,
|
|
2193
|
+
/^Keys found ONLY in [^\n]*/m,
|
|
2194
|
+
/^CONSTRAINT: Your answer MUST[^\n]*/m,
|
|
2195
|
+
/^GROUNDING CHECK:[^\n]*/m,
|
|
2196
|
+
/^VERIFICATION PROTOCOL[^\n]*/m,
|
|
2197
|
+
/^Quality gate:[^\n]*/m,
|
|
2198
|
+
/^Evidence collected:[^\n]*/m,
|
|
2199
|
+
/^Warning: \d+ search tool[^\n]*/m,
|
|
2200
|
+
/^Tool results received for direct mode[^\n]*/m,
|
|
2201
|
+
/^Original user request:[^\n]*/m,
|
|
2202
|
+
/^Project root boundary:[^\n]*/m,
|
|
2203
|
+
/^Do not declare success[^\n]*/m,
|
|
2204
|
+
/^Keep working from concrete[^\n]*/m,
|
|
2205
|
+
/^Because this is a debugging[^\n]*/m,
|
|
2206
|
+
/^If the request is already[^\n]*/m,
|
|
2207
|
+
/^If more work is required[^\n]*/m,
|
|
2208
|
+
/^Do not ask follow-up[^\n]*/m,
|
|
2209
|
+
/^CRITICAL GROUNDING RULE:[^\n]*/m,
|
|
2210
|
+
/^CROSS-FILE ATTRIBUTION:[^\n]*/m,
|
|
2211
|
+
/^EVIDENCE-GROUNDING RULE:[^\n]*/m,
|
|
2212
|
+
/^CROSS-FILE RULE:[^\n]*/m,
|
|
2213
|
+
/^OUTPUT DISCIPLINE:[^\n]*/m,
|
|
2186
2214
|
/^File: \S+\s*$/m,
|
|
2187
2215
|
/^Search status: \S+\s*$/m,
|
|
2188
2216
|
/^Output:\s*$/m,
|
|
2189
|
-
/^Tool results received for direct mode step \d+\.\s*$/m,
|
|
2190
|
-
/^Original user request:.*$/m,
|
|
2191
|
-
/^Project root boundary:.*$/m,
|
|
2192
|
-
/^Do not declare success until.*$/m,
|
|
2193
|
-
/^Keep working from concrete tool results\.\s*$/m,
|
|
2194
|
-
/^Because this is a debugging task.*$/m,
|
|
2195
|
-
/^If the request is already satisfied.*$/m,
|
|
2196
|
-
/^If more work is required.*$/m,
|
|
2197
|
-
/^Do not ask follow-up questions.*$/m,
|
|
2198
|
-
/^CRITICAL GROUNDING RULE:.*$/m,
|
|
2199
|
-
/^CROSS-FILE ATTRIBUTION:.*$/m,
|
|
2200
|
-
/^EVIDENCE-GROUNDING RULE:.*$/m,
|
|
2201
|
-
/^CROSS-FILE RULE:.*$/m,
|
|
2202
2217
|
/^\[\.\.\. ?truncated\]\s*$/m,
|
|
2203
2218
|
/^---\s*$/m,
|
|
2204
2219
|
];
|
|
2205
|
-
let cleaned = text;
|
|
2206
2220
|
for (const pat of contaminationPatterns) {
|
|
2207
2221
|
cleaned = cleaned.replace(pat, '');
|
|
2208
2222
|
}
|
|
2209
|
-
//
|
|
2223
|
+
// ── Phase 3: Paragraph-level filter ──
|
|
2224
|
+
// Split into paragraph blocks and discard any that are pure tool
|
|
2225
|
+
// output, file content dumps, or system-instruction echoes.
|
|
2226
|
+
const paragraphs = cleaned.split(/\n\n+/);
|
|
2227
|
+
const kept = paragraphs.filter(p => {
|
|
2228
|
+
const t = p.trim();
|
|
2229
|
+
if (!t)
|
|
2230
|
+
return false;
|
|
2231
|
+
// Discard lingering tool headers
|
|
2232
|
+
if (/^Tool (?:read_file|grep|list_dir|glob|bash|write_file) /i.test(t))
|
|
2233
|
+
return false;
|
|
2234
|
+
// Discard paragraphs that are mostly file-content dumps (many
|
|
2235
|
+
// lines of code with typical code tokens like { } ; = function class)
|
|
2236
|
+
const lines = t.split('\n');
|
|
2237
|
+
if (lines.length > 6) {
|
|
2238
|
+
const codeLines = lines.filter(l => /[{};=]|function |class |const |let |var |import |export |switch |case /.test(l));
|
|
2239
|
+
if (codeLines.length / lines.length > 0.4)
|
|
2240
|
+
return false;
|
|
2241
|
+
}
|
|
2242
|
+
return true;
|
|
2243
|
+
});
|
|
2244
|
+
cleaned = kept.join('\n\n');
|
|
2245
|
+
// Collapse multiple blank lines
|
|
2210
2246
|
cleaned = cleaned.replace(/\n{3,}/g, '\n\n').trim();
|
|
2211
2247
|
return cleaned || text;
|
|
2212
2248
|
}
|
|
@@ -2294,8 +2330,11 @@ class ChatCommand {
|
|
|
2294
2330
|
if (!this.tools) {
|
|
2295
2331
|
throw new Error('Agent tools are not initialized.');
|
|
2296
2332
|
}
|
|
2333
|
+
// In direct-prompt mode (--prompt), suppress verbose tool output so
|
|
2334
|
+
// only the final answer prints. In interactive mode, show full detail.
|
|
2335
|
+
const verbose = !this.jsonOutput && !this.directPromptMode;
|
|
2297
2336
|
for (const call of toolCalls) {
|
|
2298
|
-
if (
|
|
2337
|
+
if (verbose) {
|
|
2299
2338
|
console.log(chalk_1.default.cyan(`⚙ Executing: ${call.tool}`));
|
|
2300
2339
|
}
|
|
2301
2340
|
(0, bridge_client_js_1.getBridgeClient)()?.emitToolCall({ tool: call.tool, args: call.args });
|
|
@@ -2303,7 +2342,7 @@ class ChatCommand {
|
|
|
2303
2342
|
// Phase 2: If a search tool failed (search_failed), retry with alternate approach
|
|
2304
2343
|
const searchStatus = result.metadata?.searchStatus;
|
|
2305
2344
|
if (call.tool === 'grep' && searchStatus === 'search_failed') {
|
|
2306
|
-
if (
|
|
2345
|
+
if (verbose) {
|
|
2307
2346
|
console.log(chalk_1.default.yellow(`⚠ Search backend failed, retrying with alternate method...`));
|
|
2308
2347
|
}
|
|
2309
2348
|
// Force Node-native fallback by re-executing with a note
|
|
@@ -2316,7 +2355,7 @@ class ChatCommand {
|
|
|
2316
2355
|
}
|
|
2317
2356
|
}
|
|
2318
2357
|
const summary = this.formatToolResult(call, result);
|
|
2319
|
-
if (
|
|
2358
|
+
if (verbose) {
|
|
2320
2359
|
console.log(result.success ? chalk_1.default.gray(summary) : chalk_1.default.red(summary));
|
|
2321
2360
|
}
|
|
2322
2361
|
this.messages.push({ role: 'system', content: summary });
|
package/dist/index.js
CHANGED
|
@@ -155,6 +155,7 @@ async function main() {
|
|
|
155
155
|
const invokedBinaryName = getInvokedBinaryName();
|
|
156
156
|
const firstArg = process.argv[2];
|
|
157
157
|
const jsonOutputRequested = process.argv.includes('--json');
|
|
158
|
+
const directPromptRequested = process.argv.includes('--prompt') || process.argv.includes('-P');
|
|
158
159
|
if (invokedBinaryName === 'vigthoria-chat') {
|
|
159
160
|
const knownCommands = new Set([
|
|
160
161
|
'chat', 'chat-resume', 'agent', 'edit', 'generate', 'explain', 'fix', 'review',
|
|
@@ -172,7 +173,7 @@ async function main() {
|
|
|
172
173
|
// Calculate padding for centering
|
|
173
174
|
const titlePad = Math.floor((boxWidth - 4 - titleText.length) / 2);
|
|
174
175
|
const versionPad = Math.floor((boxWidth - 4 - versionText.length) / 2);
|
|
175
|
-
if (process.env.VIGTHORIA_NO_BANNER !== '1' && !jsonOutputRequested) {
|
|
176
|
+
if (process.env.VIGTHORIA_NO_BANNER !== '1' && !jsonOutputRequested && !directPromptRequested) {
|
|
176
177
|
console.log(chalk_1.default.cyan(logger_js_1.CH.dTl + logger_js_1.CH.dH.repeat(boxWidth) + logger_js_1.CH.dTr));
|
|
177
178
|
console.log(chalk_1.default.cyan(logger_js_1.CH.dV + ' '.repeat(boxWidth) + logger_js_1.CH.dV));
|
|
178
179
|
console.log(chalk_1.default.cyan(logger_js_1.CH.dV) + ' '.repeat(titlePad) + chalk_1.default.bold.white('VIGTHORIA CLI') + chalk_1.default.cyan(' - AI-Powered Coding Assistant') + ' '.repeat(boxWidth - titlePad - titleText.length) + chalk_1.default.cyan(logger_js_1.CH.dV));
|
|
@@ -182,7 +183,7 @@ async function main() {
|
|
|
182
183
|
console.log();
|
|
183
184
|
}
|
|
184
185
|
// Check for updates in background (don't wait)
|
|
185
|
-
if (process.env.VIGTHORIA_NO_UPDATE_CHECK !== '1' && !jsonOutputRequested) {
|
|
186
|
+
if (process.env.VIGTHORIA_NO_UPDATE_CHECK !== '1' && !jsonOutputRequested && !directPromptRequested) {
|
|
186
187
|
checkForUpdatesQuietly();
|
|
187
188
|
}
|
|
188
189
|
program
|