@xagent/one-shot 1.2.0 → 1.2.2
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 +82 -33
- package/dist/index.js +948 -359
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23,8 +23,8 @@ import * as readline from 'readline';
|
|
|
23
23
|
import React4, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
|
|
24
24
|
import { render, Box, Text, useApp, useInput } from 'ink';
|
|
25
25
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
26
|
+
import chalk2 from 'chalk';
|
|
26
27
|
import { program, Command } from 'commander';
|
|
27
|
-
import chalk from 'chalk';
|
|
28
28
|
import * as dotenv from 'dotenv';
|
|
29
29
|
|
|
30
30
|
var __create = Object.create;
|
|
@@ -726,7 +726,7 @@ var init_client2 = __esm({
|
|
|
726
726
|
},
|
|
727
727
|
{
|
|
728
728
|
capabilities: {
|
|
729
|
-
tools
|
|
729
|
+
// Client capabilities - not tools (tools are for servers)
|
|
730
730
|
}
|
|
731
731
|
}
|
|
732
732
|
);
|
|
@@ -7562,10 +7562,10 @@ var init_dependency_analyzer = __esm({
|
|
|
7562
7562
|
const circularDeps = [];
|
|
7563
7563
|
const visited = /* @__PURE__ */ new Set();
|
|
7564
7564
|
const visiting = /* @__PURE__ */ new Set();
|
|
7565
|
-
const dfs = (filePath,
|
|
7565
|
+
const dfs = (filePath, path39) => {
|
|
7566
7566
|
if (visiting.has(filePath)) {
|
|
7567
|
-
const cycleStart =
|
|
7568
|
-
const cycle =
|
|
7567
|
+
const cycleStart = path39.indexOf(filePath);
|
|
7568
|
+
const cycle = path39.slice(cycleStart).concat([filePath]);
|
|
7569
7569
|
circularDeps.push({
|
|
7570
7570
|
cycle: cycle.map((fp) => graph.nodes.get(fp)?.filePath || fp),
|
|
7571
7571
|
severity: cycle.length <= 2 ? "error" : "warning",
|
|
@@ -7581,7 +7581,7 @@ var init_dependency_analyzer = __esm({
|
|
|
7581
7581
|
if (node) {
|
|
7582
7582
|
for (const dependency of node.dependencies) {
|
|
7583
7583
|
if (graph.nodes.has(dependency)) {
|
|
7584
|
-
dfs(dependency, [...
|
|
7584
|
+
dfs(dependency, [...path39, filePath]);
|
|
7585
7585
|
}
|
|
7586
7586
|
}
|
|
7587
7587
|
}
|
|
@@ -12740,8 +12740,8 @@ var init_parseUtil = __esm({
|
|
|
12740
12740
|
init_errors();
|
|
12741
12741
|
init_en();
|
|
12742
12742
|
makeIssue = (params) => {
|
|
12743
|
-
const { data, path:
|
|
12744
|
-
const fullPath = [...
|
|
12743
|
+
const { data, path: path39, errorMaps, issueData } = params;
|
|
12744
|
+
const fullPath = [...path39, ...issueData.path || []];
|
|
12745
12745
|
const fullIssue = {
|
|
12746
12746
|
...issueData,
|
|
12747
12747
|
path: fullPath
|
|
@@ -13049,11 +13049,11 @@ var init_types = __esm({
|
|
|
13049
13049
|
init_parseUtil();
|
|
13050
13050
|
init_util();
|
|
13051
13051
|
ParseInputLazyPath = class {
|
|
13052
|
-
constructor(parent, value,
|
|
13052
|
+
constructor(parent, value, path39, key) {
|
|
13053
13053
|
this._cachedPath = [];
|
|
13054
13054
|
this.parent = parent;
|
|
13055
13055
|
this.data = value;
|
|
13056
|
-
this._path =
|
|
13056
|
+
this._path = path39;
|
|
13057
13057
|
this._key = key;
|
|
13058
13058
|
}
|
|
13059
13059
|
get path() {
|
|
@@ -18384,6 +18384,10 @@ var init_grok_agent = __esm({
|
|
|
18384
18384
|
this.minRequestInterval = 500;
|
|
18385
18385
|
// ms
|
|
18386
18386
|
this.lastRequestTime = 0;
|
|
18387
|
+
this.recentToolCalls = /* @__PURE__ */ new Map();
|
|
18388
|
+
// Track recent tool calls to prevent duplicates
|
|
18389
|
+
this.duplicateWindowMs = 2e3;
|
|
18390
|
+
// 2 second window for duplicate detection
|
|
18387
18391
|
// Plan Mode integration
|
|
18388
18392
|
this.planModeState = null;
|
|
18389
18393
|
this.readonlyOverlay = null;
|
|
@@ -18445,6 +18449,13 @@ The above project context should inform your responses and decision making.` : "
|
|
|
18445
18449
|
role: "system",
|
|
18446
18450
|
content: `You are Grok One-Shot, an AI-powered CLI assistant that helps with file editing, coding tasks, and system operations.${customInstructionsSection}${contextSection}${verbosityInstructions}
|
|
18447
18451
|
|
|
18452
|
+
\u{1F6A8} CRITICAL TOOL CALLING RULES:
|
|
18453
|
+
- NEVER use multiple tool calls in a single response
|
|
18454
|
+
- NEVER concatenate tool calls like "view_fileview_file" or "str_replace_editorstr_replace_editor"
|
|
18455
|
+
- ALWAYS use ONE tool call per message with proper XML structure
|
|
18456
|
+
- WAIT for tool results before making additional tool calls
|
|
18457
|
+
- Each tool call must have valid JSON arguments only
|
|
18458
|
+
|
|
18448
18459
|
You have access to these tools:
|
|
18449
18460
|
|
|
18450
18461
|
CORE TOOLS:
|
|
@@ -18979,6 +18990,24 @@ Current working directory: ${process.cwd()}`
|
|
|
18979
18990
|
}
|
|
18980
18991
|
async executeTool(toolCall) {
|
|
18981
18992
|
try {
|
|
18993
|
+
const toolName = toolCall.function?.name;
|
|
18994
|
+
const now = Date.now();
|
|
18995
|
+
const callSignature = `${toolName}:${toolCall.function?.arguments || ""}`;
|
|
18996
|
+
const lastCallTime = this.recentToolCalls.get(callSignature);
|
|
18997
|
+
if (lastCallTime && now - lastCallTime < this.duplicateWindowMs) {
|
|
18998
|
+
console.log(`[GrokAgent] Skipping duplicate tool call: ${toolName}`);
|
|
18999
|
+
return {
|
|
19000
|
+
success: true,
|
|
19001
|
+
output: "Skipped duplicate tool call",
|
|
19002
|
+
details: `This tool call was already executed ${Math.round((now - lastCallTime) / 1e3)}s ago`
|
|
19003
|
+
};
|
|
19004
|
+
}
|
|
19005
|
+
this.recentToolCalls.set(callSignature, now);
|
|
19006
|
+
for (const [key, time] of this.recentToolCalls.entries()) {
|
|
19007
|
+
if (now - time > this.duplicateWindowMs) {
|
|
19008
|
+
this.recentToolCalls.delete(key);
|
|
19009
|
+
}
|
|
19010
|
+
}
|
|
18982
19011
|
const planModeState = this.getPlanModeState();
|
|
18983
19012
|
if (planModeState?.active) {
|
|
18984
19013
|
const readonlyOverlay = this.getReadonlyOverlay();
|
|
@@ -18986,6 +19015,25 @@ Current working directory: ${process.cwd()}`
|
|
|
18986
19015
|
return await readonlyOverlay.interceptToolCall(toolCall);
|
|
18987
19016
|
}
|
|
18988
19017
|
}
|
|
19018
|
+
if (!toolCall.function?.arguments) {
|
|
19019
|
+
console.error(`[GrokAgent] Tool call missing function arguments:`, toolCall);
|
|
19020
|
+
return {
|
|
19021
|
+
success: false,
|
|
19022
|
+
error: `Tool call ${toolCall.function?.name || "unknown"} missing required arguments`,
|
|
19023
|
+
details: `This appears to be a malformed tool call. The AI model may have generated invalid XML or concatenated multiple tool calls.`
|
|
19024
|
+
};
|
|
19025
|
+
}
|
|
19026
|
+
if (typeof toolCall.function.arguments === "string" && (toolCall.function.arguments.includes("str_replace_editorstr_replace_editor") || toolCall.function.arguments.includes("view_fileview_file") || toolCall.function.arguments.includes("create_filecreate_file") || toolCall.function.arguments.includes("}{") || toolCall.function.name?.includes("view_file") && toolCall.function.name !== "view_file")) {
|
|
19027
|
+
console.error(`[GrokAgent] Detected malformed XML in tool call - appears to be concatenated:`, {
|
|
19028
|
+
toolName: toolCall.function.name,
|
|
19029
|
+
arguments: toolCall.function.arguments
|
|
19030
|
+
});
|
|
19031
|
+
return {
|
|
19032
|
+
success: false,
|
|
19033
|
+
error: `Malformed tool call detected - appears to be concatenated XML without proper structure`,
|
|
19034
|
+
details: `The AI model generated invalid XML by concatenating multiple tool calls. This is a model generation issue that requires single, properly formatted tool calls.`
|
|
19035
|
+
};
|
|
19036
|
+
}
|
|
18989
19037
|
let args;
|
|
18990
19038
|
try {
|
|
18991
19039
|
args = JSON.parse(toolCall.function.arguments);
|
|
@@ -18997,14 +19045,14 @@ Current working directory: ${process.cwd()}`
|
|
|
18997
19045
|
toolCall
|
|
18998
19046
|
});
|
|
18999
19047
|
try {
|
|
19000
|
-
const cleanedArgs = toolCall.function.arguments.replace(/,\s*}/g, "}").replace(/,\s*]/g, "]").trim();
|
|
19048
|
+
const cleanedArgs = toolCall.function.arguments.replace(/,\s*}/g, "}").replace(/,\s*]/g, "]").replace(/^\s*{?\s*/, "{").replace(/\s*}?\s*$/, "}").trim();
|
|
19001
19049
|
args = JSON.parse(cleanedArgs);
|
|
19002
19050
|
console.log(`[GrokAgent] JSON parsing recovered after cleanup`);
|
|
19003
19051
|
} catch (retryError) {
|
|
19004
19052
|
return {
|
|
19005
19053
|
success: false,
|
|
19006
19054
|
error: `Invalid JSON arguments for ${toolCall.function.name}: ${parseError.message}. Arguments: ${toolCall.function.arguments}`,
|
|
19007
|
-
details: `Tool call failed due to malformed JSON. This is likely a model generation issue.`
|
|
19055
|
+
details: `Tool call failed due to malformed JSON. This is likely a model generation issue. Try using single tool calls with proper XML structure.`
|
|
19008
19056
|
};
|
|
19009
19057
|
}
|
|
19010
19058
|
}
|
|
@@ -19050,10 +19098,10 @@ Current working directory: ${process.cwd()}`
|
|
|
19050
19098
|
return await this.textEditor.view(args.path, range);
|
|
19051
19099
|
} catch (error) {
|
|
19052
19100
|
console.warn(`view_file tool failed, falling back to bash: ${error.message}`);
|
|
19053
|
-
const
|
|
19054
|
-
let command = `cat "${
|
|
19101
|
+
const path39 = args.path;
|
|
19102
|
+
let command = `cat "${path39}"`;
|
|
19055
19103
|
if (args.start_line && args.end_line) {
|
|
19056
|
-
command = `sed -n '${args.start_line},${args.end_line}p' "${
|
|
19104
|
+
command = `sed -n '${args.start_line},${args.end_line}p' "${path39}"`;
|
|
19057
19105
|
}
|
|
19058
19106
|
return await this.bash.execute(command);
|
|
19059
19107
|
}
|
|
@@ -19264,6 +19312,25 @@ EOF`;
|
|
|
19264
19312
|
}
|
|
19265
19313
|
async executeMCPTool(toolCall) {
|
|
19266
19314
|
try {
|
|
19315
|
+
if (!toolCall.function?.arguments) {
|
|
19316
|
+
console.error(`[GrokAgent] MCP tool call missing function arguments:`, toolCall);
|
|
19317
|
+
return {
|
|
19318
|
+
success: false,
|
|
19319
|
+
error: `MCP tool call ${toolCall.function?.name || "unknown"} missing required arguments`,
|
|
19320
|
+
details: `This appears to be a malformed MCP tool call. The AI model may have generated invalid XML or concatenated multiple tool calls.`
|
|
19321
|
+
};
|
|
19322
|
+
}
|
|
19323
|
+
if (typeof toolCall.function.arguments === "string" && (toolCall.function.arguments.includes("mcp__") && toolCall.function.arguments.match(/mcp__\w+mcp__/) || toolCall.function.name?.startsWith("mcp__") && toolCall.function.name.split("__").length > 3)) {
|
|
19324
|
+
console.error(`[GrokAgent] Detected malformed XML in MCP tool call:`, {
|
|
19325
|
+
toolName: toolCall.function.name,
|
|
19326
|
+
arguments: toolCall.function.arguments
|
|
19327
|
+
});
|
|
19328
|
+
return {
|
|
19329
|
+
success: false,
|
|
19330
|
+
error: `Malformed MCP tool call detected - appears to be concatenated XML`,
|
|
19331
|
+
details: `The AI model generated invalid XML by concatenating multiple MCP tool calls. Use single, properly formatted tool calls only.`
|
|
19332
|
+
};
|
|
19333
|
+
}
|
|
19267
19334
|
let args;
|
|
19268
19335
|
try {
|
|
19269
19336
|
args = JSON.parse(toolCall.function.arguments);
|
|
@@ -19275,7 +19342,7 @@ EOF`;
|
|
|
19275
19342
|
toolCall
|
|
19276
19343
|
});
|
|
19277
19344
|
try {
|
|
19278
|
-
const cleanedArgs = toolCall.function.arguments.replace(/,\s*}/g, "}").replace(/,\s*]/g, "]").trim();
|
|
19345
|
+
const cleanedArgs = toolCall.function.arguments.replace(/,\s*}/g, "}").replace(/,\s*]/g, "]").replace(/^\s*{?\s*/, "{").replace(/\s*}?\s*$/, "}").trim();
|
|
19279
19346
|
args = JSON.parse(cleanedArgs);
|
|
19280
19347
|
console.log(`[GrokAgent] MCP JSON parsing recovered after cleanup`);
|
|
19281
19348
|
} catch (retryError) {
|
|
@@ -19634,6 +19701,10 @@ ${output?.plan?.summary || "Task completed"}`,
|
|
|
19634
19701
|
instructions += "- Keep responses CONCISE and to the point. Avoid lengthy explanations.\n";
|
|
19635
19702
|
instructions += "- Prioritize brevity over detail unless specifically requested.\n";
|
|
19636
19703
|
instructions += "- Use minimal formatting and avoid verbose tool descriptions.\n";
|
|
19704
|
+
instructions += "- NEVER use separators like ### or --- between tool results and your response.\n";
|
|
19705
|
+
instructions += "- Provide analysis immediately after tools without visual dividers.\n";
|
|
19706
|
+
instructions += "- You may use **bold** and _italic_ for emphasis when helpful.\n";
|
|
19707
|
+
instructions += "- Match Claude Code style: tool outputs followed by clean, well-formatted analysis.\n";
|
|
19637
19708
|
break;
|
|
19638
19709
|
case "normal":
|
|
19639
19710
|
instructions += "- Provide balanced responses with appropriate detail.\n";
|
|
@@ -19659,6 +19730,11 @@ ${output?.plan?.summary || "Task completed"}`,
|
|
|
19659
19730
|
instructions += "- Provide detailed context for all operations.\n";
|
|
19660
19731
|
break;
|
|
19661
19732
|
}
|
|
19733
|
+
instructions += "\n";
|
|
19734
|
+
instructions += "\n\u{1F4A1} VISUAL FORMATTING:\n";
|
|
19735
|
+
instructions += "- Use emojis for status: \u2705 success, \u274C error, \u26A0\uFE0F warning, \u{1F4A1} tips\n";
|
|
19736
|
+
instructions += "- Add checkmarks for completed features or working items\n";
|
|
19737
|
+
instructions += "- Use appropriate emojis to make responses more scannable\n";
|
|
19662
19738
|
return instructions;
|
|
19663
19739
|
}
|
|
19664
19740
|
// Plan Mode integration methods
|
|
@@ -19863,150 +19939,21 @@ var init_use_input_history = __esm({
|
|
|
19863
19939
|
"src/hooks/use-input-history.ts"() {
|
|
19864
19940
|
}
|
|
19865
19941
|
});
|
|
19866
|
-
|
|
19867
|
-
// src/services/paste-detection.ts
|
|
19868
|
-
function getPasteDetectionService() {
|
|
19869
|
-
if (!globalPasteService) {
|
|
19870
|
-
globalPasteService = new PasteDetectionService();
|
|
19871
|
-
}
|
|
19872
|
-
return globalPasteService;
|
|
19873
|
-
}
|
|
19874
|
-
var PasteDetectionService, globalPasteService;
|
|
19875
|
-
var init_paste_detection = __esm({
|
|
19876
|
-
"src/services/paste-detection.ts"() {
|
|
19877
|
-
PasteDetectionService = class {
|
|
19878
|
-
constructor(thresholds) {
|
|
19879
|
-
this.pasteCounter = 0;
|
|
19880
|
-
this.debug = process.env.GROK_PASTE_DEBUG === "true";
|
|
19881
|
-
this.thresholds = {
|
|
19882
|
-
lineThreshold: thresholds?.lineThreshold ?? this.getDefaultLineThreshold(),
|
|
19883
|
-
charThreshold: thresholds?.charThreshold ?? this.getDefaultCharThreshold()
|
|
19884
|
-
};
|
|
19885
|
-
}
|
|
19886
|
-
/**
|
|
19887
|
-
* Detects if new content represents a paste operation that should be summarized
|
|
19888
|
-
*/
|
|
19889
|
-
detectPaste(oldValue, newValue) {
|
|
19890
|
-
const added = this.getAddedContent(oldValue, newValue);
|
|
19891
|
-
if (this.debug) {
|
|
19892
|
-
console.log("\u{1F50D} Paste Detection Debug:", {
|
|
19893
|
-
addedLength: added?.length || 0,
|
|
19894
|
-
lineCount: added ? this.countLines(added) : 0,
|
|
19895
|
-
thresholds: this.thresholds,
|
|
19896
|
-
shouldSummarize: added ? this.shouldSummarize(added) : false
|
|
19897
|
-
});
|
|
19898
|
-
}
|
|
19899
|
-
if (!added || !this.shouldSummarize(added)) {
|
|
19900
|
-
return null;
|
|
19901
|
-
}
|
|
19902
|
-
this.pasteCounter++;
|
|
19903
|
-
return {
|
|
19904
|
-
content: added,
|
|
19905
|
-
lineCount: this.countLines(added),
|
|
19906
|
-
charCount: added.length,
|
|
19907
|
-
pasteNumber: this.pasteCounter,
|
|
19908
|
-
summary: this.createPasteSummary(added, this.pasteCounter)
|
|
19909
|
-
};
|
|
19910
|
-
}
|
|
19911
|
-
/**
|
|
19912
|
-
* Determines if content should be summarized based on thresholds
|
|
19913
|
-
*/
|
|
19914
|
-
shouldSummarize(content) {
|
|
19915
|
-
const lineCount = this.countLines(content);
|
|
19916
|
-
return lineCount > this.thresholds.lineThreshold || content.length > this.thresholds.charThreshold;
|
|
19917
|
-
}
|
|
19918
|
-
/**
|
|
19919
|
-
* Creates a paste summary in the format: [Pasted text #N +X lines]
|
|
19920
|
-
*/
|
|
19921
|
-
createPasteSummary(content, pasteNumber) {
|
|
19922
|
-
const lineCount = this.countLines(content);
|
|
19923
|
-
const pluralLines = lineCount === 1 ? "line" : "lines";
|
|
19924
|
-
return `[Pasted text #${pasteNumber} +${lineCount} ${pluralLines}]`;
|
|
19925
|
-
}
|
|
19926
|
-
/**
|
|
19927
|
-
* Resets the paste counter (useful for new sessions)
|
|
19928
|
-
*/
|
|
19929
|
-
resetCounter() {
|
|
19930
|
-
this.pasteCounter = 0;
|
|
19931
|
-
}
|
|
19932
|
-
/**
|
|
19933
|
-
* Updates thresholds for paste detection
|
|
19934
|
-
*/
|
|
19935
|
-
updateThresholds(thresholds) {
|
|
19936
|
-
this.thresholds = {
|
|
19937
|
-
...this.thresholds,
|
|
19938
|
-
...thresholds
|
|
19939
|
-
};
|
|
19940
|
-
}
|
|
19941
|
-
/**
|
|
19942
|
-
* Gets current paste counter value
|
|
19943
|
-
*/
|
|
19944
|
-
getCurrentCounter() {
|
|
19945
|
-
return this.pasteCounter;
|
|
19946
|
-
}
|
|
19947
|
-
/**
|
|
19948
|
-
* Gets current thresholds
|
|
19949
|
-
*/
|
|
19950
|
-
getThresholds() {
|
|
19951
|
-
return { ...this.thresholds };
|
|
19952
|
-
}
|
|
19953
|
-
/**
|
|
19954
|
-
* Extracts the content that was added between old and new values
|
|
19955
|
-
*/
|
|
19956
|
-
getAddedContent(oldValue, newValue) {
|
|
19957
|
-
if (newValue.startsWith(oldValue)) {
|
|
19958
|
-
return newValue.slice(oldValue.length);
|
|
19959
|
-
}
|
|
19960
|
-
return "";
|
|
19961
|
-
}
|
|
19962
|
-
/**
|
|
19963
|
-
* Counts the number of lines in content
|
|
19964
|
-
*/
|
|
19965
|
-
countLines(content) {
|
|
19966
|
-
if (!content) return 0;
|
|
19967
|
-
const lines = content.split(/\r\n|\r|\n/);
|
|
19968
|
-
return lines[lines.length - 1] === "" ? lines.length - 1 : lines.length;
|
|
19969
|
-
}
|
|
19970
|
-
/**
|
|
19971
|
-
* Gets default line threshold from environment or config
|
|
19972
|
-
*/
|
|
19973
|
-
getDefaultLineThreshold() {
|
|
19974
|
-
const envValue = process.env.GROK_PASTE_LINE_THRESHOLD;
|
|
19975
|
-
if (envValue) {
|
|
19976
|
-
const parsed = parseInt(envValue, 10);
|
|
19977
|
-
if (!isNaN(parsed) && parsed > 0) {
|
|
19978
|
-
return parsed;
|
|
19979
|
-
}
|
|
19980
|
-
}
|
|
19981
|
-
return 2;
|
|
19982
|
-
}
|
|
19983
|
-
/**
|
|
19984
|
-
* Gets default character threshold from environment or config
|
|
19985
|
-
*/
|
|
19986
|
-
getDefaultCharThreshold() {
|
|
19987
|
-
const envValue = process.env.GROK_PASTE_CHAR_THRESHOLD;
|
|
19988
|
-
if (envValue) {
|
|
19989
|
-
const parsed = parseInt(envValue, 10);
|
|
19990
|
-
if (!isNaN(parsed) && parsed > 0) {
|
|
19991
|
-
return parsed;
|
|
19992
|
-
}
|
|
19993
|
-
}
|
|
19994
|
-
return 50;
|
|
19995
|
-
}
|
|
19996
|
-
};
|
|
19997
|
-
globalPasteService = null;
|
|
19998
|
-
}
|
|
19999
|
-
});
|
|
20000
19942
|
function useEnhancedInput({
|
|
20001
19943
|
onSubmit,
|
|
20002
19944
|
onEscape,
|
|
20003
19945
|
onSpecialKey,
|
|
20004
|
-
onPasteDetected,
|
|
20005
19946
|
disabled = false,
|
|
20006
19947
|
multiline = false
|
|
20007
19948
|
} = {}) {
|
|
20008
19949
|
const [input, setInputState] = useState("");
|
|
20009
19950
|
const [cursorPosition, setCursorPositionState] = useState(0);
|
|
19951
|
+
const debugSetInputState = useCallback((newInput) => {
|
|
19952
|
+
setInputState(newInput);
|
|
19953
|
+
}, []);
|
|
19954
|
+
const debugSetCursorPositionState = useCallback((newPos) => {
|
|
19955
|
+
setCursorPositionState(newPos);
|
|
19956
|
+
}, []);
|
|
20010
19957
|
const isMultilineRef = useRef(multiline);
|
|
20011
19958
|
const {
|
|
20012
19959
|
addToHistory,
|
|
@@ -20016,32 +19963,34 @@ function useEnhancedInput({
|
|
|
20016
19963
|
isNavigatingHistory
|
|
20017
19964
|
} = useInputHistory();
|
|
20018
19965
|
const setInput = useCallback((text) => {
|
|
20019
|
-
|
|
20020
|
-
|
|
20021
|
-
|
|
19966
|
+
enhancedLog("\u{1F504} setInput called");
|
|
19967
|
+
enhancedLog("setInput details:", {
|
|
19968
|
+
previousInput: input.slice(0, 100) + (input.length > 100 ? "..." : ""),
|
|
19969
|
+
newText: text.slice(0, 100) + (text.length > 100 ? "..." : ""),
|
|
19970
|
+
previousLength: input.length,
|
|
19971
|
+
newLength: text.length,
|
|
19972
|
+
cursorPosition,
|
|
19973
|
+
isNavigatingHistory: isNavigatingHistory()
|
|
19974
|
+
});
|
|
19975
|
+
debugSetInputState(text);
|
|
19976
|
+
debugSetCursorPositionState(Math.min(text.length, cursorPosition));
|
|
20022
19977
|
if (!isNavigatingHistory()) {
|
|
20023
19978
|
setOriginalInput(text);
|
|
20024
19979
|
}
|
|
20025
|
-
|
|
20026
|
-
|
|
20027
|
-
const pasteEvent = pasteService.detectPaste(previousInput, text);
|
|
20028
|
-
if (pasteEvent) {
|
|
20029
|
-
onPasteDetected(pasteEvent);
|
|
20030
|
-
}
|
|
20031
|
-
}
|
|
20032
|
-
}, [input, cursorPosition, isNavigatingHistory, setOriginalInput, onPasteDetected]);
|
|
19980
|
+
enhancedLog("\u2705 setInput completed");
|
|
19981
|
+
}, [input, cursorPosition, isNavigatingHistory, setOriginalInput]);
|
|
20033
19982
|
const setCursorPosition = useCallback((position) => {
|
|
20034
|
-
|
|
20035
|
-
}, [input.length]);
|
|
19983
|
+
debugSetCursorPositionState(Math.max(0, Math.min(input.length, position)));
|
|
19984
|
+
}, [input.length, debugSetCursorPositionState]);
|
|
20036
19985
|
const clearInput = useCallback(() => {
|
|
20037
|
-
|
|
20038
|
-
|
|
19986
|
+
debugSetInputState("");
|
|
19987
|
+
debugSetCursorPositionState(0);
|
|
20039
19988
|
setOriginalInput("");
|
|
20040
|
-
}, [setOriginalInput]);
|
|
19989
|
+
}, [setOriginalInput, debugSetInputState, debugSetCursorPositionState]);
|
|
20041
19990
|
const insertAtCursor = useCallback((text) => {
|
|
20042
19991
|
const result = insertText(input, cursorPosition, text);
|
|
20043
|
-
|
|
20044
|
-
|
|
19992
|
+
debugSetInputState(result.text);
|
|
19993
|
+
debugSetCursorPositionState(result.position);
|
|
20045
19994
|
setOriginalInput(result.text);
|
|
20046
19995
|
}, [input, cursorPosition, setOriginalInput]);
|
|
20047
19996
|
const handleSubmit = useCallback(() => {
|
|
@@ -20052,10 +20001,31 @@ function useEnhancedInput({
|
|
|
20052
20001
|
}
|
|
20053
20002
|
}, [input, addToHistory, onSubmit, clearInput]);
|
|
20054
20003
|
const handleInput = useCallback((inputChar, key) => {
|
|
20055
|
-
|
|
20004
|
+
enhancedLog("\u2328\uFE0F handleInput called");
|
|
20005
|
+
enhancedLog("Input event:", {
|
|
20006
|
+
inputChar: inputChar === "" ? "(empty)" : inputChar,
|
|
20007
|
+
charCode: inputChar.charCodeAt(0) || "N/A",
|
|
20008
|
+
key: {
|
|
20009
|
+
name: key.name || "undefined",
|
|
20010
|
+
ctrl: !!key.ctrl,
|
|
20011
|
+
meta: !!key.meta,
|
|
20012
|
+
shift: !!key.shift,
|
|
20013
|
+
paste: !!key.paste,
|
|
20014
|
+
return: !!key.return,
|
|
20015
|
+
backspace: !!key.backspace,
|
|
20016
|
+
delete: !!key.delete
|
|
20017
|
+
},
|
|
20018
|
+
currentInput: input.slice(0, 50) + (input.length > 50 ? "..." : ""),
|
|
20019
|
+
currentInputLength: input.length,
|
|
20020
|
+
disabled
|
|
20021
|
+
});
|
|
20022
|
+
if (disabled) {
|
|
20023
|
+
enhancedLog("\u274C Input disabled, returning early");
|
|
20024
|
+
return;
|
|
20025
|
+
}
|
|
20056
20026
|
if (key.ctrl && inputChar === "c" || inputChar === "") {
|
|
20057
|
-
|
|
20058
|
-
|
|
20027
|
+
debugSetInputState("");
|
|
20028
|
+
debugSetCursorPositionState(0);
|
|
20059
20029
|
setOriginalInput("");
|
|
20060
20030
|
return;
|
|
20061
20031
|
}
|
|
@@ -20069,8 +20039,8 @@ function useEnhancedInput({
|
|
|
20069
20039
|
if (key.return) {
|
|
20070
20040
|
if (multiline && key.shift) {
|
|
20071
20041
|
const result = insertText(input, cursorPosition, "\n");
|
|
20072
|
-
|
|
20073
|
-
|
|
20042
|
+
debugSetInputState(result.text);
|
|
20043
|
+
debugSetCursorPositionState(result.position);
|
|
20074
20044
|
setOriginalInput(result.text);
|
|
20075
20045
|
} else {
|
|
20076
20046
|
handleSubmit();
|
|
@@ -20080,58 +20050,58 @@ function useEnhancedInput({
|
|
|
20080
20050
|
if ((key.upArrow || key.name === "up") && !key.ctrl && !key.meta) {
|
|
20081
20051
|
const historyInput = navigateHistory("up");
|
|
20082
20052
|
if (historyInput !== null) {
|
|
20083
|
-
|
|
20084
|
-
|
|
20053
|
+
debugSetInputState(historyInput);
|
|
20054
|
+
debugSetCursorPositionState(historyInput.length);
|
|
20085
20055
|
}
|
|
20086
20056
|
return;
|
|
20087
20057
|
}
|
|
20088
20058
|
if ((key.downArrow || key.name === "down") && !key.ctrl && !key.meta) {
|
|
20089
20059
|
const historyInput = navigateHistory("down");
|
|
20090
20060
|
if (historyInput !== null) {
|
|
20091
|
-
|
|
20092
|
-
|
|
20061
|
+
debugSetInputState(historyInput);
|
|
20062
|
+
debugSetCursorPositionState(historyInput.length);
|
|
20093
20063
|
}
|
|
20094
20064
|
return;
|
|
20095
20065
|
}
|
|
20096
20066
|
if ((key.leftArrow || key.name === "left") && key.ctrl && !inputChar.includes("[")) {
|
|
20097
20067
|
const newPos = moveToPreviousWord(input, cursorPosition);
|
|
20098
|
-
|
|
20068
|
+
debugSetCursorPositionState(newPos);
|
|
20099
20069
|
return;
|
|
20100
20070
|
}
|
|
20101
20071
|
if ((key.rightArrow || key.name === "right") && key.ctrl && !inputChar.includes("[")) {
|
|
20102
20072
|
const newPos = moveToNextWord(input, cursorPosition);
|
|
20103
|
-
|
|
20073
|
+
debugSetCursorPositionState(newPos);
|
|
20104
20074
|
return;
|
|
20105
20075
|
}
|
|
20106
20076
|
if (key.leftArrow || key.name === "left") {
|
|
20107
20077
|
const newPos = Math.max(0, cursorPosition - 1);
|
|
20108
|
-
|
|
20078
|
+
debugSetCursorPositionState(newPos);
|
|
20109
20079
|
return;
|
|
20110
20080
|
}
|
|
20111
20081
|
if (key.rightArrow || key.name === "right") {
|
|
20112
20082
|
const newPos = Math.min(input.length, cursorPosition + 1);
|
|
20113
|
-
|
|
20083
|
+
debugSetCursorPositionState(newPos);
|
|
20114
20084
|
return;
|
|
20115
20085
|
}
|
|
20116
20086
|
if (key.ctrl && inputChar === "a" || key.name === "home") {
|
|
20117
|
-
|
|
20087
|
+
debugSetCursorPositionState(0);
|
|
20118
20088
|
return;
|
|
20119
20089
|
}
|
|
20120
20090
|
if (key.ctrl && inputChar === "e" || key.name === "end") {
|
|
20121
|
-
|
|
20091
|
+
debugSetCursorPositionState(input.length);
|
|
20122
20092
|
return;
|
|
20123
20093
|
}
|
|
20124
20094
|
const isBackspace = key.backspace || key.name === "backspace" || inputChar === "\b" || inputChar === "\x7F" || key.delete && inputChar === "" && !key.shift;
|
|
20125
20095
|
if (isBackspace) {
|
|
20126
20096
|
if (key.ctrl || key.meta) {
|
|
20127
20097
|
const result = deleteWordBefore(input, cursorPosition);
|
|
20128
|
-
|
|
20129
|
-
|
|
20098
|
+
debugSetInputState(result.text);
|
|
20099
|
+
debugSetCursorPositionState(result.position);
|
|
20130
20100
|
setOriginalInput(result.text);
|
|
20131
20101
|
} else {
|
|
20132
20102
|
const result = deleteCharBefore(input, cursorPosition);
|
|
20133
|
-
|
|
20134
|
-
|
|
20103
|
+
debugSetInputState(result.text);
|
|
20104
|
+
debugSetCursorPositionState(result.position);
|
|
20135
20105
|
setOriginalInput(result.text);
|
|
20136
20106
|
}
|
|
20137
20107
|
return;
|
|
@@ -20139,13 +20109,13 @@ function useEnhancedInput({
|
|
|
20139
20109
|
if (key.delete && inputChar !== "" || key.ctrl && inputChar === "d") {
|
|
20140
20110
|
if (key.ctrl || key.meta) {
|
|
20141
20111
|
const result = deleteWordAfter(input, cursorPosition);
|
|
20142
|
-
|
|
20143
|
-
|
|
20112
|
+
debugSetInputState(result.text);
|
|
20113
|
+
debugSetCursorPositionState(result.position);
|
|
20144
20114
|
setOriginalInput(result.text);
|
|
20145
20115
|
} else {
|
|
20146
20116
|
const result = deleteCharAfter(input, cursorPosition);
|
|
20147
|
-
|
|
20148
|
-
|
|
20117
|
+
debugSetInputState(result.text);
|
|
20118
|
+
debugSetCursorPositionState(result.position);
|
|
20149
20119
|
setOriginalInput(result.text);
|
|
20150
20120
|
}
|
|
20151
20121
|
return;
|
|
@@ -20153,36 +20123,57 @@ function useEnhancedInput({
|
|
|
20153
20123
|
if (key.ctrl && inputChar === "k") {
|
|
20154
20124
|
const lineEnd = moveToLineEnd(input, cursorPosition);
|
|
20155
20125
|
const newText = input.slice(0, cursorPosition) + input.slice(lineEnd);
|
|
20156
|
-
|
|
20126
|
+
debugSetInputState(newText);
|
|
20157
20127
|
setOriginalInput(newText);
|
|
20158
20128
|
return;
|
|
20159
20129
|
}
|
|
20160
20130
|
if (key.ctrl && inputChar === "u") {
|
|
20161
20131
|
const lineStart = moveToLineStart(input, cursorPosition);
|
|
20162
20132
|
const newText = input.slice(0, lineStart) + input.slice(cursorPosition);
|
|
20163
|
-
|
|
20164
|
-
|
|
20133
|
+
debugSetInputState(newText);
|
|
20134
|
+
debugSetCursorPositionState(lineStart);
|
|
20165
20135
|
setOriginalInput(newText);
|
|
20166
20136
|
return;
|
|
20167
20137
|
}
|
|
20168
20138
|
if (key.ctrl && inputChar === "w") {
|
|
20169
20139
|
const result = deleteWordBefore(input, cursorPosition);
|
|
20170
|
-
|
|
20171
|
-
|
|
20140
|
+
debugSetInputState(result.text);
|
|
20141
|
+
debugSetCursorPositionState(result.position);
|
|
20172
20142
|
setOriginalInput(result.text);
|
|
20173
20143
|
return;
|
|
20174
20144
|
}
|
|
20175
20145
|
if (key.ctrl && inputChar === "x") {
|
|
20176
|
-
|
|
20177
|
-
|
|
20146
|
+
debugSetInputState("");
|
|
20147
|
+
debugSetCursorPositionState(0);
|
|
20178
20148
|
setOriginalInput("");
|
|
20179
20149
|
return;
|
|
20180
20150
|
}
|
|
20181
20151
|
if (inputChar && !key.ctrl && !key.meta) {
|
|
20152
|
+
enhancedLog("\u{1F4DD} Regular character input detected");
|
|
20153
|
+
enhancedLog("Character details:", {
|
|
20154
|
+
character: inputChar,
|
|
20155
|
+
currentPosition: cursorPosition,
|
|
20156
|
+
currentInputLength: input.length,
|
|
20157
|
+
willInsertAt: cursorPosition
|
|
20158
|
+
});
|
|
20182
20159
|
const result = insertText(input, cursorPosition, inputChar);
|
|
20183
|
-
|
|
20184
|
-
|
|
20160
|
+
enhancedLog("\u{1F4DD} Text insertion result:", {
|
|
20161
|
+
oldLength: input.length,
|
|
20162
|
+
newLength: result.text.length,
|
|
20163
|
+
newPosition: result.position,
|
|
20164
|
+
insertedChar: inputChar
|
|
20165
|
+
});
|
|
20166
|
+
debugSetInputState(result.text);
|
|
20167
|
+
debugSetCursorPositionState(result.position);
|
|
20185
20168
|
setOriginalInput(result.text);
|
|
20169
|
+
enhancedLog("\u2705 Regular character input completed");
|
|
20170
|
+
} else {
|
|
20171
|
+
enhancedLog("\u274C Character input skipped:", {
|
|
20172
|
+
hasInputChar: !!inputChar,
|
|
20173
|
+
isCtrl: !!key.ctrl,
|
|
20174
|
+
isMeta: !!key.meta,
|
|
20175
|
+
reason: !inputChar ? "No input char" : key.ctrl ? "Ctrl pressed" : "Meta pressed"
|
|
20176
|
+
});
|
|
20186
20177
|
}
|
|
20187
20178
|
}, [disabled, onSpecialKey, input, cursorPosition, multiline, handleSubmit, navigateHistory, setOriginalInput]);
|
|
20188
20179
|
return {
|
|
@@ -20197,11 +20188,13 @@ function useEnhancedInput({
|
|
|
20197
20188
|
handleInput
|
|
20198
20189
|
};
|
|
20199
20190
|
}
|
|
20191
|
+
var enhancedLog;
|
|
20200
20192
|
var init_use_enhanced_input = __esm({
|
|
20201
20193
|
"src/hooks/use-enhanced-input.ts"() {
|
|
20202
20194
|
init_text_utils();
|
|
20203
20195
|
init_use_input_history();
|
|
20204
|
-
|
|
20196
|
+
enhancedLog = (..._args) => {
|
|
20197
|
+
};
|
|
20205
20198
|
}
|
|
20206
20199
|
});
|
|
20207
20200
|
|
|
@@ -27099,7 +27092,7 @@ var init_package = __esm({
|
|
|
27099
27092
|
package_default = {
|
|
27100
27093
|
type: "module",
|
|
27101
27094
|
name: "@xagent/one-shot",
|
|
27102
|
-
version: "1.2.
|
|
27095
|
+
version: "1.2.2",
|
|
27103
27096
|
description: "An open-source AI agent that brings advanced AI capabilities directly into your terminal with automatic documentation updates.",
|
|
27104
27097
|
main: "dist/index.js",
|
|
27105
27098
|
module: "dist/index.js",
|
|
@@ -27518,23 +27511,6 @@ function useInputHandler({
|
|
|
27518
27511
|
}
|
|
27519
27512
|
}
|
|
27520
27513
|
};
|
|
27521
|
-
const handlePasteDetected = (pasteEvent) => {
|
|
27522
|
-
const userEntry = {
|
|
27523
|
-
type: "user",
|
|
27524
|
-
content: pasteEvent.content,
|
|
27525
|
-
// Full content for AI (when submitted)
|
|
27526
|
-
displayContent: pasteEvent.summary,
|
|
27527
|
-
// Summary for UI display
|
|
27528
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
27529
|
-
isPasteSummary: true,
|
|
27530
|
-
pasteMetadata: {
|
|
27531
|
-
pasteNumber: pasteEvent.pasteNumber,
|
|
27532
|
-
lineCount: pasteEvent.lineCount,
|
|
27533
|
-
charCount: pasteEvent.charCount
|
|
27534
|
-
}
|
|
27535
|
-
};
|
|
27536
|
-
setChatHistory((prev) => [...prev, userEntry]);
|
|
27537
|
-
};
|
|
27538
27514
|
const handleInputChange = (newInput) => {
|
|
27539
27515
|
if (newInput.startsWith("/")) {
|
|
27540
27516
|
setShowCommandSuggestions(true);
|
|
@@ -27550,20 +27526,75 @@ function useInputHandler({
|
|
|
27550
27526
|
setInput,
|
|
27551
27527
|
setCursorPosition,
|
|
27552
27528
|
clearInput,
|
|
27529
|
+
insertAtCursor,
|
|
27553
27530
|
resetHistory,
|
|
27554
27531
|
handleInput
|
|
27555
27532
|
} = useEnhancedInput({
|
|
27556
27533
|
onSubmit: handleInputSubmit,
|
|
27557
27534
|
onSpecialKey: handleSpecialKey,
|
|
27558
|
-
|
|
27535
|
+
// Paste detection handled inline
|
|
27559
27536
|
disabled: isConfirmationActive,
|
|
27560
27537
|
multiline: true
|
|
27561
27538
|
// Enable multiline mode to handle pasted content properly
|
|
27562
27539
|
});
|
|
27540
|
+
if (typeof globalThis.grokPasteCache === "undefined") {
|
|
27541
|
+
globalThis.grokPasteCache = /* @__PURE__ */ new Map();
|
|
27542
|
+
}
|
|
27543
|
+
if (typeof globalThis.grokPasteCounter === "undefined") {
|
|
27544
|
+
globalThis.grokPasteCounter = 0;
|
|
27545
|
+
}
|
|
27563
27546
|
useInput((inputChar, key) => {
|
|
27564
27547
|
if (onGlobalShortcut && onGlobalShortcut(inputChar, key)) {
|
|
27565
27548
|
return;
|
|
27566
27549
|
}
|
|
27550
|
+
if (inputChar.length > 1) {
|
|
27551
|
+
const existingInputBeforePaste = input;
|
|
27552
|
+
const cursorPositionBeforePaste = cursorPosition;
|
|
27553
|
+
if (!globalThis.grokStreamingPasteBuffer) {
|
|
27554
|
+
globalThis.grokExistingInputBeforePaste = existingInputBeforePaste;
|
|
27555
|
+
globalThis.grokCursorPositionBeforePaste = cursorPositionBeforePaste;
|
|
27556
|
+
}
|
|
27557
|
+
if (!globalThis.grokStreamingPasteBuffer) {
|
|
27558
|
+
globalThis.grokStreamingPasteBuffer = "";
|
|
27559
|
+
}
|
|
27560
|
+
globalThis.grokStreamingPasteBuffer += inputChar;
|
|
27561
|
+
setTimeout(() => {
|
|
27562
|
+
const pastedContent = globalThis.grokStreamingPasteBuffer;
|
|
27563
|
+
if (pastedContent && (pastedContent.length > 100 || pastedContent.split(/\r\n|\r|\n/).length > 10)) {
|
|
27564
|
+
const lines = pastedContent.split(/\r\n|\r|\n/);
|
|
27565
|
+
globalThis.grokPasteCounter += 1;
|
|
27566
|
+
const summary = `[Pasted text #${globalThis.grokPasteCounter} +${lines.length} lines]`;
|
|
27567
|
+
globalThis.grokPasteCache.set(summary, pastedContent);
|
|
27568
|
+
const existingInput2 = globalThis.grokExistingInputBeforePaste || "";
|
|
27569
|
+
const cursorPos = globalThis.grokCursorPositionBeforePaste || 0;
|
|
27570
|
+
setInput(existingInput2);
|
|
27571
|
+
setCursorPosition(cursorPos);
|
|
27572
|
+
setTimeout(() => {
|
|
27573
|
+
insertAtCursor(summary);
|
|
27574
|
+
}, 10);
|
|
27575
|
+
const pasteConfirmationEntry = {
|
|
27576
|
+
type: "assistant",
|
|
27577
|
+
content: `\u{1F4C4} Large paste detected: ${lines.length} lines, showing summary`,
|
|
27578
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
27579
|
+
};
|
|
27580
|
+
setChatHistory((prev) => [...prev, pasteConfirmationEntry]);
|
|
27581
|
+
} else if (pastedContent) {
|
|
27582
|
+
const existingInput2 = globalThis.grokExistingInputBeforePaste || "";
|
|
27583
|
+
const cursorPos = globalThis.grokCursorPositionBeforePaste || 0;
|
|
27584
|
+
const beforeCursor = existingInput2.slice(0, cursorPos);
|
|
27585
|
+
const afterCursor = existingInput2.slice(cursorPos);
|
|
27586
|
+
const combinedContent = beforeCursor + pastedContent + afterCursor;
|
|
27587
|
+
setInput(combinedContent);
|
|
27588
|
+
setTimeout(() => {
|
|
27589
|
+
setCursorPosition(beforeCursor.length + pastedContent.length);
|
|
27590
|
+
}, 0);
|
|
27591
|
+
}
|
|
27592
|
+
globalThis.grokStreamingPasteBuffer = void 0;
|
|
27593
|
+
globalThis.grokExistingInputBeforePaste = void 0;
|
|
27594
|
+
globalThis.grokCursorPositionBeforePaste = void 0;
|
|
27595
|
+
}, 100);
|
|
27596
|
+
return;
|
|
27597
|
+
}
|
|
27567
27598
|
handleInput(inputChar, key);
|
|
27568
27599
|
});
|
|
27569
27600
|
useEffect(() => {
|
|
@@ -28793,12 +28824,12 @@ Auto-compact automatically enables compact mode when conversations exceed thresh
|
|
|
28793
28824
|
content: `\u{1F50A} **Current Verbosity Level: ${verbosityLevel.toUpperCase()}**
|
|
28794
28825
|
|
|
28795
28826
|
**Available levels:**
|
|
28796
|
-
- \`quiet\` -
|
|
28827
|
+
- \`quiet\` - \u{1F3AF} **Claude Code mode**: Ultra-brief tool output (\`\u23BF Read X lines (ctrl+r to expand)\`)
|
|
28797
28828
|
- \`normal\` - Current default behavior with full details
|
|
28798
28829
|
- \`verbose\` - Additional details and debug information
|
|
28799
28830
|
|
|
28800
28831
|
**Usage:** \`/verbosity <level>\`
|
|
28801
|
-
**Example:** \`/verbosity quiet
|
|
28832
|
+
**Example:** \`/verbosity quiet\` (for Claude Code parity)`,
|
|
28802
28833
|
timestamp: /* @__PURE__ */ new Date()
|
|
28803
28834
|
};
|
|
28804
28835
|
setChatHistory((prev) => [...prev, levelEntry]);
|
|
@@ -28813,7 +28844,7 @@ Auto-compact automatically enables compact mode when conversations exceed thresh
|
|
|
28813
28844
|
type: "assistant",
|
|
28814
28845
|
content: `\u2705 **Verbosity level set to: ${newLevel.toUpperCase()}**
|
|
28815
28846
|
|
|
28816
|
-
Tool outputs will now show
|
|
28847
|
+
${newLevel === "quiet" ? "\u{1F3AF} **Claude Code mode activated!** Tool outputs will now show ultra-brief format: `\u23BF Read X lines (ctrl+r to expand)`" : newLevel === "normal" ? "Tool outputs will now show full details." : "Tool outputs will now show extra details and debug information."}`,
|
|
28817
28848
|
timestamp: /* @__PURE__ */ new Date()
|
|
28818
28849
|
};
|
|
28819
28850
|
setChatHistory((prev) => [...prev, confirmEntry]);
|
|
@@ -29220,24 +29251,27 @@ ${pushResult.error || "Git push failed"}
|
|
|
29220
29251
|
}
|
|
29221
29252
|
return false;
|
|
29222
29253
|
};
|
|
29223
|
-
const
|
|
29224
|
-
|
|
29225
|
-
|
|
29226
|
-
const
|
|
29227
|
-
const
|
|
29228
|
-
|
|
29229
|
-
|
|
29230
|
-
type: "user",
|
|
29231
|
-
content: userInput,
|
|
29232
|
-
displayContent: shouldSummarize ? pasteService.createPasteSummary(userInput, pasteService.getCurrentCounter() + 1) : userInput,
|
|
29233
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
29234
|
-
isPasteSummary: shouldSummarize
|
|
29235
|
-
};
|
|
29236
|
-
if (shouldSummarize) {
|
|
29237
|
-
pasteService.detectPaste("", userInput);
|
|
29238
|
-
}
|
|
29239
|
-
setChatHistory((prev) => [...prev, userEntry]);
|
|
29254
|
+
const expandPasteSummaryToFullContent = async (userInput) => {
|
|
29255
|
+
if (!globalThis.grokPasteCache) return userInput;
|
|
29256
|
+
let expandedInput = userInput;
|
|
29257
|
+
const cache = globalThis.grokPasteCache;
|
|
29258
|
+
for (const [summary, fullContent] of cache.entries()) {
|
|
29259
|
+
const cleanContent = fullContent.replace(/\r\n/g, "\n").replace(/\r/g, "\n").trim().split("\n").map((line) => line.trim()).join("\n");
|
|
29260
|
+
expandedInput = expandedInput.replace(summary, cleanContent);
|
|
29240
29261
|
}
|
|
29262
|
+
return expandedInput;
|
|
29263
|
+
};
|
|
29264
|
+
const processUserMessage = async (userInput) => {
|
|
29265
|
+
const expandedInput = await expandPasteSummaryToFullContent(userInput);
|
|
29266
|
+
const userEntry = {
|
|
29267
|
+
type: "user",
|
|
29268
|
+
content: expandedInput,
|
|
29269
|
+
// AI receives expanded content
|
|
29270
|
+
displayContent: userInput,
|
|
29271
|
+
// UI shows what user typed (may be summary)
|
|
29272
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
29273
|
+
};
|
|
29274
|
+
setChatHistory((prev) => [...prev, userEntry]);
|
|
29241
29275
|
setIsProcessing(true);
|
|
29242
29276
|
clearInput();
|
|
29243
29277
|
try {
|
|
@@ -29326,7 +29360,7 @@ ${pushResult.error || "Git push failed"}
|
|
|
29326
29360
|
}
|
|
29327
29361
|
lastUpdateTime = now;
|
|
29328
29362
|
};
|
|
29329
|
-
for await (const chunk of agent.processUserMessageStream(
|
|
29363
|
+
for await (const chunk of agent.processUserMessageStream(expandedInput)) {
|
|
29330
29364
|
switch (chunk.type) {
|
|
29331
29365
|
case "content":
|
|
29332
29366
|
if (chunk.content) {
|
|
@@ -29396,7 +29430,6 @@ var init_use_input_handler = __esm({
|
|
|
29396
29430
|
"src/hooks/use-input-handler.ts"() {
|
|
29397
29431
|
init_confirmation_service();
|
|
29398
29432
|
init_use_enhanced_input();
|
|
29399
|
-
init_paste_detection();
|
|
29400
29433
|
init_use_plan_mode();
|
|
29401
29434
|
init_command_suggestions();
|
|
29402
29435
|
init_model_config();
|
|
@@ -30448,18 +30481,179 @@ var init_user_message_entry = __esm({
|
|
|
30448
30481
|
};
|
|
30449
30482
|
}
|
|
30450
30483
|
});
|
|
30484
|
+
function MarkdownRenderer({ content }) {
|
|
30485
|
+
try {
|
|
30486
|
+
return /* @__PURE__ */ jsx(InlineMarkdown, { content });
|
|
30487
|
+
} catch (error) {
|
|
30488
|
+
console.error("Markdown rendering error:", error);
|
|
30489
|
+
return /* @__PURE__ */ jsx(Text, { wrap: "wrap", dimColor: false, children: content });
|
|
30490
|
+
}
|
|
30491
|
+
}
|
|
30492
|
+
function InlineMarkdown({ content }) {
|
|
30493
|
+
const lines = content.split("\n");
|
|
30494
|
+
return /* @__PURE__ */ jsx(Text, { wrap: "wrap", dimColor: false, children: lines.map((line, lineIndex) => /* @__PURE__ */ jsxs(React4.Fragment, { children: [
|
|
30495
|
+
lineIndex > 0 && "\n",
|
|
30496
|
+
parseInlineMarkdown(line).map((part, partIndex) => {
|
|
30497
|
+
if (part.type === "header") {
|
|
30498
|
+
return /* @__PURE__ */ jsx(Text, { bold: true, color: "white", children: part.text }, `${lineIndex}-${partIndex}`);
|
|
30499
|
+
}
|
|
30500
|
+
if (part.type === "bold") {
|
|
30501
|
+
return /* @__PURE__ */ jsx(Text, { bold: true, color: "white", children: part.text }, `${lineIndex}-${partIndex}`);
|
|
30502
|
+
}
|
|
30503
|
+
if (part.type === "italic") {
|
|
30504
|
+
return /* @__PURE__ */ jsx(Text, { italic: true, color: "gray", children: part.text }, `${lineIndex}-${partIndex}`);
|
|
30505
|
+
}
|
|
30506
|
+
if (part.type === "code") {
|
|
30507
|
+
return /* @__PURE__ */ jsx(Text, { color: "cyan", children: part.text }, `${lineIndex}-${partIndex}`);
|
|
30508
|
+
}
|
|
30509
|
+
if (part.type === "emoji") {
|
|
30510
|
+
const emoji = part.text;
|
|
30511
|
+
if (emoji === "\u2705" || emoji === "\u2713") {
|
|
30512
|
+
return /* @__PURE__ */ jsx(Text, { color: "green", children: emoji }, `${lineIndex}-${partIndex}`);
|
|
30513
|
+
}
|
|
30514
|
+
if (emoji === "\u274C" || emoji === "\u2717") {
|
|
30515
|
+
return /* @__PURE__ */ jsx(Text, { color: "red", children: emoji }, `${lineIndex}-${partIndex}`);
|
|
30516
|
+
}
|
|
30517
|
+
if (emoji === "\u26A0\uFE0F" || emoji === "\u26A0") {
|
|
30518
|
+
return /* @__PURE__ */ jsx(Text, { color: "yellow", children: emoji }, `${lineIndex}-${partIndex}`);
|
|
30519
|
+
}
|
|
30520
|
+
if (emoji === "\u{1F4A1}" || emoji === "\u2139\uFE0F" || emoji === "\u{1F50D}") {
|
|
30521
|
+
return /* @__PURE__ */ jsx(Text, { color: "blue", children: emoji }, `${lineIndex}-${partIndex}`);
|
|
30522
|
+
}
|
|
30523
|
+
return /* @__PURE__ */ jsx(Text, { color: "white", children: emoji }, `${lineIndex}-${partIndex}`);
|
|
30524
|
+
}
|
|
30525
|
+
if (part.type === "metadata") {
|
|
30526
|
+
return /* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: part.text }, `${lineIndex}-${partIndex}`);
|
|
30527
|
+
}
|
|
30528
|
+
return /* @__PURE__ */ jsx(Text, { color: "white", children: part.text }, `${lineIndex}-${partIndex}`);
|
|
30529
|
+
})
|
|
30530
|
+
] }, lineIndex)) });
|
|
30531
|
+
}
|
|
30532
|
+
function parseInlineMarkdown(content) {
|
|
30533
|
+
if (content.match(/^#+\s*$/)) {
|
|
30534
|
+
return [];
|
|
30535
|
+
}
|
|
30536
|
+
const headerMatch = content.match(/^(#+)\s+(.*)$/);
|
|
30537
|
+
if (headerMatch) {
|
|
30538
|
+
const [, hashes, headerText] = headerMatch;
|
|
30539
|
+
return [{ type: "header", text: headerText.trim(), level: hashes.length }];
|
|
30540
|
+
}
|
|
30541
|
+
const parts = [];
|
|
30542
|
+
let current = "";
|
|
30543
|
+
let i = 0;
|
|
30544
|
+
while (i < content.length) {
|
|
30545
|
+
if (content[i] === "`" && i < content.length - 1) {
|
|
30546
|
+
if (current) {
|
|
30547
|
+
parts.push({ type: "text", text: current });
|
|
30548
|
+
current = "";
|
|
30549
|
+
}
|
|
30550
|
+
const closeIndex = content.indexOf("`", i + 1);
|
|
30551
|
+
if (closeIndex !== -1 && closeIndex > i + 1) {
|
|
30552
|
+
const codeText = content.substring(i + 1, closeIndex);
|
|
30553
|
+
parts.push({ type: "code", text: codeText });
|
|
30554
|
+
i = closeIndex + 1;
|
|
30555
|
+
continue;
|
|
30556
|
+
}
|
|
30557
|
+
}
|
|
30558
|
+
if (content.substr(i, 2) === "**") {
|
|
30559
|
+
if (current) {
|
|
30560
|
+
parts.push({ type: "text", text: current });
|
|
30561
|
+
current = "";
|
|
30562
|
+
}
|
|
30563
|
+
const closeIndex = content.indexOf("**", i + 2);
|
|
30564
|
+
if (closeIndex !== -1) {
|
|
30565
|
+
const boldText = content.substring(i + 2, closeIndex);
|
|
30566
|
+
parts.push({ type: "bold", text: boldText });
|
|
30567
|
+
i = closeIndex + 2;
|
|
30568
|
+
continue;
|
|
30569
|
+
}
|
|
30570
|
+
}
|
|
30571
|
+
if (content[i] === "_" && content[i + 1] !== "_") {
|
|
30572
|
+
if (current) {
|
|
30573
|
+
parts.push({ type: "text", text: current });
|
|
30574
|
+
current = "";
|
|
30575
|
+
}
|
|
30576
|
+
const closeIndex = content.indexOf("_", i + 1);
|
|
30577
|
+
if (closeIndex !== -1) {
|
|
30578
|
+
const italicText = content.substring(i + 1, closeIndex);
|
|
30579
|
+
parts.push({ type: "italic", text: italicText });
|
|
30580
|
+
i = closeIndex + 1;
|
|
30581
|
+
continue;
|
|
30582
|
+
}
|
|
30583
|
+
}
|
|
30584
|
+
const char = content[i];
|
|
30585
|
+
if (/[\u{1F600}-\u{1F64F}]|[\u{1F300}-\u{1F5FF}]|[\u{1F680}-\u{1F6FF}]|[\u{1F1E0}-\u{1F1FF}]|[\u{2600}-\u{26FF}]|[\u{2700}-\u{27BF}]/u.test(char)) {
|
|
30586
|
+
if (current) {
|
|
30587
|
+
parts.push({ type: "text", text: current });
|
|
30588
|
+
current = "";
|
|
30589
|
+
}
|
|
30590
|
+
parts.push({ type: "emoji", text: char });
|
|
30591
|
+
i++;
|
|
30592
|
+
continue;
|
|
30593
|
+
}
|
|
30594
|
+
current += content[i];
|
|
30595
|
+
i++;
|
|
30596
|
+
}
|
|
30597
|
+
if (current) {
|
|
30598
|
+
const codePattern = /(view_file|str_replace_editor|create_file|search|semantic_search|ast_parser|package\.json|README\.md|GROK\.md|install\.sh|docs-getter\.sh|dist\/|src\/|scripts\/|apps\/|node_modules|\.git|\.js|\.ts|\.json|\.sh|\.md|bun\s+install|npm\s+install)/g;
|
|
30599
|
+
const metadataPattern = /(\([^)]*(?:v\d+\.\d+|\d+k?[+]?\s*(?:files?|lines?|items?)|\d+\.\d+[xX]|dependencies?|scripts?|guides?|overview|project\s+docs?|source\s+code|detailed\s+setup|changelog|debugging|session\s+files?|build\s+artifacts)[^)]*\))/g;
|
|
30600
|
+
let lastIndex = 0;
|
|
30601
|
+
let match;
|
|
30602
|
+
let processedText = current;
|
|
30603
|
+
const tempParts = [];
|
|
30604
|
+
lastIndex = 0;
|
|
30605
|
+
while ((match = codePattern.exec(processedText)) !== null) {
|
|
30606
|
+
if (match.index > lastIndex) {
|
|
30607
|
+
tempParts.push({ type: "text", text: processedText.substring(lastIndex, match.index) });
|
|
30608
|
+
}
|
|
30609
|
+
tempParts.push({ type: "code", text: match[0] });
|
|
30610
|
+
lastIndex = match.index + match[0].length;
|
|
30611
|
+
}
|
|
30612
|
+
if (lastIndex < processedText.length) {
|
|
30613
|
+
tempParts.push({ type: "text", text: processedText.substring(lastIndex) });
|
|
30614
|
+
}
|
|
30615
|
+
const finalParts = [];
|
|
30616
|
+
for (const part of tempParts) {
|
|
30617
|
+
if (part.type === "text") {
|
|
30618
|
+
lastIndex = 0;
|
|
30619
|
+
metadataPattern.lastIndex = 0;
|
|
30620
|
+
while ((match = metadataPattern.exec(part.text)) !== null) {
|
|
30621
|
+
if (match.index > lastIndex) {
|
|
30622
|
+
finalParts.push({ type: "text", text: part.text.substring(lastIndex, match.index) });
|
|
30623
|
+
}
|
|
30624
|
+
finalParts.push({ type: "metadata", text: match[0] });
|
|
30625
|
+
lastIndex = match.index + match[0].length;
|
|
30626
|
+
}
|
|
30627
|
+
if (lastIndex < part.text.length) {
|
|
30628
|
+
finalParts.push({ type: "text", text: part.text.substring(lastIndex) });
|
|
30629
|
+
}
|
|
30630
|
+
if (finalParts.length === 0 || finalParts[finalParts.length - 1].text !== part.text) {
|
|
30631
|
+
if (finalParts.length === 0) {
|
|
30632
|
+
finalParts.push(part);
|
|
30633
|
+
}
|
|
30634
|
+
}
|
|
30635
|
+
} else {
|
|
30636
|
+
finalParts.push(part);
|
|
30637
|
+
}
|
|
30638
|
+
}
|
|
30639
|
+
if (finalParts.length === 0) {
|
|
30640
|
+
parts.push({ type: "text", text: current });
|
|
30641
|
+
} else {
|
|
30642
|
+
parts.push(...finalParts);
|
|
30643
|
+
}
|
|
30644
|
+
}
|
|
30645
|
+
return parts;
|
|
30646
|
+
}
|
|
30647
|
+
var init_markdown_renderer = __esm({
|
|
30648
|
+
"src/ui/utils/markdown-renderer.tsx"() {
|
|
30649
|
+
}
|
|
30650
|
+
});
|
|
30451
30651
|
function AssistantMessageEntry({ entry, verbosityLevel: _verbosityLevel }) {
|
|
30452
30652
|
const { content: processedContent, isTruncated } = handleLongContent(entry.content);
|
|
30453
30653
|
return /* @__PURE__ */ jsx(Box, { flexDirection: "column", marginTop: 1, children: /* @__PURE__ */ jsxs(Box, { flexDirection: "row", alignItems: "flex-start", children: [
|
|
30454
30654
|
/* @__PURE__ */ jsx(Text, { color: inkColors.text, children: "\u23FA " }),
|
|
30455
30655
|
/* @__PURE__ */ jsxs(Box, { flexDirection: "column", width: "100%", children: [
|
|
30456
|
-
|
|
30457
|
-
// If there are tool calls, just show plain text
|
|
30458
|
-
/* @__PURE__ */ jsx(Text, { color: inkColors.text, wrap: "wrap", dimColor: false, children: processedContent.trim() })
|
|
30459
|
-
) : (
|
|
30460
|
-
// Use bright white text like Claude Code - explicit hex color to override any defaults
|
|
30461
|
-
/* @__PURE__ */ jsx(Text, { color: inkColors.text, wrap: "wrap", dimColor: false, children: processedContent.trim() })
|
|
30462
|
-
),
|
|
30656
|
+
/* @__PURE__ */ jsx(MarkdownRenderer, { content: processedContent.trim() }),
|
|
30463
30657
|
entry.isStreaming && /* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u2588" }),
|
|
30464
30658
|
isTruncated && /* @__PURE__ */ jsx(Text, { color: "yellow", italic: true, children: "[Response truncated for performance - full content in session log]" })
|
|
30465
30659
|
] })
|
|
@@ -30468,6 +30662,7 @@ function AssistantMessageEntry({ entry, verbosityLevel: _verbosityLevel }) {
|
|
|
30468
30662
|
var handleLongContent;
|
|
30469
30663
|
var init_assistant_message_entry = __esm({
|
|
30470
30664
|
"src/ui/components/chat-entries/assistant-message-entry.tsx"() {
|
|
30665
|
+
init_markdown_renderer();
|
|
30471
30666
|
init_colors();
|
|
30472
30667
|
handleLongContent = (content, maxLength = 5e3) => {
|
|
30473
30668
|
if (content.length <= maxLength) {
|
|
@@ -30719,7 +30914,223 @@ var init_file_content_renderer = __esm({
|
|
|
30719
30914
|
"src/ui/components/content-renderers/file-content-renderer.tsx"() {
|
|
30720
30915
|
}
|
|
30721
30916
|
});
|
|
30917
|
+
|
|
30918
|
+
// src/services/tool-brevity-service.ts
|
|
30919
|
+
var ToolBrevityService;
|
|
30920
|
+
var init_tool_brevity_service = __esm({
|
|
30921
|
+
"src/services/tool-brevity-service.ts"() {
|
|
30922
|
+
ToolBrevityService = class {
|
|
30923
|
+
/**
|
|
30924
|
+
* Format tool result based on brevity mode
|
|
30925
|
+
*/
|
|
30926
|
+
static formatToolResult(toolName, result, mode = "normal") {
|
|
30927
|
+
const normalizedToolName = this.normalizeToolName(toolName);
|
|
30928
|
+
const metadata = this.extractMetadata(normalizedToolName, result);
|
|
30929
|
+
const summary = this.generateSummary(normalizedToolName, result, metadata);
|
|
30930
|
+
return {
|
|
30931
|
+
toolName: normalizedToolName,
|
|
30932
|
+
summary,
|
|
30933
|
+
expansionHint: result.length > 0 ? "(ctrl+r to expand)" : "",
|
|
30934
|
+
hasContent: result.length > 0,
|
|
30935
|
+
originalContent: result,
|
|
30936
|
+
metadata
|
|
30937
|
+
};
|
|
30938
|
+
}
|
|
30939
|
+
/**
|
|
30940
|
+
* Normalize tool names to handle MCP and special cases
|
|
30941
|
+
*/
|
|
30942
|
+
static normalizeToolName(toolName) {
|
|
30943
|
+
if (toolName.startsWith("mcp__")) {
|
|
30944
|
+
const parts = toolName.split("__");
|
|
30945
|
+
if (parts.length >= 3) {
|
|
30946
|
+
return parts[2];
|
|
30947
|
+
}
|
|
30948
|
+
}
|
|
30949
|
+
const toolMappings = {
|
|
30950
|
+
"str_replace_editor": "Edit",
|
|
30951
|
+
"bash": "Bash",
|
|
30952
|
+
"file_editor": "Edit",
|
|
30953
|
+
"grep": "Grep",
|
|
30954
|
+
"file_search": "Search",
|
|
30955
|
+
"list_files": "List",
|
|
30956
|
+
"read_file": "Read",
|
|
30957
|
+
"write_file": "Write"
|
|
30958
|
+
};
|
|
30959
|
+
return toolMappings[toolName] || this.capitalizeFirst(toolName);
|
|
30960
|
+
}
|
|
30961
|
+
/**
|
|
30962
|
+
* Extract metadata from tool result content
|
|
30963
|
+
*/
|
|
30964
|
+
static extractMetadata(toolName, content) {
|
|
30965
|
+
const metadata = {};
|
|
30966
|
+
switch (toolName.toLowerCase()) {
|
|
30967
|
+
case "read":
|
|
30968
|
+
case "edit":
|
|
30969
|
+
case "write":
|
|
30970
|
+
metadata.lineCount = this.countLines(content);
|
|
30971
|
+
break;
|
|
30972
|
+
case "grep":
|
|
30973
|
+
case "search":
|
|
30974
|
+
const { matchCount, fileCount } = this.parseGrepResults(content);
|
|
30975
|
+
metadata.matchCount = matchCount;
|
|
30976
|
+
metadata.fileCount = fileCount;
|
|
30977
|
+
break;
|
|
30978
|
+
case "list":
|
|
30979
|
+
metadata.fileCount = this.countFileItems(content);
|
|
30980
|
+
break;
|
|
30981
|
+
case "bash":
|
|
30982
|
+
metadata.status = this.determineBashStatus(content);
|
|
30983
|
+
break;
|
|
30984
|
+
default:
|
|
30985
|
+
metadata.lineCount = this.countLines(content);
|
|
30986
|
+
}
|
|
30987
|
+
return metadata;
|
|
30988
|
+
}
|
|
30989
|
+
/**
|
|
30990
|
+
* Generate tool-specific summary text
|
|
30991
|
+
*/
|
|
30992
|
+
static generateSummary(toolName, content, metadata) {
|
|
30993
|
+
const tool = toolName.toLowerCase();
|
|
30994
|
+
if (!content || content.trim().length === 0) {
|
|
30995
|
+
return `${this.capitalizeFirst(tool)} (no output)`;
|
|
30996
|
+
}
|
|
30997
|
+
switch (tool) {
|
|
30998
|
+
case "read":
|
|
30999
|
+
return `Read ${metadata.lineCount || 0} lines`;
|
|
31000
|
+
case "edit":
|
|
31001
|
+
return `Updated ${this.getFileName(content)} with ${metadata.lineCount || 0} lines`;
|
|
31002
|
+
case "write":
|
|
31003
|
+
return `Created file (${metadata.lineCount || 0} lines)`;
|
|
31004
|
+
case "grep":
|
|
31005
|
+
case "search":
|
|
31006
|
+
if (metadata.matchCount === 0) {
|
|
31007
|
+
return "No matches found";
|
|
31008
|
+
}
|
|
31009
|
+
return `${metadata.matchCount} matches across ${metadata.fileCount || 1} files`;
|
|
31010
|
+
case "list":
|
|
31011
|
+
return `Found ${metadata.fileCount || 0} items`;
|
|
31012
|
+
case "bash":
|
|
31013
|
+
if (metadata.status === "error") {
|
|
31014
|
+
return "Command failed";
|
|
31015
|
+
}
|
|
31016
|
+
return "Command completed successfully";
|
|
31017
|
+
case "glob":
|
|
31018
|
+
return `Found ${this.countFileItems(content)} files`;
|
|
31019
|
+
case "webfetch":
|
|
31020
|
+
return `Fetched content (${metadata.lineCount || 0} lines)`;
|
|
31021
|
+
case "websearch":
|
|
31022
|
+
return `Search completed (${this.countSearchResults(content)} results)`;
|
|
31023
|
+
default:
|
|
31024
|
+
const lines = metadata.lineCount || 0;
|
|
31025
|
+
return lines > 0 ? `${this.capitalizeFirst(tool)} (${lines} lines)` : this.capitalizeFirst(tool);
|
|
31026
|
+
}
|
|
31027
|
+
}
|
|
31028
|
+
/**
|
|
31029
|
+
* Count lines in content
|
|
31030
|
+
*/
|
|
31031
|
+
static countLines(content) {
|
|
31032
|
+
if (!content) return 0;
|
|
31033
|
+
return content.split("\n").length;
|
|
31034
|
+
}
|
|
31035
|
+
/**
|
|
31036
|
+
* Parse grep/search results for match and file counts
|
|
31037
|
+
*/
|
|
31038
|
+
static parseGrepResults(content) {
|
|
31039
|
+
if (!content) return { matchCount: 0, fileCount: 0 };
|
|
31040
|
+
const lines = content.split("\n").filter((line) => line.trim().length > 0);
|
|
31041
|
+
const files = /* @__PURE__ */ new Set();
|
|
31042
|
+
let matches = 0;
|
|
31043
|
+
for (const line of lines) {
|
|
31044
|
+
const fileMatch = line.match(/^([^:]+):/);
|
|
31045
|
+
if (fileMatch) {
|
|
31046
|
+
files.add(fileMatch[1]);
|
|
31047
|
+
matches++;
|
|
31048
|
+
} else if (line.includes(":")) {
|
|
31049
|
+
matches++;
|
|
31050
|
+
}
|
|
31051
|
+
}
|
|
31052
|
+
return {
|
|
31053
|
+
matchCount: matches || lines.length,
|
|
31054
|
+
fileCount: files.size || (matches > 0 ? 1 : 0)
|
|
31055
|
+
};
|
|
31056
|
+
}
|
|
31057
|
+
/**
|
|
31058
|
+
* Count file items in directory listing
|
|
31059
|
+
*/
|
|
31060
|
+
static countFileItems(content) {
|
|
31061
|
+
if (!content) return 0;
|
|
31062
|
+
const lines = content.split("\n").filter((line) => line.trim().length > 0).filter((line) => !line.startsWith("total ")).filter((line) => !line.match(/^d.*\s+\.\s*$/)).filter((line) => !line.match(/^d.*\s+\.\.\s*$/));
|
|
31063
|
+
return lines.length;
|
|
31064
|
+
}
|
|
31065
|
+
/**
|
|
31066
|
+
* Determine bash command success/failure status
|
|
31067
|
+
*/
|
|
31068
|
+
static determineBashStatus(content) {
|
|
31069
|
+
if (!content) return "success";
|
|
31070
|
+
const errorIndicators = [
|
|
31071
|
+
"error:",
|
|
31072
|
+
"Error:",
|
|
31073
|
+
"ERROR:",
|
|
31074
|
+
"failed",
|
|
31075
|
+
"Failed",
|
|
31076
|
+
"FAILED",
|
|
31077
|
+
"permission denied",
|
|
31078
|
+
"command not found",
|
|
31079
|
+
"no such file",
|
|
31080
|
+
"cannot"
|
|
31081
|
+
];
|
|
31082
|
+
const contentLower = content.toLowerCase();
|
|
31083
|
+
return errorIndicators.some((indicator) => contentLower.includes(indicator.toLowerCase())) ? "error" : "success";
|
|
31084
|
+
}
|
|
31085
|
+
/**
|
|
31086
|
+
* Extract filename from edit/write operation content
|
|
31087
|
+
*/
|
|
31088
|
+
static getFileName(content) {
|
|
31089
|
+
const fileMatch = content.match(/(?:updated|edited|created)\s+([^\s]+)/i);
|
|
31090
|
+
if (fileMatch) return fileMatch[1];
|
|
31091
|
+
const pathMatch = content.match(/([^/]+)$/);
|
|
31092
|
+
return pathMatch ? pathMatch[1] : "file";
|
|
31093
|
+
}
|
|
31094
|
+
/**
|
|
31095
|
+
* Count search results in web search content
|
|
31096
|
+
*/
|
|
31097
|
+
static countSearchResults(content) {
|
|
31098
|
+
const resultMatches = content.match(/result\s+\d+/gi);
|
|
31099
|
+
return resultMatches ? resultMatches.length : 1;
|
|
31100
|
+
}
|
|
31101
|
+
/**
|
|
31102
|
+
* Capitalize first letter of string
|
|
31103
|
+
*/
|
|
31104
|
+
static capitalizeFirst(str) {
|
|
31105
|
+
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
|
|
31106
|
+
}
|
|
31107
|
+
/**
|
|
31108
|
+
* Check if content should use compact display
|
|
31109
|
+
*/
|
|
31110
|
+
static shouldUseCompactDisplay(mode, contentLength) {
|
|
31111
|
+
if (mode === "brief") return true;
|
|
31112
|
+
if (mode === "verbose") return false;
|
|
31113
|
+
const lineCount = contentLength > 0 ? contentLength.toString().split("\n").length : 0;
|
|
31114
|
+
return lineCount > 5;
|
|
31115
|
+
}
|
|
31116
|
+
/**
|
|
31117
|
+
* Format expansion hint with content preview
|
|
31118
|
+
*/
|
|
31119
|
+
static formatExpansionHint(hasContent, metadata) {
|
|
31120
|
+
if (!hasContent) return "";
|
|
31121
|
+
if (metadata.lineCount && metadata.lineCount > 10) {
|
|
31122
|
+
return `(${metadata.lineCount} lines, ctrl+r to expand)`;
|
|
31123
|
+
}
|
|
31124
|
+
if (metadata.matchCount && metadata.matchCount > 5) {
|
|
31125
|
+
return `(${metadata.matchCount} matches, ctrl+r to expand)`;
|
|
31126
|
+
}
|
|
31127
|
+
return "(ctrl+r to expand)";
|
|
31128
|
+
}
|
|
31129
|
+
};
|
|
31130
|
+
}
|
|
31131
|
+
});
|
|
30722
31132
|
function ToolCallEntry({ entry, verbosityLevel, explainLevel }) {
|
|
31133
|
+
const [isExpanded, setIsExpanded] = useState(false);
|
|
30723
31134
|
const getExplanation = (toolName2, filePath2, _isExecuting) => {
|
|
30724
31135
|
if (explainLevel === "off") return null;
|
|
30725
31136
|
const explanations = {
|
|
@@ -30748,6 +31159,19 @@ function ToolCallEntry({ entry, verbosityLevel, explainLevel }) {
|
|
|
30748
31159
|
if (!explanation2) return null;
|
|
30749
31160
|
return explainLevel === "detailed" ? explanation2.detailed : explanation2.brief;
|
|
30750
31161
|
};
|
|
31162
|
+
const truncateToClaudeStyle = (content) => {
|
|
31163
|
+
const lines = content.split("\n");
|
|
31164
|
+
const maxLines = 3;
|
|
31165
|
+
if (lines.length <= maxLines) {
|
|
31166
|
+
return { preview: content, hasMore: false, totalLines: lines.length };
|
|
31167
|
+
}
|
|
31168
|
+
const preview2 = lines.slice(0, maxLines).join("\n");
|
|
31169
|
+
return {
|
|
31170
|
+
preview: preview2,
|
|
31171
|
+
hasMore: true,
|
|
31172
|
+
totalLines: lines.length
|
|
31173
|
+
};
|
|
31174
|
+
};
|
|
30751
31175
|
const getToolActionName = (toolName2) => {
|
|
30752
31176
|
if (toolName2.startsWith("mcp__")) {
|
|
30753
31177
|
const parts = toolName2.split("__");
|
|
@@ -30814,7 +31238,15 @@ function ToolCallEntry({ entry, verbosityLevel, explainLevel }) {
|
|
|
30814
31238
|
const shouldShowFileContent = (entry.toolCall?.function?.name === "view_file" || entry.toolCall?.function?.name === "create_file") && entry.toolResult?.success && !shouldShowDiff;
|
|
30815
31239
|
const shouldShowToolContent = verbosityLevel !== "quiet";
|
|
30816
31240
|
const shouldShowFullContent = verbosityLevel === "normal" || verbosityLevel === "verbose";
|
|
31241
|
+
const brevityMode = verbosityLevel === "quiet" ? "brief" : verbosityLevel === "verbose" ? "verbose" : "normal";
|
|
31242
|
+
const brevitySummary = ToolBrevityService.formatToolResult(
|
|
31243
|
+
toolName,
|
|
31244
|
+
entry.content || "",
|
|
31245
|
+
brevityMode
|
|
31246
|
+
);
|
|
30817
31247
|
const explanation = getExplanation(toolName, filePath);
|
|
31248
|
+
const { preview, hasMore, totalLines } = truncateToClaudeStyle(entry.content || "");
|
|
31249
|
+
const useClaudeCodeFormat = verbosityLevel === "quiet" && brevitySummary.hasContent;
|
|
30818
31250
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginTop: 1, children: [
|
|
30819
31251
|
/* @__PURE__ */ jsxs(Box, { children: [
|
|
30820
31252
|
/* @__PURE__ */ jsx(Text, { color: "magenta", children: "\u23FA" }),
|
|
@@ -30823,24 +31255,55 @@ function ToolCallEntry({ entry, verbosityLevel, explainLevel }) {
|
|
|
30823
31255
|
filePath ? `${actionName}(${filePath})` : actionName
|
|
30824
31256
|
] })
|
|
30825
31257
|
] }),
|
|
30826
|
-
explanation && /* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsxs(Text, { color: "blue", italic: true, children: [
|
|
31258
|
+
explanation && !useClaudeCodeFormat && /* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsxs(Text, { color: "blue", italic: true, children: [
|
|
30827
31259
|
"\u{1F4A1} ",
|
|
30828
31260
|
explanation
|
|
30829
31261
|
] }) }),
|
|
30830
|
-
|
|
31262
|
+
useClaudeCodeFormat ? (
|
|
31263
|
+
// Claude Code style: ultra-brief format
|
|
31264
|
+
/* @__PURE__ */ jsx(Box, { marginLeft: 2, children: /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
31265
|
+
"\u23BF ",
|
|
31266
|
+
brevitySummary.summary,
|
|
31267
|
+
" ",
|
|
31268
|
+
brevitySummary.expansionHint
|
|
31269
|
+
] }) })
|
|
31270
|
+
) : shouldShowToolContent && /* @__PURE__ */ jsx(Box, { marginLeft: 2, flexDirection: "column", children: isExecuting ? /* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u23BF Executing..." }) : shouldShowFileContent && shouldShowFullContent ? /* @__PURE__ */ jsx(Box, { flexDirection: "column", children: !isExpanded ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
31271
|
+
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
31272
|
+
"\u23BF ",
|
|
31273
|
+
preview
|
|
31274
|
+
] }),
|
|
31275
|
+
hasMore && /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
31276
|
+
"\u2026 +",
|
|
31277
|
+
totalLines - 3,
|
|
31278
|
+
" lines (ctrl+r to expand)"
|
|
31279
|
+
] })
|
|
31280
|
+
] }) : /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
30831
31281
|
/* @__PURE__ */ jsx(Text, { color: "gray", children: "\u23BF File contents:" }),
|
|
30832
31282
|
/* @__PURE__ */ jsx(Box, { marginLeft: 2, flexDirection: "column", children: /* @__PURE__ */ jsx(FileContentRenderer, { content: entry.content }) })
|
|
30833
|
-
] }) : shouldShowDiff && shouldShowFullContent ? (
|
|
31283
|
+
] }) }) : shouldShowDiff && shouldShowFullContent ? (
|
|
30834
31284
|
// For diff results, show only the summary line, not the raw content
|
|
30835
31285
|
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
30836
31286
|
"\u23BF ",
|
|
30837
31287
|
entry.content.split("\n")[0]
|
|
30838
31288
|
] })
|
|
30839
|
-
) : !shouldShowFullContent ? /* @__PURE__ */ jsx(Text, { color: "gray", children: "\u23BF Completed" }) : /* @__PURE__ */ jsxs(
|
|
31289
|
+
) : !shouldShowFullContent ? /* @__PURE__ */ jsx(Text, { color: "gray", children: "\u23BF Completed" }) : !isExpanded && hasMore ? /* @__PURE__ */ jsxs(Box, { flexDirection: "column", children: [
|
|
31290
|
+
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
31291
|
+
"\u23BF ",
|
|
31292
|
+
preview
|
|
31293
|
+
] }),
|
|
31294
|
+
/* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
31295
|
+
"\u2026 +",
|
|
31296
|
+
totalLines - 3,
|
|
31297
|
+
" lines (ctrl+r to expand)"
|
|
31298
|
+
] })
|
|
31299
|
+
] }) : !isExpanded ? /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
31300
|
+
"\u23BF ",
|
|
31301
|
+
preview
|
|
31302
|
+
] }) : /* @__PURE__ */ jsxs(Text, { color: "gray", children: [
|
|
30840
31303
|
"\u23BF ",
|
|
30841
31304
|
formatToolContent(entry.content, toolName)
|
|
30842
31305
|
] }) }),
|
|
30843
|
-
shouldShowDiff && !isExecuting && shouldShowFullContent && /* @__PURE__ */ jsx(Box, { marginLeft: 4, flexDirection: "column", children: /* @__PURE__ */ jsx(
|
|
31306
|
+
shouldShowDiff && !isExecuting && shouldShowFullContent && !useClaudeCodeFormat && /* @__PURE__ */ jsx(Box, { marginLeft: 4, flexDirection: "column", children: /* @__PURE__ */ jsx(
|
|
30844
31307
|
DiffRenderer,
|
|
30845
31308
|
{
|
|
30846
31309
|
diffContent: entry.content,
|
|
@@ -30855,6 +31318,7 @@ var init_tool_call_entry = __esm({
|
|
|
30855
31318
|
"src/ui/components/chat-entries/tool-call-entry.tsx"() {
|
|
30856
31319
|
init_diff_renderer();
|
|
30857
31320
|
init_file_content_renderer();
|
|
31321
|
+
init_tool_brevity_service();
|
|
30858
31322
|
truncateContent2 = (content, maxLength = 100) => {
|
|
30859
31323
|
if (process.env.COMPACT !== "1") return content;
|
|
30860
31324
|
return content.length > maxLength ? content.substring(0, maxLength) + "..." : content;
|
|
@@ -31154,31 +31618,64 @@ function ChatInput({
|
|
|
31154
31618
|
isProcessing,
|
|
31155
31619
|
isStreaming
|
|
31156
31620
|
}) {
|
|
31157
|
-
|
|
31158
|
-
|
|
31159
|
-
|
|
31160
|
-
|
|
31161
|
-
|
|
31162
|
-
|
|
31163
|
-
|
|
31164
|
-
|
|
31165
|
-
|
|
31166
|
-
let currentCharIndex = 0;
|
|
31167
|
-
let totalChars = 0;
|
|
31168
|
-
for (let i = 0; i < lines.length; i++) {
|
|
31169
|
-
if (totalChars + lines[i].length >= cursorPosition) {
|
|
31170
|
-
currentLineIndex = i;
|
|
31171
|
-
currentCharIndex = cursorPosition - totalChars;
|
|
31172
|
-
break;
|
|
31621
|
+
try {
|
|
31622
|
+
let displayInput = input;
|
|
31623
|
+
const beforeCursor = displayInput.slice(0, Math.min(cursorPosition, displayInput.length));
|
|
31624
|
+
const lines = displayInput.split(/\r\n|\r|\n/);
|
|
31625
|
+
const isMultiline = lines.length > 1;
|
|
31626
|
+
const MAX_DISPLAY_LINES = 10;
|
|
31627
|
+
const shouldTruncateDisplay = lines.length > MAX_DISPLAY_LINES;
|
|
31628
|
+
if (shouldTruncateDisplay) {
|
|
31629
|
+
console.log(`\u{1F4C4} Large content: ${lines.length} lines, showing truncated view`);
|
|
31173
31630
|
}
|
|
31174
|
-
|
|
31175
|
-
|
|
31176
|
-
|
|
31177
|
-
|
|
31178
|
-
|
|
31179
|
-
|
|
31180
|
-
|
|
31181
|
-
|
|
31631
|
+
let currentLineIndex = 0;
|
|
31632
|
+
let currentCharIndex = 0;
|
|
31633
|
+
let totalChars = 0;
|
|
31634
|
+
for (let i = 0; i < lines.length; i++) {
|
|
31635
|
+
if (totalChars + lines[i].length >= cursorPosition) {
|
|
31636
|
+
currentLineIndex = i;
|
|
31637
|
+
currentCharIndex = cursorPosition - totalChars;
|
|
31638
|
+
break;
|
|
31639
|
+
}
|
|
31640
|
+
totalChars += lines[i].length + 1;
|
|
31641
|
+
}
|
|
31642
|
+
const showCursor = !isProcessing && !isStreaming;
|
|
31643
|
+
const borderColor = isProcessing || isStreaming ? "yellow" : "blue";
|
|
31644
|
+
const promptColor = "cyan";
|
|
31645
|
+
const placeholderText = "Ask me anything...";
|
|
31646
|
+
const isPlaceholder = !input;
|
|
31647
|
+
if (isMultiline) {
|
|
31648
|
+
return /* @__PURE__ */ jsx(
|
|
31649
|
+
Box,
|
|
31650
|
+
{
|
|
31651
|
+
borderStyle: "round",
|
|
31652
|
+
borderColor,
|
|
31653
|
+
paddingX: 1,
|
|
31654
|
+
paddingY: 0,
|
|
31655
|
+
marginTop: 1,
|
|
31656
|
+
flexDirection: "column",
|
|
31657
|
+
children: /* @__PURE__ */ jsx(Text, { children: shouldTruncateDisplay ? (
|
|
31658
|
+
// Show Claude Code style paste summary but don't replace input
|
|
31659
|
+
`\u276F [Pasted text #${globalThis.grokPasteCounter || 1} +${lines.length} lines]`
|
|
31660
|
+
) : (
|
|
31661
|
+
// Normal multiline display for reasonable sizes
|
|
31662
|
+
lines.map((line, index) => {
|
|
31663
|
+
const isCurrentLine = index === currentLineIndex;
|
|
31664
|
+
const promptChar = index === 0 ? "\u276F " : " ";
|
|
31665
|
+
let lineText = promptChar + line;
|
|
31666
|
+
if (isCurrentLine && showCursor) {
|
|
31667
|
+
const cursorPos = promptChar.length + currentCharIndex;
|
|
31668
|
+
lineText = lineText.slice(0, cursorPos) + "\u2588" + lineText.slice(cursorPos + 1);
|
|
31669
|
+
}
|
|
31670
|
+
return index === lines.length - 1 ? lineText : lineText + "\n";
|
|
31671
|
+
}).join("")
|
|
31672
|
+
) })
|
|
31673
|
+
}
|
|
31674
|
+
);
|
|
31675
|
+
}
|
|
31676
|
+
const adjustedCursorPos = Math.min(cursorPosition, displayInput.length);
|
|
31677
|
+
const cursorChar = displayInput.slice(adjustedCursorPos, adjustedCursorPos + 1) || " ";
|
|
31678
|
+
const afterCursorText = displayInput.slice(adjustedCursorPos + 1);
|
|
31182
31679
|
return /* @__PURE__ */ jsx(
|
|
31183
31680
|
Box,
|
|
31184
31681
|
{
|
|
@@ -31187,57 +31684,36 @@ function ChatInput({
|
|
|
31187
31684
|
paddingX: 1,
|
|
31188
31685
|
paddingY: 0,
|
|
31189
31686
|
marginTop: 1,
|
|
31190
|
-
|
|
31191
|
-
|
|
31192
|
-
|
|
31193
|
-
|
|
31194
|
-
|
|
31195
|
-
|
|
31196
|
-
|
|
31197
|
-
|
|
31198
|
-
|
|
31199
|
-
|
|
31200
|
-
|
|
31201
|
-
)
|
|
31202
|
-
|
|
31203
|
-
|
|
31204
|
-
|
|
31205
|
-
|
|
31206
|
-
|
|
31207
|
-
|
|
31208
|
-
|
|
31209
|
-
|
|
31210
|
-
|
|
31211
|
-
|
|
31212
|
-
|
|
31213
|
-
|
|
31687
|
+
children: /* @__PURE__ */ jsxs(Box, { children: [
|
|
31688
|
+
/* @__PURE__ */ jsx(Text, { color: promptColor, children: "\u276F " }),
|
|
31689
|
+
isPlaceholder ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31690
|
+
/* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: placeholderText }),
|
|
31691
|
+
showCursor && /* @__PURE__ */ jsx(Text, { backgroundColor: "white", color: "black", children: " " })
|
|
31692
|
+
] }) : /* @__PURE__ */ jsxs(Text, { children: [
|
|
31693
|
+
beforeCursor,
|
|
31694
|
+
showCursor && /* @__PURE__ */ jsx(Text, { backgroundColor: "white", color: "black", children: cursorChar }),
|
|
31695
|
+
!showCursor && cursorChar !== " " && cursorChar,
|
|
31696
|
+
afterCursorText
|
|
31697
|
+
] })
|
|
31698
|
+
] })
|
|
31699
|
+
}
|
|
31700
|
+
);
|
|
31701
|
+
} catch (error) {
|
|
31702
|
+
console.error("[ERROR] ChatInput component crashed:", error);
|
|
31703
|
+
console.error("[ERROR] Stack:", error instanceof Error ? error.stack : "No stack");
|
|
31704
|
+
console.error("[ERROR] Input data:", { input: input?.slice(0, 100), cursorPosition, isProcessing, isStreaming });
|
|
31705
|
+
return /* @__PURE__ */ jsx(
|
|
31706
|
+
Box,
|
|
31707
|
+
{
|
|
31708
|
+
borderStyle: "round",
|
|
31709
|
+
borderColor: "red",
|
|
31710
|
+
paddingX: 1,
|
|
31711
|
+
paddingY: 0,
|
|
31712
|
+
marginTop: 1,
|
|
31713
|
+
children: /* @__PURE__ */ jsx(Text, { color: "red", children: "\u276F [Input error - check console]" })
|
|
31214
31714
|
}
|
|
31215
31715
|
);
|
|
31216
31716
|
}
|
|
31217
|
-
const cursorChar = input.slice(cursorPosition, cursorPosition + 1) || " ";
|
|
31218
|
-
const afterCursorText = input.slice(cursorPosition + 1);
|
|
31219
|
-
return /* @__PURE__ */ jsx(
|
|
31220
|
-
Box,
|
|
31221
|
-
{
|
|
31222
|
-
borderStyle: "round",
|
|
31223
|
-
borderColor,
|
|
31224
|
-
paddingX: 1,
|
|
31225
|
-
paddingY: 0,
|
|
31226
|
-
marginTop: 1,
|
|
31227
|
-
children: /* @__PURE__ */ jsxs(Box, { children: [
|
|
31228
|
-
/* @__PURE__ */ jsx(Text, { color: promptColor, children: "\u276F " }),
|
|
31229
|
-
isPlaceholder ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31230
|
-
/* @__PURE__ */ jsx(Text, { color: "gray", dimColor: true, children: placeholderText }),
|
|
31231
|
-
showCursor && /* @__PURE__ */ jsx(Text, { backgroundColor: "white", color: "black", children: " " })
|
|
31232
|
-
] }) : /* @__PURE__ */ jsxs(Text, { children: [
|
|
31233
|
-
beforeCursor,
|
|
31234
|
-
showCursor && /* @__PURE__ */ jsx(Text, { backgroundColor: "white", color: "black", children: cursorChar }),
|
|
31235
|
-
!showCursor && cursorChar !== " " && cursorChar,
|
|
31236
|
-
afterCursorText
|
|
31237
|
-
] })
|
|
31238
|
-
] })
|
|
31239
|
-
}
|
|
31240
|
-
);
|
|
31241
31717
|
}
|
|
31242
31718
|
var init_chat_input = __esm({
|
|
31243
31719
|
"src/ui/components/chat-input.tsx"() {
|
|
@@ -31864,6 +32340,85 @@ var init_chat_interface_renderer = __esm({
|
|
|
31864
32340
|
init_confirmation_dialog();
|
|
31865
32341
|
}
|
|
31866
32342
|
});
|
|
32343
|
+
function getSessionLogger() {
|
|
32344
|
+
if (!sessionLogger) {
|
|
32345
|
+
sessionLogger = new SessionLogger();
|
|
32346
|
+
}
|
|
32347
|
+
return sessionLogger;
|
|
32348
|
+
}
|
|
32349
|
+
function logTerminalState(state) {
|
|
32350
|
+
getSessionLogger().logTerminalState(state);
|
|
32351
|
+
}
|
|
32352
|
+
var SessionLogger, sessionLogger;
|
|
32353
|
+
var init_session_logger = __esm({
|
|
32354
|
+
"src/utils/session-logger.ts"() {
|
|
32355
|
+
SessionLogger = class {
|
|
32356
|
+
constructor() {
|
|
32357
|
+
this.sessionId = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
32358
|
+
this.logPath = path8__default.join(process.cwd(), `session-${this.sessionId}.log`);
|
|
32359
|
+
this.init();
|
|
32360
|
+
}
|
|
32361
|
+
init() {
|
|
32362
|
+
const header = `
|
|
32363
|
+
=================================================================
|
|
32364
|
+
\u{1F9EA} GROK ONE-SHOT TESTING SESSION
|
|
32365
|
+
Session ID: ${this.sessionId}
|
|
32366
|
+
Started: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
32367
|
+
=================================================================
|
|
32368
|
+
|
|
32369
|
+
`;
|
|
32370
|
+
fs7__default.writeFileSync(this.logPath, header);
|
|
32371
|
+
}
|
|
32372
|
+
logTerminalState(state) {
|
|
32373
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
32374
|
+
const entry = `
|
|
32375
|
+
[${timestamp}] \u{1F4FA} TERMINAL STATE - ${state.action}
|
|
32376
|
+
=====================================
|
|
32377
|
+
INPUT FIELD: "${state.input}"
|
|
32378
|
+
CURSOR POS: ${state.cursorPosition}
|
|
32379
|
+
PROCESSING: ${state.isProcessing}
|
|
32380
|
+
STREAMING: ${state.isStreaming}
|
|
32381
|
+
CHAT ENTRIES: ${state.chatHistory.length}
|
|
32382
|
+
LAST ENTRY: ${state.chatHistory.length > 0 ? JSON.stringify(state.chatHistory[state.chatHistory.length - 1], null, 2) : "None"}
|
|
32383
|
+
=====================================
|
|
32384
|
+
|
|
32385
|
+
`;
|
|
32386
|
+
fs7__default.appendFileSync(this.logPath, entry);
|
|
32387
|
+
}
|
|
32388
|
+
logUserAction(action, details = {}) {
|
|
32389
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
32390
|
+
const entry = `[${timestamp}] \u{1F464} USER ACTION: ${action}
|
|
32391
|
+
Details: ${JSON.stringify(details, null, 2)}
|
|
32392
|
+
|
|
32393
|
+
`;
|
|
32394
|
+
fs7__default.appendFileSync(this.logPath, entry);
|
|
32395
|
+
}
|
|
32396
|
+
logPasteEvent(event) {
|
|
32397
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
32398
|
+
const entry = `[${timestamp}] \u{1F4CB} PASTE EVENT: ${event.phase}
|
|
32399
|
+
Data: ${JSON.stringify(event.data, null, 2)}
|
|
32400
|
+
|
|
32401
|
+
`;
|
|
32402
|
+
fs7__default.appendFileSync(this.logPath, entry);
|
|
32403
|
+
}
|
|
32404
|
+
logTestResult(testName, result, details) {
|
|
32405
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
32406
|
+
const entry = `
|
|
32407
|
+
[${timestamp}] \u2705 TEST RESULT: ${testName}
|
|
32408
|
+
Result: ${result}
|
|
32409
|
+
Details: ${details}
|
|
32410
|
+
=================================================================
|
|
32411
|
+
|
|
32412
|
+
`;
|
|
32413
|
+
fs7__default.appendFileSync(this.logPath, entry);
|
|
32414
|
+
}
|
|
32415
|
+
getLogPath() {
|
|
32416
|
+
return this.logPath;
|
|
32417
|
+
}
|
|
32418
|
+
};
|
|
32419
|
+
sessionLogger = null;
|
|
32420
|
+
}
|
|
32421
|
+
});
|
|
31867
32422
|
|
|
31868
32423
|
// src/ui/components/chat-interface.tsx
|
|
31869
32424
|
var chat_interface_exports = {};
|
|
@@ -31928,6 +32483,16 @@ function ChatInterfaceWithAgent({
|
|
|
31928
32483
|
explainLevel,
|
|
31929
32484
|
planMode
|
|
31930
32485
|
} = useInputHandler(inputHandlerProps);
|
|
32486
|
+
useEffect(() => {
|
|
32487
|
+
logTerminalState({
|
|
32488
|
+
input,
|
|
32489
|
+
cursorPosition,
|
|
32490
|
+
chatHistory,
|
|
32491
|
+
isProcessing,
|
|
32492
|
+
isStreaming,
|
|
32493
|
+
action: "STATE_CHANGE"
|
|
32494
|
+
});
|
|
32495
|
+
}, [input, cursorPosition, chatHistory.length, isProcessing, isStreaming]);
|
|
31931
32496
|
useStreaming(agent, initialMessage, setChatHistory, {
|
|
31932
32497
|
setIsProcessing,
|
|
31933
32498
|
setIsStreaming,
|
|
@@ -32014,6 +32579,29 @@ var init_chat_interface = __esm({
|
|
|
32014
32579
|
init_use_session_logging();
|
|
32015
32580
|
init_use_processing_timer();
|
|
32016
32581
|
init_chat_interface_renderer();
|
|
32582
|
+
init_session_logger();
|
|
32583
|
+
}
|
|
32584
|
+
});
|
|
32585
|
+
|
|
32586
|
+
// src/utils/console-markdown.ts
|
|
32587
|
+
var console_markdown_exports = {};
|
|
32588
|
+
__export(console_markdown_exports, {
|
|
32589
|
+
renderMarkdownToConsole: () => renderMarkdownToConsole
|
|
32590
|
+
});
|
|
32591
|
+
function renderMarkdownToConsole(content) {
|
|
32592
|
+
let result = content;
|
|
32593
|
+
result = result.replace(/^#+\s+(.*)$/gm, (_, text) => chalk2.bold.white(text));
|
|
32594
|
+
result = result.replace(/\*\*(.*?)\*\*/g, (_, text) => chalk2.bold.white(text));
|
|
32595
|
+
result = result.replace(/_(.*?)_/g, (_, text) => chalk2.italic.gray(text));
|
|
32596
|
+
result = result.replace(/`([^`]+)`/g, (_, text) => chalk2.cyan(text));
|
|
32597
|
+
result = result.replace(/(✅|✓)/g, (match) => chalk2.green(match));
|
|
32598
|
+
result = result.replace(/(❌|✗)/g, (match) => chalk2.red(match));
|
|
32599
|
+
result = result.replace(/(⚠️|⚠)/g, (match) => chalk2.yellow(match));
|
|
32600
|
+
result = result.replace(/(ℹ️|💡|🔍)/g, (match) => chalk2.blue(match));
|
|
32601
|
+
return result;
|
|
32602
|
+
}
|
|
32603
|
+
var init_console_markdown = __esm({
|
|
32604
|
+
"src/utils/console-markdown.ts"() {
|
|
32017
32605
|
}
|
|
32018
32606
|
});
|
|
32019
32607
|
|
|
@@ -32030,27 +32618,27 @@ function createMCPCommand() {
|
|
|
32030
32618
|
if (PREDEFINED_SERVERS[name]) {
|
|
32031
32619
|
const config3 = PREDEFINED_SERVERS[name];
|
|
32032
32620
|
addMCPServer(config3);
|
|
32033
|
-
console.log(
|
|
32621
|
+
console.log(chalk2.green(`\u2713 Added predefined MCP server: ${name}`));
|
|
32034
32622
|
const manager2 = getMCPManager();
|
|
32035
32623
|
await manager2.addServer(config3);
|
|
32036
|
-
console.log(
|
|
32624
|
+
console.log(chalk2.green(`\u2713 Connected to MCP server: ${name}`));
|
|
32037
32625
|
const tools2 = manager2.getTools().filter((t) => t.serverName === name);
|
|
32038
|
-
console.log(
|
|
32626
|
+
console.log(chalk2.blue(` Available tools: ${tools2.length}`));
|
|
32039
32627
|
return;
|
|
32040
32628
|
}
|
|
32041
32629
|
const transportType = options.transport.toLowerCase();
|
|
32042
32630
|
if (transportType === "stdio") {
|
|
32043
32631
|
if (!options.command) {
|
|
32044
|
-
console.error(
|
|
32632
|
+
console.error(chalk2.red("Error: --command is required for stdio transport"));
|
|
32045
32633
|
process.exit(1);
|
|
32046
32634
|
}
|
|
32047
32635
|
} else if (transportType === "http" || transportType === "sse" || transportType === "streamable_http") {
|
|
32048
32636
|
if (!options.url) {
|
|
32049
|
-
console.error(
|
|
32637
|
+
console.error(chalk2.red(`Error: --url is required for ${transportType} transport`));
|
|
32050
32638
|
process.exit(1);
|
|
32051
32639
|
}
|
|
32052
32640
|
} else {
|
|
32053
|
-
console.error(
|
|
32641
|
+
console.error(chalk2.red("Error: Transport type must be stdio, http, sse, or streamable_http"));
|
|
32054
32642
|
process.exit(1);
|
|
32055
32643
|
}
|
|
32056
32644
|
const env = {};
|
|
@@ -32079,14 +32667,14 @@ function createMCPCommand() {
|
|
|
32079
32667
|
}
|
|
32080
32668
|
};
|
|
32081
32669
|
addMCPServer(config2);
|
|
32082
|
-
console.log(
|
|
32670
|
+
console.log(chalk2.green(`\u2713 Added MCP server: ${name}`));
|
|
32083
32671
|
const manager = getMCPManager();
|
|
32084
32672
|
await manager.addServer(config2);
|
|
32085
|
-
console.log(
|
|
32673
|
+
console.log(chalk2.green(`\u2713 Connected to MCP server: ${name}`));
|
|
32086
32674
|
const tools = manager.getTools().filter((t) => t.serverName === name);
|
|
32087
|
-
console.log(
|
|
32675
|
+
console.log(chalk2.blue(` Available tools: ${tools.length}`));
|
|
32088
32676
|
} catch (error) {
|
|
32089
|
-
console.error(
|
|
32677
|
+
console.error(chalk2.red(`Error adding MCP server: ${error.message}`));
|
|
32090
32678
|
process.exit(1);
|
|
32091
32679
|
}
|
|
32092
32680
|
});
|
|
@@ -32096,7 +32684,7 @@ function createMCPCommand() {
|
|
|
32096
32684
|
try {
|
|
32097
32685
|
config2 = JSON.parse(jsonConfig);
|
|
32098
32686
|
} catch {
|
|
32099
|
-
console.error(
|
|
32687
|
+
console.error(chalk2.red("Error: Invalid JSON configuration"));
|
|
32100
32688
|
process.exit(1);
|
|
32101
32689
|
}
|
|
32102
32690
|
const serverConfig = {
|
|
@@ -32119,14 +32707,14 @@ function createMCPCommand() {
|
|
|
32119
32707
|
}
|
|
32120
32708
|
}
|
|
32121
32709
|
addMCPServer(serverConfig);
|
|
32122
|
-
console.log(
|
|
32710
|
+
console.log(chalk2.green(`\u2713 Added MCP server: ${name}`));
|
|
32123
32711
|
const manager = getMCPManager();
|
|
32124
32712
|
await manager.addServer(serverConfig);
|
|
32125
|
-
console.log(
|
|
32713
|
+
console.log(chalk2.green(`\u2713 Connected to MCP server: ${name}`));
|
|
32126
32714
|
const tools = manager.getTools().filter((t) => t.serverName === name);
|
|
32127
|
-
console.log(
|
|
32715
|
+
console.log(chalk2.blue(` Available tools: ${tools.length}`));
|
|
32128
32716
|
} catch (error) {
|
|
32129
|
-
console.error(
|
|
32717
|
+
console.error(chalk2.red(`Error adding MCP server: ${error.message}`));
|
|
32130
32718
|
process.exit(1);
|
|
32131
32719
|
}
|
|
32132
32720
|
});
|
|
@@ -32135,9 +32723,9 @@ function createMCPCommand() {
|
|
|
32135
32723
|
const manager = getMCPManager();
|
|
32136
32724
|
await manager.removeServer(name);
|
|
32137
32725
|
removeMCPServer(name);
|
|
32138
|
-
console.log(
|
|
32726
|
+
console.log(chalk2.green(`\u2713 Removed MCP server: ${name}`));
|
|
32139
32727
|
} catch (error) {
|
|
32140
|
-
console.error(
|
|
32728
|
+
console.error(chalk2.red(`Error removing MCP server: ${error.message}`));
|
|
32141
32729
|
process.exit(1);
|
|
32142
32730
|
}
|
|
32143
32731
|
});
|
|
@@ -32145,15 +32733,15 @@ function createMCPCommand() {
|
|
|
32145
32733
|
const config2 = loadMCPConfig();
|
|
32146
32734
|
const manager = getMCPManager();
|
|
32147
32735
|
if (config2.servers.length === 0) {
|
|
32148
|
-
console.log(
|
|
32736
|
+
console.log(chalk2.yellow("No MCP servers configured"));
|
|
32149
32737
|
return;
|
|
32150
32738
|
}
|
|
32151
|
-
console.log(
|
|
32739
|
+
console.log(chalk2.bold("Configured MCP servers:"));
|
|
32152
32740
|
console.log();
|
|
32153
32741
|
for (const server of config2.servers) {
|
|
32154
32742
|
const isConnected = manager.getServers().includes(server.name);
|
|
32155
|
-
const status = isConnected ?
|
|
32156
|
-
console.log(`${
|
|
32743
|
+
const status = isConnected ? chalk2.green("\u2713 Connected") : chalk2.red("\u2717 Disconnected");
|
|
32744
|
+
console.log(`${chalk2.bold(server.name)}: ${status}`);
|
|
32157
32745
|
if (server.transport) {
|
|
32158
32746
|
console.log(` Transport: ${server.transport.type}`);
|
|
32159
32747
|
if (server.transport.type === "stdio") {
|
|
@@ -32186,15 +32774,15 @@ function createMCPCommand() {
|
|
|
32186
32774
|
const config2 = loadMCPConfig();
|
|
32187
32775
|
const serverConfig = config2.servers.find((s) => s.name === name);
|
|
32188
32776
|
if (!serverConfig) {
|
|
32189
|
-
console.error(
|
|
32777
|
+
console.error(chalk2.red(`Server ${name} not found`));
|
|
32190
32778
|
process.exit(1);
|
|
32191
32779
|
}
|
|
32192
|
-
console.log(
|
|
32780
|
+
console.log(chalk2.blue(`Testing connection to ${name}...`));
|
|
32193
32781
|
const manager = getMCPManager();
|
|
32194
32782
|
await manager.addServer(serverConfig);
|
|
32195
32783
|
const tools = manager.getTools().filter((t) => t.serverName === name);
|
|
32196
|
-
console.log(
|
|
32197
|
-
console.log(
|
|
32784
|
+
console.log(chalk2.green(`\u2713 Successfully connected to ${name}`));
|
|
32785
|
+
console.log(chalk2.blue(` Available tools: ${tools.length}`));
|
|
32198
32786
|
if (tools.length > 0) {
|
|
32199
32787
|
console.log(" Tools:");
|
|
32200
32788
|
tools.forEach((tool) => {
|
|
@@ -32203,7 +32791,7 @@ function createMCPCommand() {
|
|
|
32203
32791
|
});
|
|
32204
32792
|
}
|
|
32205
32793
|
} catch (error) {
|
|
32206
|
-
console.error(
|
|
32794
|
+
console.error(chalk2.red(`\u2717 Failed to connect to ${name}: ${error.message}`));
|
|
32207
32795
|
process.exit(1);
|
|
32208
32796
|
}
|
|
32209
32797
|
});
|
|
@@ -32227,9 +32815,9 @@ function createSetNameCommand() {
|
|
|
32227
32815
|
try {
|
|
32228
32816
|
const settingsManager = getSettingsManager();
|
|
32229
32817
|
settingsManager.updateUserSetting("assistantName", name);
|
|
32230
|
-
console.log(
|
|
32818
|
+
console.log(chalk2.green(`\u2705 Assistant name set to: ${name}`));
|
|
32231
32819
|
} catch (error) {
|
|
32232
|
-
console.error(
|
|
32820
|
+
console.error(chalk2.red(`\u274C Failed to set assistant name: ${error.message}`));
|
|
32233
32821
|
process.exit(1);
|
|
32234
32822
|
}
|
|
32235
32823
|
});
|
|
@@ -32254,10 +32842,10 @@ function createToggleConfirmationsCommand() {
|
|
|
32254
32842
|
const currentValue = settingsManager.getUserSetting("requireConfirmation") ?? true;
|
|
32255
32843
|
const newValue = !currentValue;
|
|
32256
32844
|
settingsManager.updateUserSetting("requireConfirmation", newValue);
|
|
32257
|
-
console.log(
|
|
32845
|
+
console.log(chalk2.green(`\u2705 Confirmation requirement ${newValue ? "enabled" : "disabled"}`));
|
|
32258
32846
|
console.log(`File operations and bash commands will ${newValue ? "now" : "no longer"} require confirmation.`);
|
|
32259
32847
|
} catch (error) {
|
|
32260
|
-
console.error(
|
|
32848
|
+
console.error(chalk2.red(`\u274C Failed to toggle confirmations: ${error.message}`));
|
|
32261
32849
|
process.exit(1);
|
|
32262
32850
|
}
|
|
32263
32851
|
});
|
|
@@ -32275,7 +32863,7 @@ var require_package = __commonJS({
|
|
|
32275
32863
|
module.exports = {
|
|
32276
32864
|
type: "module",
|
|
32277
32865
|
name: "@xagent/one-shot",
|
|
32278
|
-
version: "1.2.
|
|
32866
|
+
version: "1.2.2",
|
|
32279
32867
|
description: "An open-source AI agent that brings advanced AI capabilities directly into your terminal with automatic documentation updates.",
|
|
32280
32868
|
main: "dist/index.js",
|
|
32281
32869
|
module: "dist/index.js",
|
|
@@ -32460,6 +33048,7 @@ try {
|
|
|
32460
33048
|
const { printWelcomeBanner: printWelcomeBanner2 } = await Promise.resolve().then(() => (init_use_console_setup(), use_console_setup_exports));
|
|
32461
33049
|
const { getSettingsManager: getSettingsManager2 } = await Promise.resolve().then(() => (init_settings_manager(), settings_manager_exports));
|
|
32462
33050
|
const { ConfirmationService: ConfirmationService2 } = await Promise.resolve().then(() => (init_confirmation_service(), confirmation_service_exports));
|
|
33051
|
+
const { renderMarkdownToConsole: renderMarkdownToConsole2 } = await Promise.resolve().then(() => (init_console_markdown(), console_markdown_exports));
|
|
32463
33052
|
const { createMCPCommand: createMCPCommand2 } = await Promise.resolve().then(() => (init_mcp(), mcp_exports));
|
|
32464
33053
|
const { createSetNameCommand: createSetNameCommand2 } = await Promise.resolve().then(() => (init_set_name(), set_name_exports));
|
|
32465
33054
|
const { createToggleConfirmationsCommand: createToggleConfirmationsCommand2 } = await Promise.resolve().then(() => (init_toggle_confirmations(), toggle_confirmations_exports));
|
|
@@ -32535,7 +33124,7 @@ try {
|
|
|
32535
33124
|
const chatEntries = await agent.processUserMessage(options.prompt);
|
|
32536
33125
|
for (const entry of chatEntries) {
|
|
32537
33126
|
if (entry.type === "assistant" && entry.content) {
|
|
32538
|
-
console.log(entry.content);
|
|
33127
|
+
console.log(renderMarkdownToConsole2(entry.content));
|
|
32539
33128
|
}
|
|
32540
33129
|
}
|
|
32541
33130
|
} catch (error) {
|