codesavant 1.2.0 → 1.2.6
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/cli.js +82 -36
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -5455,6 +5455,9 @@ var init_commands = __esm({
|
|
|
5455
5455
|
// src/cli.ts
|
|
5456
5456
|
import { Command } from "commander";
|
|
5457
5457
|
import chalk20 from "chalk";
|
|
5458
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
5459
|
+
import { fileURLToPath as fileURLToPath4 } from "url";
|
|
5460
|
+
import { dirname as dirname4, join as join6 } from "path";
|
|
5458
5461
|
|
|
5459
5462
|
// src/config.ts
|
|
5460
5463
|
import fs from "fs-extra";
|
|
@@ -5792,6 +5795,9 @@ Use this context to provide more relevant and personalized assistance.`;
|
|
|
5792
5795
|
import readline from "readline";
|
|
5793
5796
|
import chalk17 from "chalk";
|
|
5794
5797
|
import ora from "ora";
|
|
5798
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
5799
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
5800
|
+
import { dirname as dirname2, join as join4 } from "path";
|
|
5795
5801
|
|
|
5796
5802
|
// src/providers/router.ts
|
|
5797
5803
|
import OpenAI from "openai";
|
|
@@ -23004,29 +23010,37 @@ function formatGlobResult(files, pattern, options = {}) {
|
|
|
23004
23010
|
}
|
|
23005
23011
|
function formatBashResult(result, command, options = {}) {
|
|
23006
23012
|
const { collapsed = true, maxCollapsedLines = 10, showExpandHint = true } = options;
|
|
23013
|
+
const isFailed = result.exitCode !== 0;
|
|
23007
23014
|
const lines = [];
|
|
23008
|
-
const displayCommand = command.length > 60 ? command.slice(0, 60) + "..." : command;
|
|
23009
|
-
const statusIcon =
|
|
23010
|
-
const statusText =
|
|
23011
|
-
lines.push(`${COLORS2.accent(ICONS.lightning)} ${COLORS2.accent(displayCommand)}`);
|
|
23012
|
-
lines.push(` ${statusIcon} ${
|
|
23015
|
+
const displayCommand = isFailed ? command : command.length > 60 ? command.slice(0, 60) + "..." : command;
|
|
23016
|
+
const statusIcon = isFailed ? COLORS2.error(ICONS.error) : COLORS2.success(ICONS.success);
|
|
23017
|
+
const statusText = isFailed ? `failed (exit ${result.exitCode})` : "completed";
|
|
23018
|
+
lines.push(`${COLORS2.accent(ICONS.lightning)} ${isFailed ? COLORS2.error("bash") : COLORS2.accent("bash")} ${COLORS2.accent(displayCommand)}`);
|
|
23019
|
+
lines.push(` ${statusIcon} ${isFailed ? COLORS2.error(statusText) : COLORS2.success(statusText)}`);
|
|
23013
23020
|
const outputLines = result.output.split("\n").filter((l) => l.trim()).length;
|
|
23014
23021
|
if (outputLines > 0) {
|
|
23015
23022
|
lines.push(` ${COLORS2.muted(`${outputLines} lines of output`)}`);
|
|
23016
|
-
|
|
23023
|
+
const shouldShowOutput = isFailed || !collapsed;
|
|
23024
|
+
if (collapsed && showExpandHint && !isFailed) {
|
|
23017
23025
|
lines.push(COLORS2.muted(" (ctrl+o to expand)"));
|
|
23018
23026
|
}
|
|
23019
|
-
if (
|
|
23027
|
+
if (shouldShowOutput) {
|
|
23020
23028
|
const outputPreview = result.output.split("\n").slice(0, maxCollapsedLines);
|
|
23021
23029
|
lines.push(COLORS2.muted(" \u2500".repeat(30)));
|
|
23022
23030
|
for (const line of outputPreview) {
|
|
23023
|
-
|
|
23031
|
+
if (isFailed && (line.toLowerCase().includes("error") || line.toLowerCase().includes("failed"))) {
|
|
23032
|
+
lines.push(` ${COLORS2.muted("\u2502")} ${COLORS2.error(line)}`);
|
|
23033
|
+
} else {
|
|
23034
|
+
lines.push(` ${COLORS2.muted("\u2502")} ${line}`);
|
|
23035
|
+
}
|
|
23024
23036
|
}
|
|
23025
23037
|
if (result.truncated || outputLines > maxCollapsedLines) {
|
|
23026
23038
|
const remaining = (result.totalLines || outputLines) - maxCollapsedLines;
|
|
23027
23039
|
lines.push(` ${COLORS2.muted("\u2502")} ${COLORS2.muted(`... (${remaining} more lines)`)}`);
|
|
23028
23040
|
}
|
|
23029
23041
|
}
|
|
23042
|
+
} else if (isFailed) {
|
|
23043
|
+
lines.push(` ${COLORS2.error("No output (command failed silently)")}`);
|
|
23030
23044
|
}
|
|
23031
23045
|
return lines.join("\n");
|
|
23032
23046
|
}
|
|
@@ -25463,6 +25477,9 @@ init_commands();
|
|
|
25463
25477
|
import os18 from "os";
|
|
25464
25478
|
import path24 from "path";
|
|
25465
25479
|
import fs23 from "fs-extra";
|
|
25480
|
+
import { readFileSync as readFileSync2 } from "fs";
|
|
25481
|
+
import { fileURLToPath } from "url";
|
|
25482
|
+
import { dirname, join as join3 } from "path";
|
|
25466
25483
|
|
|
25467
25484
|
// src/commands/types.ts
|
|
25468
25485
|
var DEFAULT_BUG_REPORT_OPTIONS = {
|
|
@@ -25475,7 +25492,11 @@ var DEFAULT_BUG_REPORT_OPTIONS = {
|
|
|
25475
25492
|
};
|
|
25476
25493
|
|
|
25477
25494
|
// src/commands/bug.ts
|
|
25478
|
-
var
|
|
25495
|
+
var __bug_filename = fileURLToPath(import.meta.url);
|
|
25496
|
+
var __bug_dirname = dirname(__bug_filename);
|
|
25497
|
+
var bugPackageJsonPath = join3(__bug_dirname, "..", "package.json");
|
|
25498
|
+
var bugPackageJson = JSON.parse(readFileSync2(bugPackageJsonPath, "utf-8"));
|
|
25499
|
+
var CODESAVANT_VERSION = bugPackageJson.version;
|
|
25479
25500
|
var GITHUB_REPO_URL = "https://github.com/codesavant/codesavant";
|
|
25480
25501
|
function collectSystemInfo() {
|
|
25481
25502
|
return {
|
|
@@ -26505,6 +26526,11 @@ function stripAnsi2(str) {
|
|
|
26505
26526
|
}
|
|
26506
26527
|
|
|
26507
26528
|
// src/repl.ts
|
|
26529
|
+
var __classic_repl_filename = fileURLToPath2(import.meta.url);
|
|
26530
|
+
var __classic_repl_dirname = dirname2(__classic_repl_filename);
|
|
26531
|
+
var classicReplPackageJsonPath = join4(__classic_repl_dirname, "..", "package.json");
|
|
26532
|
+
var classicReplPackageJson = JSON.parse(readFileSync3(classicReplPackageJsonPath, "utf-8"));
|
|
26533
|
+
var CLASSIC_REPL_VERSION = classicReplPackageJson.version;
|
|
26508
26534
|
var PERMISSION_MODES = ["default", "plan", "acceptEdits", "strict", "yolo"];
|
|
26509
26535
|
function createREPL(replConfig) {
|
|
26510
26536
|
const agent = createAgent({
|
|
@@ -27091,7 +27117,7 @@ ${result.message}`));
|
|
|
27091
27117
|
});
|
|
27092
27118
|
const defaultProvider = replConfig.config.providers.find((p) => p.name === replConfig.config.defaultProvider) || replConfig.config.providers[0];
|
|
27093
27119
|
const welcomeScreen = createWelcomeScreen({
|
|
27094
|
-
version:
|
|
27120
|
+
version: CLASSIC_REPL_VERSION,
|
|
27095
27121
|
sessionId: sessionId2,
|
|
27096
27122
|
// Multi-provider info
|
|
27097
27123
|
providers: providerInfoList,
|
|
@@ -28799,6 +28825,11 @@ Undo complete: restored ${restoredCount} file(s)`));
|
|
|
28799
28825
|
};
|
|
28800
28826
|
}
|
|
28801
28827
|
|
|
28828
|
+
// src/repl-ink.ts
|
|
28829
|
+
import { readFileSync as readFileSync4 } from "fs";
|
|
28830
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
28831
|
+
import { dirname as dirname3, join as join5 } from "path";
|
|
28832
|
+
|
|
28802
28833
|
// src/ink/index.tsx
|
|
28803
28834
|
import { render } from "ink";
|
|
28804
28835
|
|
|
@@ -30069,7 +30100,7 @@ function InputBoxView({
|
|
|
30069
30100
|
}
|
|
30070
30101
|
),
|
|
30071
30102
|
/* @__PURE__ */ jsx4(Text4, { color: colors.muted, children: icons.horizontal.repeat(cols) }),
|
|
30072
|
-
/* @__PURE__ */
|
|
30103
|
+
/* @__PURE__ */ jsx4(Box4, { paddingLeft: 1, flexDirection: "column", children: /* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", children: [
|
|
30073
30104
|
/* @__PURE__ */ jsxs4(Text4, { color: colors.primary, bold: true, children: [
|
|
30074
30105
|
isMultiline ? icons.boxV : icons.prompt,
|
|
30075
30106
|
" "
|
|
@@ -30080,11 +30111,11 @@ function InputBoxView({
|
|
|
30080
30111
|
" ",
|
|
30081
30112
|
statusText || "Processing..."
|
|
30082
30113
|
] })
|
|
30083
|
-
] }) : /* @__PURE__ */ jsxs4(Text4, { color: colors.text, children: [
|
|
30084
|
-
value,
|
|
30114
|
+
] }) : /* @__PURE__ */ jsx4(Box4, { flexGrow: 1, children: /* @__PURE__ */ jsxs4(Text4, { wrap: "truncate-end", color: colors.text, children: [
|
|
30115
|
+
value.length > cols - 5 ? value.slice(-(cols - 5)) : value,
|
|
30085
30116
|
/* @__PURE__ */ jsx4(Text4, { color: colors.muted, children: "_" })
|
|
30086
|
-
] })
|
|
30087
|
-
] }),
|
|
30117
|
+
] }) })
|
|
30118
|
+
] }) }),
|
|
30088
30119
|
/* @__PURE__ */ jsx4(Box4, { paddingLeft: 1, children: isMultiline ? /* @__PURE__ */ jsxs4(Text4, { children: [
|
|
30089
30120
|
/* @__PURE__ */ jsx4(Text4, { color: colors.warning, children: "multiline" }),
|
|
30090
30121
|
/* @__PURE__ */ jsxs4(Text4, { color: colors.muted, children: [
|
|
@@ -30130,7 +30161,7 @@ function InputBoxView({
|
|
|
30130
30161
|
] }),
|
|
30131
30162
|
/* @__PURE__ */ jsx4(Text4, { color: colors.primary, children: "Ctrl+C" }),
|
|
30132
30163
|
/* @__PURE__ */ jsx4(Text4, { color: colors.muted, children: " cancel" }),
|
|
30133
|
-
|
|
30164
|
+
permissionMode && /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
30134
30165
|
/* @__PURE__ */ jsxs4(Text4, { color: colors.muted, children: [
|
|
30135
30166
|
" ",
|
|
30136
30167
|
icons.boxV,
|
|
@@ -30138,7 +30169,7 @@ function InputBoxView({
|
|
|
30138
30169
|
] }),
|
|
30139
30170
|
/* @__PURE__ */ jsxs4(Text4, { color: colors.info, children: [
|
|
30140
30171
|
"[",
|
|
30141
|
-
|
|
30172
|
+
permissionMode,
|
|
30142
30173
|
"]"
|
|
30143
30174
|
] })
|
|
30144
30175
|
] })
|
|
@@ -30170,8 +30201,8 @@ function App({
|
|
|
30170
30201
|
const [autocompleteQuery, setAutocompleteQuery] = useState5("");
|
|
30171
30202
|
const lastEscapeRef = useRef(0);
|
|
30172
30203
|
const [renderedMessageCount, setRenderedMessageCount] = useState5(0);
|
|
30173
|
-
const permissionModes = ["
|
|
30174
|
-
const [
|
|
30204
|
+
const permissionModes = ["default", "plan", "acceptEdits", "strict", "yolo"];
|
|
30205
|
+
const [currentPermissionMode, setCurrentPermissionMode] = useState5(permissionMode);
|
|
30175
30206
|
useEffect2(() => {
|
|
30176
30207
|
if (sessionId2) actions.setSessionId(sessionId2);
|
|
30177
30208
|
if (provider && model) actions.setProvider(provider, model);
|
|
@@ -30251,7 +30282,7 @@ function App({
|
|
|
30251
30282
|
return;
|
|
30252
30283
|
}
|
|
30253
30284
|
if (key.shift && key.tab) {
|
|
30254
|
-
const currentIndex = permissionModes.indexOf(
|
|
30285
|
+
const currentIndex = permissionModes.indexOf(currentPermissionMode);
|
|
30255
30286
|
const nextIndex = (currentIndex + 1) % permissionModes.length;
|
|
30256
30287
|
const nextMode = permissionModes[nextIndex];
|
|
30257
30288
|
setCurrentPermissionMode(nextMode);
|
|
@@ -30387,10 +30418,14 @@ function App({
|
|
|
30387
30418
|
setAutocompleteQuery("");
|
|
30388
30419
|
}, []);
|
|
30389
30420
|
useEffect2(() => {
|
|
30390
|
-
|
|
30391
|
-
|
|
30392
|
-
|
|
30393
|
-
|
|
30421
|
+
const canMoveToStatic = !state.isProcessing && !state.streamingContent && (!state.todosVisible || state.todos.length === 0);
|
|
30422
|
+
if (canMoveToStatic && state.messages.length > renderedMessageCount) {
|
|
30423
|
+
const timer = setTimeout(() => {
|
|
30424
|
+
setRenderedMessageCount(state.messages.length);
|
|
30425
|
+
}, 100);
|
|
30426
|
+
return () => clearTimeout(timer);
|
|
30427
|
+
}
|
|
30428
|
+
}, [state.isProcessing, state.streamingContent, state.todosVisible, state.todos.length, state.messages.length, renderedMessageCount]);
|
|
30394
30429
|
const completedMessages = state.messages.slice(0, renderedMessageCount);
|
|
30395
30430
|
const activeMessages = state.messages.slice(renderedMessageCount);
|
|
30396
30431
|
const { colors } = theme;
|
|
@@ -30425,7 +30460,7 @@ function App({
|
|
|
30425
30460
|
historyIndex: state.historyIndex,
|
|
30426
30461
|
onHistoryNavigate: handleHistoryNavigate,
|
|
30427
30462
|
theme,
|
|
30428
|
-
permissionMode:
|
|
30463
|
+
permissionMode: currentPermissionMode,
|
|
30429
30464
|
historySearchMode,
|
|
30430
30465
|
historySearchQuery,
|
|
30431
30466
|
historySearchMatch,
|
|
@@ -30624,6 +30659,11 @@ async function waitForExit() {
|
|
|
30624
30659
|
// src/repl-ink.ts
|
|
30625
30660
|
init_errors();
|
|
30626
30661
|
init_commands();
|
|
30662
|
+
var __repl_filename = fileURLToPath3(import.meta.url);
|
|
30663
|
+
var __repl_dirname = dirname3(__repl_filename);
|
|
30664
|
+
var replPackageJsonPath = join5(__repl_dirname, "..", "package.json");
|
|
30665
|
+
var replPackageJson = JSON.parse(readFileSync4(replPackageJsonPath, "utf-8"));
|
|
30666
|
+
var REPL_VERSION = replPackageJson.version;
|
|
30627
30667
|
function createInkREPL(replConfig) {
|
|
30628
30668
|
const agent = createAgent({
|
|
30629
30669
|
config: replConfig.config,
|
|
@@ -30703,13 +30743,14 @@ function createInkREPL(replConfig) {
|
|
|
30703
30743
|
truncated: output.length > 500,
|
|
30704
30744
|
totalLines: lineCount
|
|
30705
30745
|
};
|
|
30706
|
-
return formatBashResult(result, command, { collapsed:
|
|
30746
|
+
return formatBashResult(result, command, { collapsed: success });
|
|
30707
30747
|
}
|
|
30708
30748
|
default:
|
|
30709
30749
|
if (success) {
|
|
30710
30750
|
return `${toolName} completed${lineCount > 0 ? ` (${lineCount} lines)` : ""}`;
|
|
30711
30751
|
} else {
|
|
30712
|
-
|
|
30752
|
+
const errorMsg = toolResult.error || output.slice(0, 200) || "Unknown error";
|
|
30753
|
+
return `${toolName} failed: ${errorMsg}`;
|
|
30713
30754
|
}
|
|
30714
30755
|
}
|
|
30715
30756
|
}
|
|
@@ -31977,7 +32018,7 @@ Type /help for available commands.`);
|
|
|
31977
32018
|
isAvailable: p.name === "ollama" || !!p.apiKey
|
|
31978
32019
|
}));
|
|
31979
32020
|
const welcomeMessage = createWelcomeScreen({
|
|
31980
|
-
version:
|
|
32021
|
+
version: REPL_VERSION,
|
|
31981
32022
|
sessionId: sessionId2,
|
|
31982
32023
|
providers: providerInfoList,
|
|
31983
32024
|
activeProvider: replConfig.config.defaultProvider,
|
|
@@ -31990,13 +32031,13 @@ Type /help for available commands.`);
|
|
|
31990
32031
|
mcpTools: mcpToolCount,
|
|
31991
32032
|
workingDir: projectPath
|
|
31992
32033
|
});
|
|
31993
|
-
let
|
|
32034
|
+
let currentPermissionMode = agent.getPermissionManager().getMode();
|
|
31994
32035
|
appController = renderApp({
|
|
31995
32036
|
sessionId: sessionId2,
|
|
31996
32037
|
provider: defaultProvider?.name,
|
|
31997
32038
|
model: defaultProvider?.model,
|
|
31998
32039
|
welcomeMessage,
|
|
31999
|
-
permissionMode:
|
|
32040
|
+
permissionMode: currentPermissionMode,
|
|
32000
32041
|
onSubmit: (input) => {
|
|
32001
32042
|
if (!isProcessing) {
|
|
32002
32043
|
processAgentStream(input);
|
|
@@ -32032,7 +32073,7 @@ Type /help for available commands.`);
|
|
|
32032
32073
|
const validModes = ["prompt", "auto-edit", "auto-full", "deny"];
|
|
32033
32074
|
if (validModes.includes(mode)) {
|
|
32034
32075
|
agent.getPermissionManager().setMode(mode);
|
|
32035
|
-
|
|
32076
|
+
currentPermissionMode = mode;
|
|
32036
32077
|
}
|
|
32037
32078
|
}
|
|
32038
32079
|
});
|
|
@@ -32195,10 +32236,10 @@ async function detectCICommands(projectPath) {
|
|
|
32195
32236
|
const fs26 = await import("fs-extra");
|
|
32196
32237
|
const path27 = await import("path");
|
|
32197
32238
|
const commands = [];
|
|
32198
|
-
const
|
|
32199
|
-
if (await fs26.pathExists(
|
|
32239
|
+
const packageJsonPath2 = path27.join(projectPath, "package.json");
|
|
32240
|
+
if (await fs26.pathExists(packageJsonPath2)) {
|
|
32200
32241
|
try {
|
|
32201
|
-
const pkg = await fs26.readJson(
|
|
32242
|
+
const pkg = await fs26.readJson(packageJsonPath2);
|
|
32202
32243
|
if (pkg.scripts?.build) {
|
|
32203
32244
|
commands.push("npm run build");
|
|
32204
32245
|
}
|
|
@@ -32231,7 +32272,7 @@ async function detectCICommands(projectPath) {
|
|
|
32231
32272
|
if (await fs26.pathExists(path27.join(projectPath, "pyproject.toml")) || await fs26.pathExists(path27.join(projectPath, "setup.py"))) {
|
|
32232
32273
|
commands.push("python -m pytest");
|
|
32233
32274
|
}
|
|
32234
|
-
if (commands.length === 0 && await fs26.pathExists(
|
|
32275
|
+
if (commands.length === 0 && await fs26.pathExists(packageJsonPath2)) {
|
|
32235
32276
|
commands.push("npm run build");
|
|
32236
32277
|
}
|
|
32237
32278
|
return commands;
|
|
@@ -32327,6 +32368,11 @@ Fix all the issues to make the CI pass. Use the available tools to read files, e
|
|
|
32327
32368
|
}
|
|
32328
32369
|
|
|
32329
32370
|
// src/cli.ts
|
|
32371
|
+
var __filename = fileURLToPath4(import.meta.url);
|
|
32372
|
+
var __dirname = dirname4(__filename);
|
|
32373
|
+
var packageJsonPath = join6(__dirname, "..", "package.json");
|
|
32374
|
+
var packageJson = JSON.parse(readFileSync5(packageJsonPath, "utf-8"));
|
|
32375
|
+
var VERSION = packageJson.version;
|
|
32330
32376
|
var MAX_STDIN_SIZE = 10 * 1024 * 1024;
|
|
32331
32377
|
var MAX_STDIN_LINES = 1e5;
|
|
32332
32378
|
async function readStdinInput(format, options) {
|
|
@@ -32378,7 +32424,7 @@ async function readStdinInput(format, options) {
|
|
|
32378
32424
|
});
|
|
32379
32425
|
}
|
|
32380
32426
|
var program = new Command();
|
|
32381
|
-
program.name("codesavant").description("AI coding assistant for your terminal").version(
|
|
32427
|
+
program.name("codesavant").description("AI coding assistant for your terminal").version(VERSION).option("--verbose", "Enable verbose logging for debugging").option("--debug <categories>", 'Enable debug logging for specific categories (comma-separated: api,mcp,tool,provider,stream,session,context,permission,checkpoint,error,all). Use ! prefix to exclude: "all,!mcp"').option("--mcp-debug", "Enable MCP protocol-level debug logging").hook("preAction", (thisCommand) => {
|
|
32382
32428
|
const opts = thisCommand.opts();
|
|
32383
32429
|
if (opts.debug) {
|
|
32384
32430
|
setVerbose(true);
|