@kimbho/kimbho-cli 0.1.31 → 0.1.36
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/index.cjs +1215 -361
- package/dist/index.cjs.map +4 -4
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1147,9 +1147,9 @@ var require_command = __commonJS({
|
|
|
1147
1147
|
"../../node_modules/commander/lib/command.js"(exports2) {
|
|
1148
1148
|
var EventEmitter = require("node:events").EventEmitter;
|
|
1149
1149
|
var childProcess = require("node:child_process");
|
|
1150
|
-
var
|
|
1150
|
+
var path35 = require("node:path");
|
|
1151
1151
|
var fs = require("node:fs");
|
|
1152
|
-
var
|
|
1152
|
+
var process38 = require("node:process");
|
|
1153
1153
|
var { Argument: Argument2, humanReadableArgName } = require_argument();
|
|
1154
1154
|
var { CommanderError: CommanderError2 } = require_error();
|
|
1155
1155
|
var { Help: Help2, stripColor } = require_help();
|
|
@@ -1196,13 +1196,13 @@ var require_command = __commonJS({
|
|
|
1196
1196
|
this._showSuggestionAfterError = true;
|
|
1197
1197
|
this._savedState = null;
|
|
1198
1198
|
this._outputConfiguration = {
|
|
1199
|
-
writeOut: (str) =>
|
|
1200
|
-
writeErr: (str) =>
|
|
1199
|
+
writeOut: (str) => process38.stdout.write(str),
|
|
1200
|
+
writeErr: (str) => process38.stderr.write(str),
|
|
1201
1201
|
outputError: (str, write) => write(str),
|
|
1202
|
-
getOutHelpWidth: () =>
|
|
1203
|
-
getErrHelpWidth: () =>
|
|
1204
|
-
getOutHasColors: () => useColor() ?? (
|
|
1205
|
-
getErrHasColors: () => useColor() ?? (
|
|
1202
|
+
getOutHelpWidth: () => process38.stdout.isTTY ? process38.stdout.columns : void 0,
|
|
1203
|
+
getErrHelpWidth: () => process38.stderr.isTTY ? process38.stderr.columns : void 0,
|
|
1204
|
+
getOutHasColors: () => useColor() ?? (process38.stdout.isTTY && process38.stdout.hasColors?.()),
|
|
1205
|
+
getErrHasColors: () => useColor() ?? (process38.stderr.isTTY && process38.stderr.hasColors?.()),
|
|
1206
1206
|
stripColor: (str) => stripColor(str)
|
|
1207
1207
|
};
|
|
1208
1208
|
this._hidden = false;
|
|
@@ -1585,7 +1585,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1585
1585
|
if (this._exitCallback) {
|
|
1586
1586
|
this._exitCallback(new CommanderError2(exitCode, code, message));
|
|
1587
1587
|
}
|
|
1588
|
-
|
|
1588
|
+
process38.exit(exitCode);
|
|
1589
1589
|
}
|
|
1590
1590
|
/**
|
|
1591
1591
|
* Register callback `fn` for the command.
|
|
@@ -1983,16 +1983,16 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
1983
1983
|
}
|
|
1984
1984
|
parseOptions = parseOptions || {};
|
|
1985
1985
|
if (argv === void 0 && parseOptions.from === void 0) {
|
|
1986
|
-
if (
|
|
1986
|
+
if (process38.versions?.electron) {
|
|
1987
1987
|
parseOptions.from = "electron";
|
|
1988
1988
|
}
|
|
1989
|
-
const execArgv =
|
|
1989
|
+
const execArgv = process38.execArgv ?? [];
|
|
1990
1990
|
if (execArgv.includes("-e") || execArgv.includes("--eval") || execArgv.includes("-p") || execArgv.includes("--print")) {
|
|
1991
1991
|
parseOptions.from = "eval";
|
|
1992
1992
|
}
|
|
1993
1993
|
}
|
|
1994
1994
|
if (argv === void 0) {
|
|
1995
|
-
argv =
|
|
1995
|
+
argv = process38.argv;
|
|
1996
1996
|
}
|
|
1997
1997
|
this.rawArgs = argv.slice();
|
|
1998
1998
|
let userArgs;
|
|
@@ -2003,7 +2003,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2003
2003
|
userArgs = argv.slice(2);
|
|
2004
2004
|
break;
|
|
2005
2005
|
case "electron":
|
|
2006
|
-
if (
|
|
2006
|
+
if (process38.defaultApp) {
|
|
2007
2007
|
this._scriptPath = argv[1];
|
|
2008
2008
|
userArgs = argv.slice(2);
|
|
2009
2009
|
} else {
|
|
@@ -2147,9 +2147,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2147
2147
|
let launchWithNode = false;
|
|
2148
2148
|
const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
|
|
2149
2149
|
function findFile(baseDir, baseName) {
|
|
2150
|
-
const localBin =
|
|
2150
|
+
const localBin = path35.resolve(baseDir, baseName);
|
|
2151
2151
|
if (fs.existsSync(localBin)) return localBin;
|
|
2152
|
-
if (sourceExt.includes(
|
|
2152
|
+
if (sourceExt.includes(path35.extname(baseName))) return void 0;
|
|
2153
2153
|
const foundExt = sourceExt.find(
|
|
2154
2154
|
(ext) => fs.existsSync(`${localBin}${ext}`)
|
|
2155
2155
|
);
|
|
@@ -2167,17 +2167,17 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2167
2167
|
} catch {
|
|
2168
2168
|
resolvedScriptPath = this._scriptPath;
|
|
2169
2169
|
}
|
|
2170
|
-
executableDir =
|
|
2171
|
-
|
|
2170
|
+
executableDir = path35.resolve(
|
|
2171
|
+
path35.dirname(resolvedScriptPath),
|
|
2172
2172
|
executableDir
|
|
2173
2173
|
);
|
|
2174
2174
|
}
|
|
2175
2175
|
if (executableDir) {
|
|
2176
2176
|
let localFile = findFile(executableDir, executableFile);
|
|
2177
2177
|
if (!localFile && !subcommand._executableFile && this._scriptPath) {
|
|
2178
|
-
const legacyName =
|
|
2178
|
+
const legacyName = path35.basename(
|
|
2179
2179
|
this._scriptPath,
|
|
2180
|
-
|
|
2180
|
+
path35.extname(this._scriptPath)
|
|
2181
2181
|
);
|
|
2182
2182
|
if (legacyName !== this._name) {
|
|
2183
2183
|
localFile = findFile(
|
|
@@ -2188,13 +2188,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2188
2188
|
}
|
|
2189
2189
|
executableFile = localFile || executableFile;
|
|
2190
2190
|
}
|
|
2191
|
-
launchWithNode = sourceExt.includes(
|
|
2191
|
+
launchWithNode = sourceExt.includes(path35.extname(executableFile));
|
|
2192
2192
|
let proc;
|
|
2193
|
-
if (
|
|
2193
|
+
if (process38.platform !== "win32") {
|
|
2194
2194
|
if (launchWithNode) {
|
|
2195
2195
|
args.unshift(executableFile);
|
|
2196
|
-
args = incrementNodeInspectorPort(
|
|
2197
|
-
proc = childProcess.spawn(
|
|
2196
|
+
args = incrementNodeInspectorPort(process38.execArgv).concat(args);
|
|
2197
|
+
proc = childProcess.spawn(process38.argv[0], args, { stdio: "inherit" });
|
|
2198
2198
|
} else {
|
|
2199
2199
|
proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
|
|
2200
2200
|
}
|
|
@@ -2205,13 +2205,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2205
2205
|
subcommand._name
|
|
2206
2206
|
);
|
|
2207
2207
|
args.unshift(executableFile);
|
|
2208
|
-
args = incrementNodeInspectorPort(
|
|
2209
|
-
proc = childProcess.spawn(
|
|
2208
|
+
args = incrementNodeInspectorPort(process38.execArgv).concat(args);
|
|
2209
|
+
proc = childProcess.spawn(process38.execPath, args, { stdio: "inherit" });
|
|
2210
2210
|
}
|
|
2211
2211
|
if (!proc.killed) {
|
|
2212
2212
|
const signals = ["SIGUSR1", "SIGUSR2", "SIGTERM", "SIGINT", "SIGHUP"];
|
|
2213
2213
|
signals.forEach((signal) => {
|
|
2214
|
-
|
|
2214
|
+
process38.on(signal, () => {
|
|
2215
2215
|
if (proc.killed === false && proc.exitCode === null) {
|
|
2216
2216
|
proc.kill(signal);
|
|
2217
2217
|
}
|
|
@@ -2222,7 +2222,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2222
2222
|
proc.on("close", (code) => {
|
|
2223
2223
|
code = code ?? 1;
|
|
2224
2224
|
if (!exitCallback) {
|
|
2225
|
-
|
|
2225
|
+
process38.exit(code);
|
|
2226
2226
|
} else {
|
|
2227
2227
|
exitCallback(
|
|
2228
2228
|
new CommanderError2(
|
|
@@ -2244,7 +2244,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2244
2244
|
throw new Error(`'${executableFile}' not executable`);
|
|
2245
2245
|
}
|
|
2246
2246
|
if (!exitCallback) {
|
|
2247
|
-
|
|
2247
|
+
process38.exit(1);
|
|
2248
2248
|
} else {
|
|
2249
2249
|
const wrappedError = new CommanderError2(
|
|
2250
2250
|
1,
|
|
@@ -2739,13 +2739,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
2739
2739
|
*/
|
|
2740
2740
|
_parseOptionsEnv() {
|
|
2741
2741
|
this.options.forEach((option) => {
|
|
2742
|
-
if (option.envVar && option.envVar in
|
|
2742
|
+
if (option.envVar && option.envVar in process38.env) {
|
|
2743
2743
|
const optionKey = option.attributeName();
|
|
2744
2744
|
if (this.getOptionValue(optionKey) === void 0 || ["default", "config", "env"].includes(
|
|
2745
2745
|
this.getOptionValueSource(optionKey)
|
|
2746
2746
|
)) {
|
|
2747
2747
|
if (option.required || option.optional) {
|
|
2748
|
-
this.emit(`optionEnv:${option.name()}`,
|
|
2748
|
+
this.emit(`optionEnv:${option.name()}`, process38.env[option.envVar]);
|
|
2749
2749
|
} else {
|
|
2750
2750
|
this.emit(`optionEnv:${option.name()}`);
|
|
2751
2751
|
}
|
|
@@ -3035,7 +3035,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3035
3035
|
* @return {Command}
|
|
3036
3036
|
*/
|
|
3037
3037
|
nameFromFilename(filename) {
|
|
3038
|
-
this._name =
|
|
3038
|
+
this._name = path35.basename(filename, path35.extname(filename));
|
|
3039
3039
|
return this;
|
|
3040
3040
|
}
|
|
3041
3041
|
/**
|
|
@@ -3049,9 +3049,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3049
3049
|
* @param {string} [path]
|
|
3050
3050
|
* @return {(string|null|Command)}
|
|
3051
3051
|
*/
|
|
3052
|
-
executableDir(
|
|
3053
|
-
if (
|
|
3054
|
-
this._executableDir =
|
|
3052
|
+
executableDir(path36) {
|
|
3053
|
+
if (path36 === void 0) return this._executableDir;
|
|
3054
|
+
this._executableDir = path36;
|
|
3055
3055
|
return this;
|
|
3056
3056
|
}
|
|
3057
3057
|
/**
|
|
@@ -3200,7 +3200,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3200
3200
|
*/
|
|
3201
3201
|
help(contextOptions) {
|
|
3202
3202
|
this.outputHelp(contextOptions);
|
|
3203
|
-
let exitCode = Number(
|
|
3203
|
+
let exitCode = Number(process38.exitCode ?? 0);
|
|
3204
3204
|
if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
|
|
3205
3205
|
exitCode = 1;
|
|
3206
3206
|
}
|
|
@@ -3290,9 +3290,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
|
|
|
3290
3290
|
});
|
|
3291
3291
|
}
|
|
3292
3292
|
function useColor() {
|
|
3293
|
-
if (
|
|
3293
|
+
if (process38.env.NO_COLOR || process38.env.FORCE_COLOR === "0" || process38.env.FORCE_COLOR === "false")
|
|
3294
3294
|
return false;
|
|
3295
|
-
if (
|
|
3295
|
+
if (process38.env.FORCE_COLOR || process38.env.CLICOLOR_FORCE !== void 0)
|
|
3296
3296
|
return true;
|
|
3297
3297
|
return void 0;
|
|
3298
3298
|
}
|
|
@@ -8511,8 +8511,8 @@ var require_utils = __commonJS({
|
|
|
8511
8511
|
}
|
|
8512
8512
|
return ind;
|
|
8513
8513
|
}
|
|
8514
|
-
function removeDotSegments(
|
|
8515
|
-
let input =
|
|
8514
|
+
function removeDotSegments(path35) {
|
|
8515
|
+
let input = path35;
|
|
8516
8516
|
const output = [];
|
|
8517
8517
|
let nextSlash = -1;
|
|
8518
8518
|
let len = 0;
|
|
@@ -8711,8 +8711,8 @@ var require_schemes = __commonJS({
|
|
|
8711
8711
|
wsComponent.secure = void 0;
|
|
8712
8712
|
}
|
|
8713
8713
|
if (wsComponent.resourceName) {
|
|
8714
|
-
const [
|
|
8715
|
-
wsComponent.path =
|
|
8714
|
+
const [path35, query] = wsComponent.resourceName.split("?");
|
|
8715
|
+
wsComponent.path = path35 && path35 !== "/" ? path35 : void 0;
|
|
8716
8716
|
wsComponent.query = query;
|
|
8717
8717
|
wsComponent.resourceName = void 0;
|
|
8718
8718
|
}
|
|
@@ -12093,7 +12093,7 @@ var require_windows = __commonJS({
|
|
|
12093
12093
|
module2.exports = isexe;
|
|
12094
12094
|
isexe.sync = sync;
|
|
12095
12095
|
var fs = require("fs");
|
|
12096
|
-
function checkPathExt(
|
|
12096
|
+
function checkPathExt(path35, options) {
|
|
12097
12097
|
var pathext = options.pathExt !== void 0 ? options.pathExt : process.env.PATHEXT;
|
|
12098
12098
|
if (!pathext) {
|
|
12099
12099
|
return true;
|
|
@@ -12104,25 +12104,25 @@ var require_windows = __commonJS({
|
|
|
12104
12104
|
}
|
|
12105
12105
|
for (var i = 0; i < pathext.length; i++) {
|
|
12106
12106
|
var p = pathext[i].toLowerCase();
|
|
12107
|
-
if (p &&
|
|
12107
|
+
if (p && path35.substr(-p.length).toLowerCase() === p) {
|
|
12108
12108
|
return true;
|
|
12109
12109
|
}
|
|
12110
12110
|
}
|
|
12111
12111
|
return false;
|
|
12112
12112
|
}
|
|
12113
|
-
function checkStat(stat2,
|
|
12113
|
+
function checkStat(stat2, path35, options) {
|
|
12114
12114
|
if (!stat2.isSymbolicLink() && !stat2.isFile()) {
|
|
12115
12115
|
return false;
|
|
12116
12116
|
}
|
|
12117
|
-
return checkPathExt(
|
|
12117
|
+
return checkPathExt(path35, options);
|
|
12118
12118
|
}
|
|
12119
|
-
function isexe(
|
|
12120
|
-
fs.stat(
|
|
12121
|
-
cb(er, er ? false : checkStat(stat2,
|
|
12119
|
+
function isexe(path35, options, cb) {
|
|
12120
|
+
fs.stat(path35, function(er, stat2) {
|
|
12121
|
+
cb(er, er ? false : checkStat(stat2, path35, options));
|
|
12122
12122
|
});
|
|
12123
12123
|
}
|
|
12124
|
-
function sync(
|
|
12125
|
-
return checkStat(fs.statSync(
|
|
12124
|
+
function sync(path35, options) {
|
|
12125
|
+
return checkStat(fs.statSync(path35), path35, options);
|
|
12126
12126
|
}
|
|
12127
12127
|
}
|
|
12128
12128
|
});
|
|
@@ -12133,13 +12133,13 @@ var require_mode = __commonJS({
|
|
|
12133
12133
|
module2.exports = isexe;
|
|
12134
12134
|
isexe.sync = sync;
|
|
12135
12135
|
var fs = require("fs");
|
|
12136
|
-
function isexe(
|
|
12137
|
-
fs.stat(
|
|
12136
|
+
function isexe(path35, options, cb) {
|
|
12137
|
+
fs.stat(path35, function(er, stat2) {
|
|
12138
12138
|
cb(er, er ? false : checkStat(stat2, options));
|
|
12139
12139
|
});
|
|
12140
12140
|
}
|
|
12141
|
-
function sync(
|
|
12142
|
-
return checkStat(fs.statSync(
|
|
12141
|
+
function sync(path35, options) {
|
|
12142
|
+
return checkStat(fs.statSync(path35), options);
|
|
12143
12143
|
}
|
|
12144
12144
|
function checkStat(stat2, options) {
|
|
12145
12145
|
return stat2.isFile() && checkMode(stat2, options);
|
|
@@ -12172,7 +12172,7 @@ var require_isexe = __commonJS({
|
|
|
12172
12172
|
}
|
|
12173
12173
|
module2.exports = isexe;
|
|
12174
12174
|
isexe.sync = sync;
|
|
12175
|
-
function isexe(
|
|
12175
|
+
function isexe(path35, options, cb) {
|
|
12176
12176
|
if (typeof options === "function") {
|
|
12177
12177
|
cb = options;
|
|
12178
12178
|
options = {};
|
|
@@ -12182,7 +12182,7 @@ var require_isexe = __commonJS({
|
|
|
12182
12182
|
throw new TypeError("callback not provided");
|
|
12183
12183
|
}
|
|
12184
12184
|
return new Promise(function(resolve, reject) {
|
|
12185
|
-
isexe(
|
|
12185
|
+
isexe(path35, options || {}, function(er, is) {
|
|
12186
12186
|
if (er) {
|
|
12187
12187
|
reject(er);
|
|
12188
12188
|
} else {
|
|
@@ -12191,7 +12191,7 @@ var require_isexe = __commonJS({
|
|
|
12191
12191
|
});
|
|
12192
12192
|
});
|
|
12193
12193
|
}
|
|
12194
|
-
core(
|
|
12194
|
+
core(path35, options || {}, function(er, is) {
|
|
12195
12195
|
if (er) {
|
|
12196
12196
|
if (er.code === "EACCES" || options && options.ignoreErrors) {
|
|
12197
12197
|
er = null;
|
|
@@ -12201,9 +12201,9 @@ var require_isexe = __commonJS({
|
|
|
12201
12201
|
cb(er, is);
|
|
12202
12202
|
});
|
|
12203
12203
|
}
|
|
12204
|
-
function sync(
|
|
12204
|
+
function sync(path35, options) {
|
|
12205
12205
|
try {
|
|
12206
|
-
return core.sync(
|
|
12206
|
+
return core.sync(path35, options || {});
|
|
12207
12207
|
} catch (er) {
|
|
12208
12208
|
if (options && options.ignoreErrors || er.code === "EACCES") {
|
|
12209
12209
|
return false;
|
|
@@ -12219,7 +12219,7 @@ var require_isexe = __commonJS({
|
|
|
12219
12219
|
var require_which = __commonJS({
|
|
12220
12220
|
"../../node_modules/which/which.js"(exports2, module2) {
|
|
12221
12221
|
var isWindows = process.platform === "win32" || process.env.OSTYPE === "cygwin" || process.env.OSTYPE === "msys";
|
|
12222
|
-
var
|
|
12222
|
+
var path35 = require("path");
|
|
12223
12223
|
var COLON = isWindows ? ";" : ":";
|
|
12224
12224
|
var isexe = require_isexe();
|
|
12225
12225
|
var getNotFoundError = (cmd) => Object.assign(new Error(`not found: ${cmd}`), { code: "ENOENT" });
|
|
@@ -12257,7 +12257,7 @@ var require_which = __commonJS({
|
|
|
12257
12257
|
return opt.all && found.length ? resolve(found) : reject(getNotFoundError(cmd));
|
|
12258
12258
|
const ppRaw = pathEnv[i];
|
|
12259
12259
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
12260
|
-
const pCmd =
|
|
12260
|
+
const pCmd = path35.join(pathPart, cmd);
|
|
12261
12261
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
12262
12262
|
resolve(subStep(p, i, 0));
|
|
12263
12263
|
});
|
|
@@ -12284,7 +12284,7 @@ var require_which = __commonJS({
|
|
|
12284
12284
|
for (let i = 0; i < pathEnv.length; i++) {
|
|
12285
12285
|
const ppRaw = pathEnv[i];
|
|
12286
12286
|
const pathPart = /^".*"$/.test(ppRaw) ? ppRaw.slice(1, -1) : ppRaw;
|
|
12287
|
-
const pCmd =
|
|
12287
|
+
const pCmd = path35.join(pathPart, cmd);
|
|
12288
12288
|
const p = !pathPart && /^\.[\\\/]/.test(cmd) ? cmd.slice(0, 2) + pCmd : pCmd;
|
|
12289
12289
|
for (let j = 0; j < pathExt.length; j++) {
|
|
12290
12290
|
const cur = p + pathExt[j];
|
|
@@ -12332,7 +12332,7 @@ var require_path_key = __commonJS({
|
|
|
12332
12332
|
var require_resolveCommand = __commonJS({
|
|
12333
12333
|
"../../node_modules/cross-spawn/lib/util/resolveCommand.js"(exports2, module2) {
|
|
12334
12334
|
"use strict";
|
|
12335
|
-
var
|
|
12335
|
+
var path35 = require("path");
|
|
12336
12336
|
var which = require_which();
|
|
12337
12337
|
var getPathKey = require_path_key();
|
|
12338
12338
|
function resolveCommandAttempt(parsed, withoutPathExt) {
|
|
@@ -12350,7 +12350,7 @@ var require_resolveCommand = __commonJS({
|
|
|
12350
12350
|
try {
|
|
12351
12351
|
resolved = which.sync(parsed.command, {
|
|
12352
12352
|
path: env[getPathKey({ env })],
|
|
12353
|
-
pathExt: withoutPathExt ?
|
|
12353
|
+
pathExt: withoutPathExt ? path35.delimiter : void 0
|
|
12354
12354
|
});
|
|
12355
12355
|
} catch (e) {
|
|
12356
12356
|
} finally {
|
|
@@ -12359,7 +12359,7 @@ var require_resolveCommand = __commonJS({
|
|
|
12359
12359
|
}
|
|
12360
12360
|
}
|
|
12361
12361
|
if (resolved) {
|
|
12362
|
-
resolved =
|
|
12362
|
+
resolved = path35.resolve(hasCustomCwd ? parsed.options.cwd : "", resolved);
|
|
12363
12363
|
}
|
|
12364
12364
|
return resolved;
|
|
12365
12365
|
}
|
|
@@ -12413,8 +12413,8 @@ var require_shebang_command = __commonJS({
|
|
|
12413
12413
|
if (!match) {
|
|
12414
12414
|
return null;
|
|
12415
12415
|
}
|
|
12416
|
-
const [
|
|
12417
|
-
const binary =
|
|
12416
|
+
const [path35, argument] = match[0].replace(/#! ?/, "").split(" ");
|
|
12417
|
+
const binary = path35.split("/").pop();
|
|
12418
12418
|
if (binary === "env") {
|
|
12419
12419
|
return argument;
|
|
12420
12420
|
}
|
|
@@ -12449,7 +12449,7 @@ var require_readShebang = __commonJS({
|
|
|
12449
12449
|
var require_parse2 = __commonJS({
|
|
12450
12450
|
"../../node_modules/cross-spawn/lib/parse.js"(exports2, module2) {
|
|
12451
12451
|
"use strict";
|
|
12452
|
-
var
|
|
12452
|
+
var path35 = require("path");
|
|
12453
12453
|
var resolveCommand = require_resolveCommand();
|
|
12454
12454
|
var escape2 = require_escape();
|
|
12455
12455
|
var readShebang = require_readShebang();
|
|
@@ -12474,7 +12474,7 @@ var require_parse2 = __commonJS({
|
|
|
12474
12474
|
const needsShell = !isExecutableRegExp.test(commandFile);
|
|
12475
12475
|
if (parsed.options.forceShell || needsShell) {
|
|
12476
12476
|
const needsDoubleEscapeMetaChars = isCmdShimRegExp.test(commandFile);
|
|
12477
|
-
parsed.command =
|
|
12477
|
+
parsed.command = path35.normalize(parsed.command);
|
|
12478
12478
|
parsed.command = escape2.command(parsed.command);
|
|
12479
12479
|
parsed.args = parsed.args.map((arg) => escape2.argument(arg, needsDoubleEscapeMetaChars));
|
|
12480
12480
|
const shellCommand = [parsed.command].concat(parsed.args).join(" ");
|
|
@@ -12718,7 +12718,7 @@ function createCompletionRuntimeCommand(program2) {
|
|
|
12718
12718
|
// package.json
|
|
12719
12719
|
var package_default = {
|
|
12720
12720
|
name: "@kimbho/kimbho-cli",
|
|
12721
|
-
version: "0.1.
|
|
12721
|
+
version: "0.1.36",
|
|
12722
12722
|
description: "Kimbho CLI is a terminal-native coding agent for planning, execution, and verification.",
|
|
12723
12723
|
type: "module",
|
|
12724
12724
|
engines: {
|
|
@@ -13771,8 +13771,8 @@ function getErrorMap() {
|
|
|
13771
13771
|
|
|
13772
13772
|
// ../../node_modules/zod/v3/helpers/parseUtil.js
|
|
13773
13773
|
var makeIssue = (params) => {
|
|
13774
|
-
const { data, path:
|
|
13775
|
-
const fullPath = [...
|
|
13774
|
+
const { data, path: path35, errorMaps, issueData } = params;
|
|
13775
|
+
const fullPath = [...path35, ...issueData.path || []];
|
|
13776
13776
|
const fullIssue = {
|
|
13777
13777
|
...issueData,
|
|
13778
13778
|
path: fullPath
|
|
@@ -13888,11 +13888,11 @@ var errorUtil;
|
|
|
13888
13888
|
|
|
13889
13889
|
// ../../node_modules/zod/v3/types.js
|
|
13890
13890
|
var ParseInputLazyPath = class {
|
|
13891
|
-
constructor(parent, value,
|
|
13891
|
+
constructor(parent, value, path35, key) {
|
|
13892
13892
|
this._cachedPath = [];
|
|
13893
13893
|
this.parent = parent;
|
|
13894
13894
|
this.data = value;
|
|
13895
|
-
this._path =
|
|
13895
|
+
this._path = path35;
|
|
13896
13896
|
this._key = key;
|
|
13897
13897
|
}
|
|
13898
13898
|
get path() {
|
|
@@ -26304,10 +26304,10 @@ function assignProp(target, prop, value) {
|
|
|
26304
26304
|
configurable: true
|
|
26305
26305
|
});
|
|
26306
26306
|
}
|
|
26307
|
-
function getElementAtPath(obj,
|
|
26308
|
-
if (!
|
|
26307
|
+
function getElementAtPath(obj, path35) {
|
|
26308
|
+
if (!path35)
|
|
26309
26309
|
return obj;
|
|
26310
|
-
return
|
|
26310
|
+
return path35.reduce((acc, key) => acc?.[key], obj);
|
|
26311
26311
|
}
|
|
26312
26312
|
function promiseAllObject(promisesObj) {
|
|
26313
26313
|
const keys = Object.keys(promisesObj);
|
|
@@ -26627,11 +26627,11 @@ function aborted(x, startIndex = 0) {
|
|
|
26627
26627
|
}
|
|
26628
26628
|
return false;
|
|
26629
26629
|
}
|
|
26630
|
-
function prefixIssues(
|
|
26630
|
+
function prefixIssues(path35, issues) {
|
|
26631
26631
|
return issues.map((iss) => {
|
|
26632
26632
|
var _a;
|
|
26633
26633
|
(_a = iss).path ?? (_a.path = []);
|
|
26634
|
-
iss.path.unshift(
|
|
26634
|
+
iss.path.unshift(path35);
|
|
26635
26635
|
return iss;
|
|
26636
26636
|
});
|
|
26637
26637
|
}
|
|
@@ -41714,7 +41714,7 @@ function formatCliHookIssues(issues) {
|
|
|
41714
41714
|
|
|
41715
41715
|
// src/commands/exec.ts
|
|
41716
41716
|
var import_promises22 = require("node:fs/promises");
|
|
41717
|
-
var
|
|
41717
|
+
var import_node_path23 = __toESM(require("node:path"), 1);
|
|
41718
41718
|
var import_node_process8 = __toESM(require("node:process"), 1);
|
|
41719
41719
|
var import_ajv2 = __toESM(require_ajv(), 1);
|
|
41720
41720
|
|
|
@@ -42420,6 +42420,9 @@ async function resolveAgentSelection(cwd, options) {
|
|
|
42420
42420
|
}
|
|
42421
42421
|
|
|
42422
42422
|
// src/prompt-intent.ts
|
|
42423
|
+
var WORKSPACE_NOUN_PATTERN = /\b(project|repo|repository|codebase|workspace|app|directory|folder|dir)\b/;
|
|
42424
|
+
var WORKSPACE_CONTENT_PATTERN = /\b(files?|contents?|structure|layout|tree|code)\b/;
|
|
42425
|
+
var WORKSPACE_REFERENCE_PATTERN = /\b(current|this|the|local|working)\s+(project|repo|repository|codebase|workspace|app|directory|folder|dir)\b/;
|
|
42423
42426
|
var EXECUTION_PREFIXES = [
|
|
42424
42427
|
"build ",
|
|
42425
42428
|
"create ",
|
|
@@ -42456,7 +42459,13 @@ var CHAT_PREFIXES = [
|
|
|
42456
42459
|
"explain ",
|
|
42457
42460
|
"summarize ",
|
|
42458
42461
|
"review ",
|
|
42459
|
-
"analyze "
|
|
42462
|
+
"analyze ",
|
|
42463
|
+
"tell me ",
|
|
42464
|
+
"describe ",
|
|
42465
|
+
"detail ",
|
|
42466
|
+
"details ",
|
|
42467
|
+
"walk me through ",
|
|
42468
|
+
"help me understand "
|
|
42460
42469
|
];
|
|
42461
42470
|
var PLAN_PREFIXES = [
|
|
42462
42471
|
"plan ",
|
|
@@ -42468,6 +42477,31 @@ var PLAN_PREFIXES = [
|
|
|
42468
42477
|
function looksLikeExecutionRequest(input) {
|
|
42469
42478
|
return /\b(build|create|make|scaffold|implement|fix|refactor|setup|set up|generate|add|change|update|edit|rewrite|restyle|redesign|improve|enhance)\b/.test(input);
|
|
42470
42479
|
}
|
|
42480
|
+
function looksLikeInformationalRequest(input) {
|
|
42481
|
+
if (/\b(tell me|describe|walk me through|help me understand)\b/.test(input)) {
|
|
42482
|
+
return true;
|
|
42483
|
+
}
|
|
42484
|
+
if (/\b(details?|overview|summary|walkthrough|explanation|structure|layout|contents?)\b/.test(input) && (WORKSPACE_NOUN_PATTERN.test(input) || WORKSPACE_CONTENT_PATTERN.test(input))) {
|
|
42485
|
+
return true;
|
|
42486
|
+
}
|
|
42487
|
+
return WORKSPACE_REFERENCE_PATTERN.test(input) && /\b(details?|overview|summary|about|inside|in|contents?|structure|layout)\b/.test(input);
|
|
42488
|
+
}
|
|
42489
|
+
function looksLikeWorkspaceInfoPrompt(input) {
|
|
42490
|
+
const normalized = input.toLowerCase();
|
|
42491
|
+
if (looksLikeInformationalRequest(normalized) && (WORKSPACE_NOUN_PATTERN.test(normalized) || WORKSPACE_CONTENT_PATTERN.test(normalized))) {
|
|
42492
|
+
return true;
|
|
42493
|
+
}
|
|
42494
|
+
if (/\b(analy[sz]e|summari[sz]e|explain|describe|show|list|walk me through|tell me about)\b/.test(normalized) && (WORKSPACE_NOUN_PATTERN.test(normalized) || WORKSPACE_CONTENT_PATTERN.test(normalized))) {
|
|
42495
|
+
return true;
|
|
42496
|
+
}
|
|
42497
|
+
if (/\b(what('?s| is)?\s+in|show me|list)\b/.test(normalized) && /\b(this|the current|current)\s+(directory|folder|workspace|repo|repository|project|dir)\b/.test(normalized)) {
|
|
42498
|
+
return true;
|
|
42499
|
+
}
|
|
42500
|
+
if (/\bfiles?\s+in\s+(this|the current|current)\s+(directory|folder|workspace|repo|repository|project|dir)\b/.test(normalized)) {
|
|
42501
|
+
return true;
|
|
42502
|
+
}
|
|
42503
|
+
return false;
|
|
42504
|
+
}
|
|
42471
42505
|
function stripConversationalLead(input) {
|
|
42472
42506
|
let normalized = input.trim().toLowerCase();
|
|
42473
42507
|
normalized = normalized.replace(/^(hi|hello|hey|yo|sup)\b[!,. ]*/u, "").trim();
|
|
@@ -42495,6 +42529,9 @@ function inferPromptIntent(input) {
|
|
|
42495
42529
|
if (looksLikeExecutionRequest(taskCandidate)) {
|
|
42496
42530
|
return "run";
|
|
42497
42531
|
}
|
|
42532
|
+
if (looksLikeInformationalRequest(taskCandidate)) {
|
|
42533
|
+
return "chat";
|
|
42534
|
+
}
|
|
42498
42535
|
if (normalized.endsWith("?")) {
|
|
42499
42536
|
return "chat";
|
|
42500
42537
|
}
|
|
@@ -42783,10 +42820,265 @@ async function resolveExecutionWorkspace(cwd, goal) {
|
|
|
42783
42820
|
};
|
|
42784
42821
|
}
|
|
42785
42822
|
|
|
42823
|
+
// src/workspace-analysis.ts
|
|
42824
|
+
var import_node_path22 = __toESM(require("node:path"), 1);
|
|
42825
|
+
function buildWorkspaceAnalysisPlan(request, prompt) {
|
|
42826
|
+
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
42827
|
+
return {
|
|
42828
|
+
goal: request.goal,
|
|
42829
|
+
generatedAt,
|
|
42830
|
+
summary: "Read-only multi-agent analysis of the current repository to answer the operator's question with concrete workspace evidence.",
|
|
42831
|
+
repoStrategy: {
|
|
42832
|
+
mode: "existing-repo",
|
|
42833
|
+
reasoning: "This is an analysis-only request about the current workspace, so the agent team should inspect the repo and synthesize findings without editing source files."
|
|
42834
|
+
},
|
|
42835
|
+
assumptions: [
|
|
42836
|
+
"The user wants a grounded explanation of the current repository, not code changes.",
|
|
42837
|
+
"The analysis should stay read-only and avoid modifying product files."
|
|
42838
|
+
],
|
|
42839
|
+
openQuestions: [],
|
|
42840
|
+
milestones: [
|
|
42841
|
+
{
|
|
42842
|
+
id: "m1-repo-survey",
|
|
42843
|
+
title: "Repository Survey",
|
|
42844
|
+
objective: "Inspect the current workspace structure, entrypoints, tooling, and conventions.",
|
|
42845
|
+
tasks: [
|
|
42846
|
+
{
|
|
42847
|
+
id: "t1-repo-analysis",
|
|
42848
|
+
title: "Analyze the current workspace and conventions",
|
|
42849
|
+
description: "Map the repository shape, commands, entrypoints, and constraints before answering the user's question.",
|
|
42850
|
+
type: "analysis",
|
|
42851
|
+
status: "pending",
|
|
42852
|
+
agentRole: "repo-analyst",
|
|
42853
|
+
dependsOn: [],
|
|
42854
|
+
acceptanceCriteria: [
|
|
42855
|
+
"Repository shape and commands are captured.",
|
|
42856
|
+
"Likely entrypoints and major packages are identified."
|
|
42857
|
+
],
|
|
42858
|
+
outputs: [
|
|
42859
|
+
"Repo analysis summary"
|
|
42860
|
+
],
|
|
42861
|
+
filesLikelyTouched: [
|
|
42862
|
+
".",
|
|
42863
|
+
".kimbho/"
|
|
42864
|
+
],
|
|
42865
|
+
riskLevel: "low",
|
|
42866
|
+
sandboxModeOverride: "read-only"
|
|
42867
|
+
},
|
|
42868
|
+
{
|
|
42869
|
+
id: "t2-architecture",
|
|
42870
|
+
title: "Synthesize the architecture and package boundaries",
|
|
42871
|
+
description: "Turn the repository findings into a clear explanation of the system structure and responsibilities.",
|
|
42872
|
+
type: "documentation",
|
|
42873
|
+
status: "pending",
|
|
42874
|
+
agentRole: "planner",
|
|
42875
|
+
dependsOn: [
|
|
42876
|
+
"t1-repo-analysis"
|
|
42877
|
+
],
|
|
42878
|
+
acceptanceCriteria: [
|
|
42879
|
+
"Architecture summary is grounded in repo analysis findings.",
|
|
42880
|
+
"The main packages and responsibilities are explicit."
|
|
42881
|
+
],
|
|
42882
|
+
outputs: [
|
|
42883
|
+
"Architecture brief"
|
|
42884
|
+
],
|
|
42885
|
+
filesLikelyTouched: [
|
|
42886
|
+
".kimbho/"
|
|
42887
|
+
],
|
|
42888
|
+
riskLevel: "low",
|
|
42889
|
+
sandboxModeOverride: "read-only"
|
|
42890
|
+
}
|
|
42891
|
+
]
|
|
42892
|
+
},
|
|
42893
|
+
{
|
|
42894
|
+
id: "m2-answer",
|
|
42895
|
+
title: "Answer",
|
|
42896
|
+
objective: "Review the gathered analysis artifacts and produce the final project explanation.",
|
|
42897
|
+
tasks: [
|
|
42898
|
+
{
|
|
42899
|
+
id: "t3-project-brief",
|
|
42900
|
+
title: "Review the analysis artifacts and prepare the project explanation",
|
|
42901
|
+
description: "Inspect the repo-analysis and architecture artifacts, then summarize the current project in terms that answer the user's question.",
|
|
42902
|
+
type: "documentation",
|
|
42903
|
+
status: "pending",
|
|
42904
|
+
agentRole: "reviewer",
|
|
42905
|
+
dependsOn: [
|
|
42906
|
+
"t1-repo-analysis",
|
|
42907
|
+
"t2-architecture"
|
|
42908
|
+
],
|
|
42909
|
+
acceptanceCriteria: [
|
|
42910
|
+
"The answer addresses the user's question directly.",
|
|
42911
|
+
"The summary is grounded in repository evidence instead of generic assistant chatter."
|
|
42912
|
+
],
|
|
42913
|
+
outputs: [
|
|
42914
|
+
"Project explanation summary"
|
|
42915
|
+
],
|
|
42916
|
+
filesLikelyTouched: [
|
|
42917
|
+
".kimbho/logs/",
|
|
42918
|
+
"kimbho_init.md"
|
|
42919
|
+
],
|
|
42920
|
+
riskLevel: "low",
|
|
42921
|
+
sandboxModeOverride: "read-only",
|
|
42922
|
+
allowedTools: [
|
|
42923
|
+
"file.read",
|
|
42924
|
+
"file.search",
|
|
42925
|
+
"file.list",
|
|
42926
|
+
"repo.index",
|
|
42927
|
+
"repo.query",
|
|
42928
|
+
"git.diff"
|
|
42929
|
+
],
|
|
42930
|
+
deniedTools: [
|
|
42931
|
+
"file.write",
|
|
42932
|
+
"file.patch",
|
|
42933
|
+
"shell.exec"
|
|
42934
|
+
],
|
|
42935
|
+
agentPromptPreamble: [
|
|
42936
|
+
"This is a read-only repository explanation task.",
|
|
42937
|
+
"Do not modify product files, install packages, or run development servers.",
|
|
42938
|
+
`Answer the operator's question: ${prompt}`,
|
|
42939
|
+
"Use the repo-analysis and architecture artifacts plus direct file inspection if needed.",
|
|
42940
|
+
"Finish with a concise but concrete summary of the project, stack, entrypoints, commands, and notable risks or gaps."
|
|
42941
|
+
].join("\n")
|
|
42942
|
+
}
|
|
42943
|
+
]
|
|
42944
|
+
}
|
|
42945
|
+
],
|
|
42946
|
+
verificationChecklist: [
|
|
42947
|
+
"Repo analysis artifacts were captured.",
|
|
42948
|
+
"The architecture summary is grounded in the workspace.",
|
|
42949
|
+
"The final explanation answers the user's question without changing source files."
|
|
42950
|
+
],
|
|
42951
|
+
executionNotes: [
|
|
42952
|
+
"Read-only analysis run triggered directly from a workspace question.",
|
|
42953
|
+
"Prefer repo/file tools and existing memory artifacts over generic assistant responses."
|
|
42954
|
+
]
|
|
42955
|
+
};
|
|
42956
|
+
}
|
|
42957
|
+
async function synthesizeWorkspaceAnalysisAnswer(cwd, prompt, role, snapshot) {
|
|
42958
|
+
const config2 = await loadConfig(cwd);
|
|
42959
|
+
const projectInit = await readMarkdownIfExists(import_node_path22.default.join(cwd, "kimbho_init.md"));
|
|
42960
|
+
const artifactPaths = Array.from(new Set(
|
|
42961
|
+
snapshot.events.flatMap((event) => [
|
|
42962
|
+
...event.artifacts,
|
|
42963
|
+
...event.toolResults.flatMap((toolResult) => toolResult.artifacts)
|
|
42964
|
+
])
|
|
42965
|
+
));
|
|
42966
|
+
const prioritizedArtifacts = artifactPaths.filter((artifactPath) => /repo-analysis|architecture-brief|project-brief|transcript/i.test(import_node_path22.default.basename(artifactPath))).slice(0, 4);
|
|
42967
|
+
const artifactSections = (await Promise.all(
|
|
42968
|
+
prioritizedArtifacts.map(async (artifactPath) => {
|
|
42969
|
+
const content = await readMarkdownIfExists(artifactPath);
|
|
42970
|
+
if (!content) {
|
|
42971
|
+
return null;
|
|
42972
|
+
}
|
|
42973
|
+
return `Artifact: ${artifactPath}
|
|
42974
|
+
${content.slice(0, 4e3)}`;
|
|
42975
|
+
})
|
|
42976
|
+
)).filter((section) => Boolean(section));
|
|
42977
|
+
if (!config2) {
|
|
42978
|
+
return [
|
|
42979
|
+
"Repository analysis completed.",
|
|
42980
|
+
projectInit ? `Current workspace summary:
|
|
42981
|
+
${projectInit.slice(0, 4e3)}` : "Project summary is available in the session artifacts, but no configured model was available to synthesize a narrative answer."
|
|
42982
|
+
].join("\n\n");
|
|
42983
|
+
}
|
|
42984
|
+
const resolver = new BrainResolver(config2, createDefaultBrainProviderRegistry(cwd));
|
|
42985
|
+
const brain = await resolver.resolve(role);
|
|
42986
|
+
const result = await brain.client.generateText({
|
|
42987
|
+
model: brain.model,
|
|
42988
|
+
systemPrompt: [
|
|
42989
|
+
brain.settings.promptPreamble,
|
|
42990
|
+
"You are summarizing the current repository after a read-only multi-agent analysis session.",
|
|
42991
|
+
"Answer the user's question directly and concretely from the provided workspace evidence.",
|
|
42992
|
+
"Do not greet, do not speak generically about your own capabilities, and do not invent repository details.",
|
|
42993
|
+
"Prefer a crisp project overview with stack, structure, key entrypoints, commands, and notable risks or gaps."
|
|
42994
|
+
].filter(Boolean).join("\n\n"),
|
|
42995
|
+
userPrompt: [
|
|
42996
|
+
`User question: ${prompt}`,
|
|
42997
|
+
projectInit ? `Workspace overview:
|
|
42998
|
+
${projectInit.slice(0, 6e3)}` : null,
|
|
42999
|
+
artifactSections.length > 0 ? artifactSections.join("\n\n") : "No detailed analysis artifacts were available; answer from the workspace overview only."
|
|
43000
|
+
].filter((value) => Boolean(value)).join("\n\n"),
|
|
43001
|
+
...typeof brain.settings.temperature === "number" ? {
|
|
43002
|
+
temperature: brain.settings.temperature
|
|
43003
|
+
} : {},
|
|
43004
|
+
...typeof brain.settings.maxTokens === "number" ? {
|
|
43005
|
+
maxTokens: brain.settings.maxTokens
|
|
43006
|
+
} : {}
|
|
43007
|
+
});
|
|
43008
|
+
return result.text;
|
|
43009
|
+
}
|
|
43010
|
+
async function executeWorkspaceAnalysis(cwd, prompt, options) {
|
|
43011
|
+
const prepared = await preparePlanningRequest({
|
|
43012
|
+
goal: `Analyze the current repository and answer the user's question: ${prompt}`,
|
|
43013
|
+
mode: "run",
|
|
43014
|
+
cwd,
|
|
43015
|
+
workspaceState: "existing",
|
|
43016
|
+
constraints: [
|
|
43017
|
+
"Read-only repository analysis only.",
|
|
43018
|
+
"Do not modify source files, install packages, or start development servers.",
|
|
43019
|
+
"Use multiple agents to inspect the workspace and synthesize the answer when helpful."
|
|
43020
|
+
],
|
|
43021
|
+
...options.agentSelection ? {
|
|
43022
|
+
agentSelection: options.agentSelection
|
|
43023
|
+
} : {}
|
|
43024
|
+
});
|
|
43025
|
+
const request = prepared.request;
|
|
43026
|
+
const plan = buildWorkspaceAnalysisPlan(request, prompt);
|
|
43027
|
+
const planPath = options.ephemeral ? null : await savePlan(plan, request.cwd);
|
|
43028
|
+
const orchestrator = new ExecutionOrchestrator();
|
|
43029
|
+
const envelope = orchestrator.buildEnvelope(request, plan, options.sessionId);
|
|
43030
|
+
const initialSnapshot = orchestrator.createSessionSnapshot(envelope);
|
|
43031
|
+
const progressEvents = [];
|
|
43032
|
+
const snapshot = await orchestrator.continueSession(initialSnapshot, {
|
|
43033
|
+
maxAutoTasks: options.maxAutoTasks,
|
|
43034
|
+
maxAgentSteps: options.maxAgentSteps,
|
|
43035
|
+
maxRepairAttempts: options.maxRepairAttempts,
|
|
43036
|
+
...typeof options.maxToolCalls === "number" ? {
|
|
43037
|
+
maxToolCalls: options.maxToolCalls
|
|
43038
|
+
} : {},
|
|
43039
|
+
...typeof options.maxModelCalls === "number" ? {
|
|
43040
|
+
maxModelCalls: options.maxModelCalls
|
|
43041
|
+
} : {},
|
|
43042
|
+
...typeof options.maxInputTokens === "number" ? {
|
|
43043
|
+
maxInputTokens: options.maxInputTokens
|
|
43044
|
+
} : {},
|
|
43045
|
+
...typeof options.maxOutputTokens === "number" ? {
|
|
43046
|
+
maxOutputTokens: options.maxOutputTokens
|
|
43047
|
+
} : {},
|
|
43048
|
+
onProgress: async (event) => {
|
|
43049
|
+
progressEvents.push(event);
|
|
43050
|
+
await options.onProgress?.(event);
|
|
43051
|
+
}
|
|
43052
|
+
});
|
|
43053
|
+
const sessionPath = options.ephemeral ? null : await saveSession(snapshot, request.cwd);
|
|
43054
|
+
const answer = await synthesizeWorkspaceAnalysisAnswer(
|
|
43055
|
+
request.cwd,
|
|
43056
|
+
prompt,
|
|
43057
|
+
options.answerRole ?? "coder",
|
|
43058
|
+
snapshot
|
|
43059
|
+
);
|
|
43060
|
+
return {
|
|
43061
|
+
answer,
|
|
43062
|
+
plan,
|
|
43063
|
+
planPath,
|
|
43064
|
+
preparedNotes: prepared.notes,
|
|
43065
|
+
progressEvents,
|
|
43066
|
+
request,
|
|
43067
|
+
sessionPath,
|
|
43068
|
+
snapshot
|
|
43069
|
+
};
|
|
43070
|
+
}
|
|
43071
|
+
|
|
42786
43072
|
// src/commands/exec.ts
|
|
42787
43073
|
function resolveSkillPromptSource(input) {
|
|
42788
43074
|
return input.prompt || input.messages.at(-1)?.content || "";
|
|
42789
43075
|
}
|
|
43076
|
+
function shouldRouteToWorkspaceAnalysis(input, explicitIntent) {
|
|
43077
|
+
if (explicitIntent) {
|
|
43078
|
+
return false;
|
|
43079
|
+
}
|
|
43080
|
+
return looksLikeWorkspaceInfoPrompt(resolveSkillPromptSource(input));
|
|
43081
|
+
}
|
|
42790
43082
|
var IMAGE_EXTENSIONS = /* @__PURE__ */ new Map([
|
|
42791
43083
|
[".png", "image/png"],
|
|
42792
43084
|
[".jpg", "image/jpeg"],
|
|
@@ -42881,14 +43173,14 @@ async function pathExists4(filePath) {
|
|
|
42881
43173
|
}
|
|
42882
43174
|
}
|
|
42883
43175
|
function inferMimeType(name, fallback = "application/octet-stream") {
|
|
42884
|
-
const extension =
|
|
43176
|
+
const extension = import_node_path23.default.extname(name).toLowerCase();
|
|
42885
43177
|
return IMAGE_EXTENSIONS.get(extension) ?? TEXT_EXTENSIONS.get(extension) ?? fallback;
|
|
42886
43178
|
}
|
|
42887
43179
|
function isLikelyText(name, mimeType, buffer) {
|
|
42888
43180
|
if (mimeType.startsWith("text/") || mimeType === "application/json" || mimeType === "application/toml" || mimeType === "application/yaml" || mimeType === "application/xml") {
|
|
42889
43181
|
return true;
|
|
42890
43182
|
}
|
|
42891
|
-
if (TEXT_EXTENSIONS.has(
|
|
43183
|
+
if (TEXT_EXTENSIONS.has(import_node_path23.default.extname(name).toLowerCase())) {
|
|
42892
43184
|
return true;
|
|
42893
43185
|
}
|
|
42894
43186
|
return !buffer.includes(0);
|
|
@@ -42911,7 +43203,7 @@ async function fetchAttachment(value) {
|
|
|
42911
43203
|
throw new Error(`Failed to download attachment "${value}": ${response.status} ${response.statusText}`);
|
|
42912
43204
|
}
|
|
42913
43205
|
const url = new URL(value);
|
|
42914
|
-
const name2 =
|
|
43206
|
+
const name2 = import_node_path23.default.basename(url.pathname) || "attachment";
|
|
42915
43207
|
const mimeType = response.headers.get("content-type")?.split(";")[0]?.trim() ?? inferMimeType(name2);
|
|
42916
43208
|
const buffer2 = Buffer.from(await response.arrayBuffer());
|
|
42917
43209
|
return {
|
|
@@ -42920,9 +43212,9 @@ async function fetchAttachment(value) {
|
|
|
42920
43212
|
buffer: buffer2
|
|
42921
43213
|
};
|
|
42922
43214
|
}
|
|
42923
|
-
const filePath =
|
|
43215
|
+
const filePath = import_node_path23.default.resolve(import_node_process8.default.cwd(), value);
|
|
42924
43216
|
const buffer = await (0, import_promises22.readFile)(filePath);
|
|
42925
|
-
const name =
|
|
43217
|
+
const name = import_node_path23.default.basename(filePath);
|
|
42926
43218
|
return {
|
|
42927
43219
|
name,
|
|
42928
43220
|
mimeType: inferMimeType(name),
|
|
@@ -43119,7 +43411,7 @@ async function resolveJsonSchemaInput(cwd, schemaInput) {
|
|
|
43119
43411
|
if (!schemaInput) {
|
|
43120
43412
|
return null;
|
|
43121
43413
|
}
|
|
43122
|
-
const candidatePath =
|
|
43414
|
+
const candidatePath = import_node_path23.default.resolve(cwd, schemaInput);
|
|
43123
43415
|
if (await pathExists4(candidatePath)) {
|
|
43124
43416
|
const raw = await (0, import_promises22.readFile)(candidatePath, "utf8");
|
|
43125
43417
|
return JSON.parse(raw);
|
|
@@ -43148,7 +43440,7 @@ async function maybeWriteOutputFile(outputFile, format, payload, textOutput) {
|
|
|
43148
43440
|
if (!outputFile) {
|
|
43149
43441
|
return;
|
|
43150
43442
|
}
|
|
43151
|
-
const filePath =
|
|
43443
|
+
const filePath = import_node_path23.default.resolve(import_node_process8.default.cwd(), outputFile);
|
|
43152
43444
|
const serialized = format === "text" ? textOutput : `${renderJson(payload)}
|
|
43153
43445
|
`;
|
|
43154
43446
|
await (0, import_promises22.writeFile)(filePath, serialized, "utf8");
|
|
@@ -43376,8 +43668,104 @@ async function executeRunPrompt(cwd, input, format, options) {
|
|
|
43376
43668
|
textOutput
|
|
43377
43669
|
};
|
|
43378
43670
|
}
|
|
43671
|
+
async function executeWorkspaceAnalysisPrompt(cwd, input, format, options) {
|
|
43672
|
+
const question = enrichPromptWithAttachments(resolveSkillPromptSource(input), input.attachments);
|
|
43673
|
+
const result = await executeWorkspaceAnalysis(cwd, question, {
|
|
43674
|
+
answerRole: "coder",
|
|
43675
|
+
ephemeral: options.ephemeral,
|
|
43676
|
+
maxAutoTasks: options.maxAutoTasks,
|
|
43677
|
+
maxAgentSteps: options.maxAgentSteps,
|
|
43678
|
+
maxRepairAttempts: options.maxRepairAttempts,
|
|
43679
|
+
...typeof options.maxToolCalls === "number" ? {
|
|
43680
|
+
maxToolCalls: options.maxToolCalls
|
|
43681
|
+
} : {},
|
|
43682
|
+
...typeof options.maxModelCalls === "number" ? {
|
|
43683
|
+
maxModelCalls: options.maxModelCalls
|
|
43684
|
+
} : {},
|
|
43685
|
+
...typeof options.maxInputTokens === "number" ? {
|
|
43686
|
+
maxInputTokens: options.maxInputTokens
|
|
43687
|
+
} : {},
|
|
43688
|
+
...typeof options.maxOutputTokens === "number" ? {
|
|
43689
|
+
maxOutputTokens: options.maxOutputTokens
|
|
43690
|
+
} : {},
|
|
43691
|
+
...options.sessionId ? {
|
|
43692
|
+
sessionId: options.sessionId
|
|
43693
|
+
} : {},
|
|
43694
|
+
...options.agentSelection ? {
|
|
43695
|
+
agentSelection: options.agentSelection
|
|
43696
|
+
} : {},
|
|
43697
|
+
...format === "stream-json" ? {
|
|
43698
|
+
onProgress: async (event) => {
|
|
43699
|
+
printStreamEvent({
|
|
43700
|
+
type: "progress",
|
|
43701
|
+
event
|
|
43702
|
+
});
|
|
43703
|
+
}
|
|
43704
|
+
} : {}
|
|
43705
|
+
});
|
|
43706
|
+
const textOutput = [
|
|
43707
|
+
...result.preparedNotes,
|
|
43708
|
+
...result.preparedNotes.length > 0 ? [""] : [],
|
|
43709
|
+
renderPlan(result.plan),
|
|
43710
|
+
"",
|
|
43711
|
+
renderSession(result.snapshot),
|
|
43712
|
+
...result.planPath ? ["", `Saved plan: ${result.planPath}`] : [],
|
|
43713
|
+
...result.sessionPath ? [`Saved session: ${result.sessionPath}`] : [],
|
|
43714
|
+
...result.request.cwd !== cwd ? [`Continue in: cd ${result.request.cwd}`] : [],
|
|
43715
|
+
"",
|
|
43716
|
+
"[analysis answer]",
|
|
43717
|
+
result.answer
|
|
43718
|
+
].join("\n");
|
|
43719
|
+
const payload = {
|
|
43720
|
+
mode: "workspace-analysis",
|
|
43721
|
+
prompt: question,
|
|
43722
|
+
answer: result.answer,
|
|
43723
|
+
plan: result.plan,
|
|
43724
|
+
session: result.snapshot,
|
|
43725
|
+
planningNotes: result.preparedNotes,
|
|
43726
|
+
attachments: input.attachments.map((attachment) => ({
|
|
43727
|
+
kind: attachment.kind,
|
|
43728
|
+
name: attachment.name,
|
|
43729
|
+
mimeType: attachment.mimeType
|
|
43730
|
+
})),
|
|
43731
|
+
planPath: result.planPath,
|
|
43732
|
+
sessionPath: result.sessionPath,
|
|
43733
|
+
progressEvents: result.progressEvents
|
|
43734
|
+
};
|
|
43735
|
+
return {
|
|
43736
|
+
payload,
|
|
43737
|
+
lastMessage: result.answer,
|
|
43738
|
+
textOutput
|
|
43739
|
+
};
|
|
43740
|
+
}
|
|
43379
43741
|
async function executePromptByIntent(cwd, input, options = {}) {
|
|
43380
|
-
|
|
43742
|
+
if (shouldRouteToWorkspaceAnalysis(input, options.intent)) {
|
|
43743
|
+
return executeWorkspaceAnalysisPrompt(cwd, input, options.outputFormat ?? "json", {
|
|
43744
|
+
ephemeral: options.ephemeral ?? false,
|
|
43745
|
+
maxAutoTasks: options.maxAutoTasks ?? 4,
|
|
43746
|
+
maxAgentSteps: options.maxAgentSteps ?? 8,
|
|
43747
|
+
maxRepairAttempts: options.maxRepairAttempts ?? 2,
|
|
43748
|
+
...typeof options.maxToolCalls === "number" ? {
|
|
43749
|
+
maxToolCalls: options.maxToolCalls
|
|
43750
|
+
} : {},
|
|
43751
|
+
...typeof options.maxModelCalls === "number" ? {
|
|
43752
|
+
maxModelCalls: options.maxModelCalls
|
|
43753
|
+
} : {},
|
|
43754
|
+
...typeof options.maxInputTokens === "number" ? {
|
|
43755
|
+
maxInputTokens: options.maxInputTokens
|
|
43756
|
+
} : {},
|
|
43757
|
+
...typeof options.maxOutputTokens === "number" ? {
|
|
43758
|
+
maxOutputTokens: options.maxOutputTokens
|
|
43759
|
+
} : {},
|
|
43760
|
+
...options.sessionId ? {
|
|
43761
|
+
sessionId: options.sessionId
|
|
43762
|
+
} : {},
|
|
43763
|
+
...options.agentSelection ? {
|
|
43764
|
+
agentSelection: options.agentSelection
|
|
43765
|
+
} : {}
|
|
43766
|
+
});
|
|
43767
|
+
}
|
|
43768
|
+
const intent = options.intent ?? inferPromptIntent(resolveSkillPromptSource(input));
|
|
43381
43769
|
if (intent === "chat") {
|
|
43382
43770
|
return executeChatPrompt(cwd, input);
|
|
43383
43771
|
}
|
|
@@ -43435,12 +43823,9 @@ function createExecCommand() {
|
|
|
43435
43823
|
file: options.file,
|
|
43436
43824
|
image: options.image
|
|
43437
43825
|
});
|
|
43438
|
-
const intent = inferPromptIntent(input.prompt || input.messages.at(-1)?.content || "");
|
|
43439
43826
|
const schema = await resolveJsonSchemaInput(cwd, options.jsonSchema);
|
|
43440
|
-
const result =
|
|
43441
|
-
|
|
43442
|
-
agentSelection
|
|
43443
|
-
}) : await executeRunPrompt(cwd, input, format, {
|
|
43827
|
+
const result = await executePromptByIntent(cwd, input, {
|
|
43828
|
+
outputFormat: format,
|
|
43444
43829
|
sessionId: options.sessionId,
|
|
43445
43830
|
ephemeral: options.ephemeral,
|
|
43446
43831
|
maxAutoTasks: options.maxAutoTasks,
|
|
@@ -43481,7 +43866,7 @@ function createExecCommand() {
|
|
|
43481
43866
|
|
|
43482
43867
|
// src/review-service.ts
|
|
43483
43868
|
var import_promises23 = require("node:fs/promises");
|
|
43484
|
-
var
|
|
43869
|
+
var import_node_path24 = __toESM(require("node:path"), 1);
|
|
43485
43870
|
function summarizeChangedFiles2(diff) {
|
|
43486
43871
|
const files = /* @__PURE__ */ new Set();
|
|
43487
43872
|
for (const line of diff.split("\n")) {
|
|
@@ -43550,20 +43935,20 @@ async function reviewWorkspace(cwd, options = {}) {
|
|
|
43550
43935
|
toolId: "file.read",
|
|
43551
43936
|
success: true,
|
|
43552
43937
|
summary: `Loaded review patch ${options.patchPath}.`,
|
|
43553
|
-
stdout: `patch:${
|
|
43938
|
+
stdout: `patch:${import_node_path24.default.resolve(cwd, options.patchPath)}`,
|
|
43554
43939
|
stderr: "",
|
|
43555
43940
|
artifacts: [
|
|
43556
|
-
|
|
43941
|
+
import_node_path24.default.resolve(cwd, options.patchPath)
|
|
43557
43942
|
]
|
|
43558
43943
|
} : await runtime.run("git.status", {}, { cwd });
|
|
43559
43944
|
const diff = options.patchPath ? {
|
|
43560
43945
|
toolId: "file.read",
|
|
43561
43946
|
success: true,
|
|
43562
43947
|
summary: `Loaded review patch ${options.patchPath}.`,
|
|
43563
|
-
stdout: await (0, import_promises23.readFile)(
|
|
43948
|
+
stdout: await (0, import_promises23.readFile)(import_node_path24.default.resolve(cwd, options.patchPath), "utf8"),
|
|
43564
43949
|
stderr: "",
|
|
43565
43950
|
artifacts: [
|
|
43566
|
-
|
|
43951
|
+
import_node_path24.default.resolve(cwd, options.patchPath)
|
|
43567
43952
|
]
|
|
43568
43953
|
} : await runtime.run("git.diff", {}, { cwd });
|
|
43569
43954
|
const repoIndex = await runtime.run("repo.index", {}, { cwd }).catch(() => null);
|
|
@@ -43630,7 +44015,7 @@ ${diff.stdout}`
|
|
|
43630
44015
|
}
|
|
43631
44016
|
}
|
|
43632
44017
|
await ensureKimbhoDir(cwd);
|
|
43633
|
-
const artifactPath =
|
|
44018
|
+
const artifactPath = import_node_path24.default.join(resolveKimbhoDir(cwd), "logs", `review-${Date.now()}.md`);
|
|
43634
44019
|
await (0, import_promises23.writeFile)(artifactPath, [
|
|
43635
44020
|
`# Review`,
|
|
43636
44021
|
``,
|
|
@@ -45224,7 +45609,7 @@ function createChromeCommand() {
|
|
|
45224
45609
|
|
|
45225
45610
|
// src/commands/cloud.ts
|
|
45226
45611
|
var import_promises24 = require("node:fs/promises");
|
|
45227
|
-
var
|
|
45612
|
+
var import_node_path25 = __toESM(require("node:path"), 1);
|
|
45228
45613
|
var import_node_process12 = __toESM(require("node:process"), 1);
|
|
45229
45614
|
var import_node_child_process8 = require("node:child_process");
|
|
45230
45615
|
function parseCount2(value) {
|
|
@@ -45296,15 +45681,15 @@ async function resolveSession(sessionId, last = false) {
|
|
|
45296
45681
|
return loadSessionById(sessionId, import_node_process12.default.cwd());
|
|
45297
45682
|
}
|
|
45298
45683
|
async function ensureCloudPatchDir(cwd) {
|
|
45299
|
-
const outputDir =
|
|
45684
|
+
const outputDir = import_node_path25.default.join(resolveKimbhoDir(cwd), "cloud");
|
|
45300
45685
|
await (0, import_promises24.mkdir)(outputDir, {
|
|
45301
45686
|
recursive: true
|
|
45302
45687
|
});
|
|
45303
45688
|
return outputDir;
|
|
45304
45689
|
}
|
|
45305
45690
|
async function writePatchArtifact(cwd, taskId, patchArtifact, output) {
|
|
45306
|
-
const outputPath = output ?
|
|
45307
|
-
await (0, import_promises24.mkdir)(
|
|
45691
|
+
const outputPath = output ? import_node_path25.default.resolve(cwd, output) : import_node_path25.default.join(await ensureCloudPatchDir(cwd), patchArtifact.fileName ?? `${taskId}.patch`);
|
|
45692
|
+
await (0, import_promises24.mkdir)(import_node_path25.default.dirname(outputPath), {
|
|
45308
45693
|
recursive: true
|
|
45309
45694
|
});
|
|
45310
45695
|
await (0, import_promises24.writeFile)(outputPath, patchArtifact.content, "utf8");
|
|
@@ -45453,7 +45838,7 @@ function createCloudCommand() {
|
|
|
45453
45838
|
}
|
|
45454
45839
|
|
|
45455
45840
|
// src/commands/compat.ts
|
|
45456
|
-
var
|
|
45841
|
+
var import_node_path26 = __toESM(require("node:path"), 1);
|
|
45457
45842
|
var import_node_process13 = __toESM(require("node:process"), 1);
|
|
45458
45843
|
|
|
45459
45844
|
// src/plugin-commands.ts
|
|
@@ -45816,7 +46201,7 @@ function createPluginCommand() {
|
|
|
45816
46201
|
const cwd = import_node_process13.default.cwd();
|
|
45817
46202
|
const { direct, resolved } = await loadScopedConfig(scope, cwd);
|
|
45818
46203
|
const current = baseConfig(direct, resolved);
|
|
45819
|
-
const normalized =
|
|
46204
|
+
const normalized = import_node_path26.default.resolve(cwd, directory);
|
|
45820
46205
|
const outputPath = await saveScopedConfig(scope, cwd, {
|
|
45821
46206
|
...current,
|
|
45822
46207
|
pluginDirectories: Array.from(/* @__PURE__ */ new Set([
|
|
@@ -45831,7 +46216,7 @@ function createPluginCommand() {
|
|
|
45831
46216
|
const cwd = import_node_process13.default.cwd();
|
|
45832
46217
|
const { direct, resolved } = await loadScopedConfig(scope, cwd);
|
|
45833
46218
|
const current = baseConfig(direct, resolved);
|
|
45834
|
-
const normalized =
|
|
46219
|
+
const normalized = import_node_path26.default.resolve(cwd, directory);
|
|
45835
46220
|
const outputPath = await saveScopedConfig(scope, cwd, {
|
|
45836
46221
|
...current,
|
|
45837
46222
|
pluginDirectories: current.pluginDirectories.filter((entry) => entry !== directory && entry !== normalized)
|
|
@@ -46008,11 +46393,11 @@ function createSandboxCommand() {
|
|
|
46008
46393
|
var import_node_process14 = __toESM(require("node:process"), 1);
|
|
46009
46394
|
|
|
46010
46395
|
// src/memory.ts
|
|
46011
|
-
var
|
|
46396
|
+
var import_node_path28 = __toESM(require("node:path"), 1);
|
|
46012
46397
|
|
|
46013
46398
|
// src/project-init.ts
|
|
46014
46399
|
var import_promises25 = require("node:fs/promises");
|
|
46015
|
-
var
|
|
46400
|
+
var import_node_path27 = __toESM(require("node:path"), 1);
|
|
46016
46401
|
var import_node_child_process9 = require("node:child_process");
|
|
46017
46402
|
var import_node_util = require("node:util");
|
|
46018
46403
|
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process9.execFile);
|
|
@@ -46025,16 +46410,16 @@ async function pathExists5(filePath) {
|
|
|
46025
46410
|
}
|
|
46026
46411
|
}
|
|
46027
46412
|
async function detectPackageManager(cwd) {
|
|
46028
|
-
if (await pathExists5(
|
|
46413
|
+
if (await pathExists5(import_node_path27.default.join(cwd, "pnpm-lock.yaml"))) {
|
|
46029
46414
|
return "pnpm";
|
|
46030
46415
|
}
|
|
46031
|
-
if (await pathExists5(
|
|
46416
|
+
if (await pathExists5(import_node_path27.default.join(cwd, "yarn.lock"))) {
|
|
46032
46417
|
return "yarn";
|
|
46033
46418
|
}
|
|
46034
|
-
if (await pathExists5(
|
|
46419
|
+
if (await pathExists5(import_node_path27.default.join(cwd, "bun.lockb")) || await pathExists5(import_node_path27.default.join(cwd, "bun.lock"))) {
|
|
46035
46420
|
return "bun";
|
|
46036
46421
|
}
|
|
46037
|
-
if (await pathExists5(
|
|
46422
|
+
if (await pathExists5(import_node_path27.default.join(cwd, "package-lock.json"))) {
|
|
46038
46423
|
return "npm";
|
|
46039
46424
|
}
|
|
46040
46425
|
return "npm";
|
|
@@ -46178,8 +46563,8 @@ async function generateProjectInitFile(cwd, outputFileName = "kimbho_init.md") {
|
|
|
46178
46563
|
const entrypoints = inferPrimaryEntrypoints(index);
|
|
46179
46564
|
const verificationCommands = inferVerificationCommands(rootPackage, packageManager);
|
|
46180
46565
|
const git = await captureGitSnapshot(cwd);
|
|
46181
|
-
const packageJson = await readJsonFile2(
|
|
46182
|
-
const outputPath =
|
|
46566
|
+
const packageJson = await readJsonFile2(import_node_path27.default.join(cwd, "package.json"));
|
|
46567
|
+
const outputPath = import_node_path27.default.join(cwd, outputFileName);
|
|
46183
46568
|
const summaryLines = [
|
|
46184
46569
|
`- workspace: \`${cwd}\``,
|
|
46185
46570
|
`- generated: ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
@@ -46240,14 +46625,14 @@ async function generateProjectInitFile(cwd, outputFileName = "kimbho_init.md") {
|
|
|
46240
46625
|
renderSection("Schemas", schemaLines),
|
|
46241
46626
|
renderSection("Key Symbols", symbolLines),
|
|
46242
46627
|
renderSection("Agent Guidance", guidanceLines),
|
|
46243
|
-
`Repo index artifact: \`${
|
|
46628
|
+
`Repo index artifact: \`${import_node_path27.default.relative(cwd, artifactPath) || artifactPath}\``,
|
|
46244
46629
|
""
|
|
46245
46630
|
].join("\n");
|
|
46246
46631
|
await (0, import_promises25.writeFile)(outputPath, content, "utf8");
|
|
46247
46632
|
return {
|
|
46248
46633
|
outputPath,
|
|
46249
46634
|
indexArtifactPath: artifactPath,
|
|
46250
|
-
summary: `Generated ${outputFileName} with indexed project context for ${
|
|
46635
|
+
summary: `Generated ${outputFileName} with indexed project context for ${import_node_path27.default.basename(cwd)}.`,
|
|
46251
46636
|
purpose,
|
|
46252
46637
|
frameworks,
|
|
46253
46638
|
entrypoints,
|
|
@@ -46268,7 +46653,7 @@ function renderProjectMemory(initFilePath) {
|
|
|
46268
46653
|
"",
|
|
46269
46654
|
"## Canonical References",
|
|
46270
46655
|
"",
|
|
46271
|
-
`- bootstrap: \`${
|
|
46656
|
+
`- bootstrap: \`${import_node_path28.default.basename(initFilePath)}\``,
|
|
46272
46657
|
"- read the bootstrap file before large changes",
|
|
46273
46658
|
"- record important repo-specific rules here so future runs do not need to rediscover them",
|
|
46274
46659
|
"",
|
|
@@ -46312,7 +46697,7 @@ async function refreshMemoryFiles(cwd) {
|
|
|
46312
46697
|
initFilePath: init.outputPath,
|
|
46313
46698
|
projectMemoryPath,
|
|
46314
46699
|
userMemoryPath,
|
|
46315
|
-
summary: `Refreshed project bootstrap and memory files for ${
|
|
46700
|
+
summary: `Refreshed project bootstrap and memory files for ${import_node_path28.default.basename(cwd)}.`,
|
|
46316
46701
|
purpose: init.purpose,
|
|
46317
46702
|
frameworks: init.frameworks,
|
|
46318
46703
|
entrypoints: init.entrypoints,
|
|
@@ -46333,7 +46718,7 @@ async function appendMemoryNote(cwd, scope, text, agentId) {
|
|
|
46333
46718
|
throw new Error("Agent memory updates require an agent id.");
|
|
46334
46719
|
}
|
|
46335
46720
|
return appendMarkdownSection(
|
|
46336
|
-
|
|
46721
|
+
import_node_path28.default.join(resolveAgentMemoryDir(cwd), `${agentId}.md`),
|
|
46337
46722
|
"Note",
|
|
46338
46723
|
text
|
|
46339
46724
|
);
|
|
@@ -46343,7 +46728,7 @@ async function appendMemoryNote(cwd, scope, text, agentId) {
|
|
|
46343
46728
|
async function listMemoryPaths(cwd) {
|
|
46344
46729
|
await ensureMemoryDirs(cwd);
|
|
46345
46730
|
return {
|
|
46346
|
-
initFilePath:
|
|
46731
|
+
initFilePath: import_node_path28.default.join(cwd, "kimbho_init.md"),
|
|
46347
46732
|
projectMemoryPath: resolveProjectMemoryPath(cwd),
|
|
46348
46733
|
userMemoryPath: resolveUserMemoryPath(),
|
|
46349
46734
|
adaptiveProjectMemoryPath: resolveAdaptiveProjectMemoryPath(cwd),
|
|
@@ -46705,7 +47090,7 @@ function createDoctorCommand() {
|
|
|
46705
47090
|
});
|
|
46706
47091
|
}
|
|
46707
47092
|
|
|
46708
|
-
// src/commands/
|
|
47093
|
+
// src/commands/fix.ts
|
|
46709
47094
|
var import_node_process17 = __toESM(require("node:process"), 1);
|
|
46710
47095
|
function parseCount3(value) {
|
|
46711
47096
|
const parsed = Number(value);
|
|
@@ -46714,6 +47099,111 @@ function parseCount3(value) {
|
|
|
46714
47099
|
}
|
|
46715
47100
|
return parsed;
|
|
46716
47101
|
}
|
|
47102
|
+
function buildFixPrompt(issue2, review) {
|
|
47103
|
+
const lines = [
|
|
47104
|
+
issue2?.trim() ? `Fix request: ${issue2.trim()}` : "Fix the current repository issue.",
|
|
47105
|
+
"Diagnose the failing behavior first, identify the root cause, implement the minimum safe fix, and verify the result before finishing."
|
|
47106
|
+
];
|
|
47107
|
+
if (!review) {
|
|
47108
|
+
return lines.join("\n\n");
|
|
47109
|
+
}
|
|
47110
|
+
lines.push(
|
|
47111
|
+
"Use the current repository state and review context below as additional evidence.",
|
|
47112
|
+
[
|
|
47113
|
+
"Review context:",
|
|
47114
|
+
`- source: ${review.source}`,
|
|
47115
|
+
`- risk: ${review.riskLevel}`,
|
|
47116
|
+
`- changed files: ${review.changedFiles.length > 0 ? review.changedFiles.join(", ") : "none recorded"}`,
|
|
47117
|
+
`- summary: ${review.summary}`,
|
|
47118
|
+
...review.findings.length > 0 ? review.findings.slice(0, 5).map((finding) => `- finding: [${finding.severity}] ${finding.title}${finding.file ? ` (${finding.file})` : ""} :: ${finding.detail}`) : [
|
|
47119
|
+
"- findings: none recorded"
|
|
47120
|
+
],
|
|
47121
|
+
...review.missingVerification.length > 0 ? review.missingVerification.map((item) => `- missing verification: ${item}`) : [
|
|
47122
|
+
"- missing verification: none recorded"
|
|
47123
|
+
],
|
|
47124
|
+
`- review artifact: ${review.artifactPath}`
|
|
47125
|
+
].join("\n")
|
|
47126
|
+
);
|
|
47127
|
+
return lines.join("\n\n");
|
|
47128
|
+
}
|
|
47129
|
+
function renderFixTextOutput(input, result, review) {
|
|
47130
|
+
const lines = [
|
|
47131
|
+
`Goal: ${input.prompt}`
|
|
47132
|
+
];
|
|
47133
|
+
if (review) {
|
|
47134
|
+
lines.push(`Diagnostic review: ${review.artifactPath}`);
|
|
47135
|
+
lines.push(`Risk: ${review.riskLevel}`);
|
|
47136
|
+
lines.push("");
|
|
47137
|
+
}
|
|
47138
|
+
lines.push(result.textOutput);
|
|
47139
|
+
return lines.join("\n");
|
|
47140
|
+
}
|
|
47141
|
+
function createFixCommand() {
|
|
47142
|
+
return new Command("fix").description("Diagnose the current repository issue, implement the minimum safe fix, and verify the result.").argument("[issue]", "Optional issue description or failure symptom").option("--json", "Print the fix payload as JSON", false).option("--patch <path>", "Use a patch file as additional diagnostic context").option("--agent <id>", "Prefer one custom or plugin agent id for this invocation").option("--agents <jsonOrPath>", "Inline agent definitions as JSON or a path to a JSON file").option("--session-id <id>", "Use an explicit session id for the repair run").option("--ephemeral", "Do not persist plans or sessions for this invocation", false).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount3, 4).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount3, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount3, 2).option("--max-tool-calls <count>", "Maximum tool calls per autonomous task", parseCount3).option("--max-model-calls <count>", "Maximum model calls per autonomous task", parseCount3).option("--max-input-tokens <count>", "Maximum input tokens per autonomous task", parseCount3).option("--max-output-tokens <count>", "Maximum output tokens per autonomous task", parseCount3).action(async (issue2, options) => {
|
|
47143
|
+
const cwd = import_node_process17.default.cwd();
|
|
47144
|
+
const agentSelection = await resolveAgentSelection(cwd, {
|
|
47145
|
+
agent: options.agent,
|
|
47146
|
+
agents: options.agents
|
|
47147
|
+
});
|
|
47148
|
+
const review = await reviewWorkspace(cwd, {
|
|
47149
|
+
patchPath: options.patch
|
|
47150
|
+
}).catch(() => null);
|
|
47151
|
+
const input = {
|
|
47152
|
+
prompt: buildFixPrompt(issue2, review),
|
|
47153
|
+
messages: [],
|
|
47154
|
+
attachments: []
|
|
47155
|
+
};
|
|
47156
|
+
const result = await executePromptByIntent(cwd, input, {
|
|
47157
|
+
intent: "run",
|
|
47158
|
+
outputFormat: options.json ? "json" : "text",
|
|
47159
|
+
sessionId: options.sessionId,
|
|
47160
|
+
ephemeral: options.ephemeral,
|
|
47161
|
+
maxAutoTasks: options.maxAutoTasks,
|
|
47162
|
+
maxAgentSteps: options.maxAgentSteps,
|
|
47163
|
+
maxRepairAttempts: options.maxRepairAttempts,
|
|
47164
|
+
...typeof options.maxToolCalls === "number" ? {
|
|
47165
|
+
maxToolCalls: options.maxToolCalls
|
|
47166
|
+
} : {},
|
|
47167
|
+
...typeof options.maxModelCalls === "number" ? {
|
|
47168
|
+
maxModelCalls: options.maxModelCalls
|
|
47169
|
+
} : {},
|
|
47170
|
+
...typeof options.maxInputTokens === "number" ? {
|
|
47171
|
+
maxInputTokens: options.maxInputTokens
|
|
47172
|
+
} : {},
|
|
47173
|
+
...typeof options.maxOutputTokens === "number" ? {
|
|
47174
|
+
maxOutputTokens: options.maxOutputTokens
|
|
47175
|
+
} : {},
|
|
47176
|
+
...agentSelection ? {
|
|
47177
|
+
agentSelection
|
|
47178
|
+
} : {}
|
|
47179
|
+
});
|
|
47180
|
+
if (options.json) {
|
|
47181
|
+
console.log(renderJson({
|
|
47182
|
+
mode: "fix",
|
|
47183
|
+
goal: input.prompt,
|
|
47184
|
+
review: review ? {
|
|
47185
|
+
source: review.source,
|
|
47186
|
+
riskLevel: review.riskLevel,
|
|
47187
|
+
changedFiles: review.changedFiles,
|
|
47188
|
+
artifactPath: review.artifactPath
|
|
47189
|
+
} : null,
|
|
47190
|
+
result: result.payload
|
|
47191
|
+
}));
|
|
47192
|
+
return;
|
|
47193
|
+
}
|
|
47194
|
+
console.log(renderFixTextOutput(input, result, review));
|
|
47195
|
+
});
|
|
47196
|
+
}
|
|
47197
|
+
|
|
47198
|
+
// src/commands/fork.ts
|
|
47199
|
+
var import_node_process18 = __toESM(require("node:process"), 1);
|
|
47200
|
+
function parseCount4(value) {
|
|
47201
|
+
const parsed = Number(value);
|
|
47202
|
+
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
47203
|
+
throw new Error(`Expected a positive integer, received "${value}".`);
|
|
47204
|
+
}
|
|
47205
|
+
return parsed;
|
|
47206
|
+
}
|
|
46717
47207
|
function printSessionList(rows) {
|
|
46718
47208
|
if (rows.length === 0) {
|
|
46719
47209
|
console.log("No saved sessions found.");
|
|
@@ -46738,8 +47228,8 @@ async function resolveSourceSession(cwd, sessionId, last = false, search) {
|
|
|
46738
47228
|
return loadSessionById(sessionId, cwd);
|
|
46739
47229
|
}
|
|
46740
47230
|
function createForkCommand() {
|
|
46741
|
-
return new Command("fork").description("Fork a saved session into a new session snapshot.").argument("[sessionId]", "Optional session id; defaults to the latest session").option("--last", "Fork the most recent session", false).option("--list", "List recent sessions and exit", false).option("--search <query>", "Filter sessions by id, goal, cwd, or labels").option("--json", "Print the forked snapshot as JSON", false).option("--execute", "Continue auto-executing the forked session", false).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute",
|
|
46742
|
-
const cwd =
|
|
47231
|
+
return new Command("fork").description("Fork a saved session into a new session snapshot.").argument("[sessionId]", "Optional session id; defaults to the latest session").option("--last", "Fork the most recent session", false).option("--list", "List recent sessions and exit", false).option("--search <query>", "Filter sessions by id, goal, cwd, or labels").option("--json", "Print the forked snapshot as JSON", false).option("--execute", "Continue auto-executing the forked session", false).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount4, 4).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount4, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount4, 2).option("--max-tool-calls <count>", "Maximum tool calls per autonomous task", parseCount4).option("--max-model-calls <count>", "Maximum model calls per autonomous task", parseCount4).option("--max-input-tokens <count>", "Maximum input tokens per autonomous task", parseCount4).option("--max-output-tokens <count>", "Maximum output tokens per autonomous task", parseCount4).action(async (sessionId, options) => {
|
|
47232
|
+
const cwd = import_node_process18.default.cwd();
|
|
46743
47233
|
if (options.list) {
|
|
46744
47234
|
const sessions = options.search ? await searchSessions(options.search, cwd) : await listSessions(cwd);
|
|
46745
47235
|
if (options.json) {
|
|
@@ -46752,7 +47242,7 @@ function createForkCommand() {
|
|
|
46752
47242
|
const source = await resolveSourceSession(cwd, sessionId, options.last, options.search);
|
|
46753
47243
|
if (!source) {
|
|
46754
47244
|
console.error("No saved session found.");
|
|
46755
|
-
|
|
47245
|
+
import_node_process18.default.exitCode = 1;
|
|
46756
47246
|
return;
|
|
46757
47247
|
}
|
|
46758
47248
|
const forked = forkSessionSnapshot(source);
|
|
@@ -46790,7 +47280,7 @@ function createForkCommand() {
|
|
|
46790
47280
|
}
|
|
46791
47281
|
|
|
46792
47282
|
// src/commands/init.ts
|
|
46793
|
-
var
|
|
47283
|
+
var import_node_process19 = __toESM(require("node:process"), 1);
|
|
46794
47284
|
function printProjectUnderstanding(result) {
|
|
46795
47285
|
console.log(result.summary);
|
|
46796
47286
|
console.log("Now I have a durable understanding of the current project structure.");
|
|
@@ -46809,7 +47299,7 @@ function printProjectUnderstanding(result) {
|
|
|
46809
47299
|
}
|
|
46810
47300
|
function createInitCommand() {
|
|
46811
47301
|
return new Command("init").description("Create or refresh local Kimbho config and project bootstrap memory.").option("--template <template>", "Provider template to use for the initial provider").option("--provider-id <id>", "Identifier for the initial provider").option("--driver <driver>", "Provider driver to use when no template is supplied").option("--label <label>", "Human-readable provider label").option("--model <model>", "Default model to use for planner/coder/reviewer brains").option("--fast-model <model>", "Model to use for the fast utility brain").option("--api-key-env <env>", "Environment variable that stores the provider API key").option("--base-url <url>", "Base URL or endpoint for the provider driver").option("--module-path <path>", "Module path for a custom provider driver").option("--config-only", "Only write .kimbho/config.toml and skip project memory generation", false).option("--memory-only", "Only generate kimbho_init.md and keep the existing config untouched", false).option("--memory-file <file>", "Project memory file to write", "kimbho_init.md").option("--force", "Overwrite an existing config file", false).action(async (options) => {
|
|
46812
|
-
const existing = await loadConfig(
|
|
47302
|
+
const existing = await loadConfig(import_node_process19.default.cwd());
|
|
46813
47303
|
const configMutationRequested = [
|
|
46814
47304
|
options.template,
|
|
46815
47305
|
options.providerId,
|
|
@@ -46823,12 +47313,12 @@ function createInitCommand() {
|
|
|
46823
47313
|
].some((value) => typeof value === "string" && value.trim().length > 0);
|
|
46824
47314
|
if (options.configOnly && options.memoryOnly) {
|
|
46825
47315
|
console.error("Choose either --config-only or --memory-only, not both.");
|
|
46826
|
-
|
|
47316
|
+
import_node_process19.default.exitCode = 1;
|
|
46827
47317
|
return;
|
|
46828
47318
|
}
|
|
46829
47319
|
if (existing && !options.force && configMutationRequested && !options.memoryOnly) {
|
|
46830
47320
|
console.error("Config already exists. Re-run with --force to overwrite it.");
|
|
46831
|
-
|
|
47321
|
+
import_node_process19.default.exitCode = 1;
|
|
46832
47322
|
return;
|
|
46833
47323
|
}
|
|
46834
47324
|
if (!options.memoryOnly) {
|
|
@@ -46866,20 +47356,20 @@ function createInitCommand() {
|
|
|
46866
47356
|
defaultModel: options.model ?? provider.defaultModel,
|
|
46867
47357
|
fastModel: options.fastModel ?? options.model ?? provider.defaultModel
|
|
46868
47358
|
});
|
|
46869
|
-
const outputPath = await saveConfig(nextConfig,
|
|
47359
|
+
const outputPath = await saveConfig(nextConfig, import_node_process19.default.cwd());
|
|
46870
47360
|
console.log(`Created ${outputPath}`);
|
|
46871
47361
|
}
|
|
46872
47362
|
}
|
|
46873
47363
|
if (!options.configOnly) {
|
|
46874
|
-
const result = await refreshMemoryFiles(
|
|
47364
|
+
const result = await refreshMemoryFiles(import_node_process19.default.cwd());
|
|
46875
47365
|
printProjectUnderstanding(result);
|
|
46876
47366
|
}
|
|
46877
47367
|
});
|
|
46878
47368
|
}
|
|
46879
47369
|
|
|
46880
47370
|
// src/commands/ide.ts
|
|
46881
|
-
var
|
|
46882
|
-
var
|
|
47371
|
+
var import_node_path29 = __toESM(require("node:path"), 1);
|
|
47372
|
+
var import_node_process20 = __toESM(require("node:process"), 1);
|
|
46883
47373
|
function renderIdeState(state) {
|
|
46884
47374
|
if (!state) {
|
|
46885
47375
|
return "No IDE companion is linked.";
|
|
@@ -46897,27 +47387,27 @@ function renderIdeState(state) {
|
|
|
46897
47387
|
function createIdeCommand() {
|
|
46898
47388
|
const command = new Command("ide").description("Discover, link, and open the active workspace in a local IDE companion.");
|
|
46899
47389
|
command.command("status").description("Show the linked or detected IDE companion.").option("--json", "Print the IDE companion payload as JSON", false).action(async (options) => {
|
|
46900
|
-
const state = await detectIdeBridge(
|
|
47390
|
+
const state = await detectIdeBridge(import_node_process20.default.cwd());
|
|
46901
47391
|
if (options.json) {
|
|
46902
47392
|
console.log(JSON.stringify(state, null, 2));
|
|
46903
47393
|
return;
|
|
46904
47394
|
}
|
|
46905
47395
|
console.log(renderIdeState(state));
|
|
46906
47396
|
});
|
|
46907
|
-
command.command("link").description("Persist a local IDE companion link for this workspace.").option("--editor <id>", "Editor id", "manual").option("--label <label>", "Human-readable label").option("--command <binary>", "Launcher command").option("--workspace <path>", "Workspace path",
|
|
46908
|
-
const detected = !options.command ? await detectIdeBridge(
|
|
47397
|
+
command.command("link").description("Persist a local IDE companion link for this workspace.").option("--editor <id>", "Editor id", "manual").option("--label <label>", "Human-readable label").option("--command <binary>", "Launcher command").option("--workspace <path>", "Workspace path", import_node_process20.default.cwd()).option("--json", "Print the IDE companion payload as JSON", false).action(async (options) => {
|
|
47398
|
+
const detected = !options.command ? await detectIdeBridge(import_node_process20.default.cwd()) : null;
|
|
46909
47399
|
const state = {
|
|
46910
47400
|
editorId: options.command ? options.editor : detected?.editorId ?? options.editor,
|
|
46911
47401
|
label: options.label ?? detected?.label ?? options.editor,
|
|
46912
47402
|
command: options.command ?? detected?.command ?? options.editor,
|
|
46913
|
-
workspace:
|
|
47403
|
+
workspace: import_node_path29.default.resolve(import_node_process20.default.cwd(), options.workspace),
|
|
46914
47404
|
source: options.command ? "manual" : detected?.source ?? "detected",
|
|
46915
47405
|
linkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
46916
47406
|
...detected?.lastOpenedPath ? {
|
|
46917
47407
|
lastOpenedPath: detected.lastOpenedPath
|
|
46918
47408
|
} : {}
|
|
46919
47409
|
};
|
|
46920
|
-
const outputPath = await saveIdeBridgeState(
|
|
47410
|
+
const outputPath = await saveIdeBridgeState(import_node_process20.default.cwd(), state);
|
|
46921
47411
|
if (options.json) {
|
|
46922
47412
|
console.log(JSON.stringify({
|
|
46923
47413
|
state,
|
|
@@ -46929,13 +47419,13 @@ function createIdeCommand() {
|
|
|
46929
47419
|
console.log(`Saved: ${outputPath}`);
|
|
46930
47420
|
});
|
|
46931
47421
|
command.command("open").description("Open one file or the current workspace in the linked IDE.").argument("[target]", "Optional file path; defaults to the current workspace", ".").option("--line <line>", "Open at a specific line", (value) => Number.parseInt(value, 10)).option("--column <column>", "Open at a specific column", (value) => Number.parseInt(value, 10)).option("--json", "Print the IDE companion payload as JSON", false).action(async (target, options) => {
|
|
46932
|
-
const state = await openInIde(
|
|
47422
|
+
const state = await openInIde(import_node_process20.default.cwd(), target, {
|
|
46933
47423
|
line: Number.isInteger(options.line) && options.line > 0 ? options.line : void 0,
|
|
46934
47424
|
column: Number.isInteger(options.column) && options.column > 0 ? options.column : void 0
|
|
46935
47425
|
});
|
|
46936
47426
|
const payload = {
|
|
46937
47427
|
state,
|
|
46938
|
-
target:
|
|
47428
|
+
target: import_node_path29.default.resolve(import_node_process20.default.cwd(), target)
|
|
46939
47429
|
};
|
|
46940
47430
|
if (options.json) {
|
|
46941
47431
|
console.log(JSON.stringify(payload, null, 2));
|
|
@@ -46947,7 +47437,7 @@ function createIdeCommand() {
|
|
|
46947
47437
|
}
|
|
46948
47438
|
|
|
46949
47439
|
// src/commands/update.ts
|
|
46950
|
-
var
|
|
47440
|
+
var import_node_process21 = __toESM(require("node:process"), 1);
|
|
46951
47441
|
function renderUpdatePayload(payload) {
|
|
46952
47442
|
return [
|
|
46953
47443
|
`current: ${payload.currentVersion}`,
|
|
@@ -46976,7 +47466,7 @@ function createInstallCommand() {
|
|
|
46976
47466
|
console.log(result.detail);
|
|
46977
47467
|
}
|
|
46978
47468
|
if (!result.ok) {
|
|
46979
|
-
|
|
47469
|
+
import_node_process21.default.exitCode = 1;
|
|
46980
47470
|
}
|
|
46981
47471
|
return;
|
|
46982
47472
|
}
|
|
@@ -46989,7 +47479,7 @@ function createInstallCommand() {
|
|
|
46989
47479
|
}
|
|
46990
47480
|
function createUpdateCommand(commandName = "update") {
|
|
46991
47481
|
return new Command(commandName).description(commandName === "upgrade" ? "Check for and optionally install a newer Kimbho CLI build." : "Check for and optionally install a newer Kimbho CLI build.").option("--apply", "Run the global npm install command immediately when an update exists", false).option("--json", "Print the update payload as JSON", false).action(async (options) => {
|
|
46992
|
-
const payload = await resolveUpdateManifest(
|
|
47482
|
+
const payload = await resolveUpdateManifest(import_node_process21.default.cwd());
|
|
46993
47483
|
const updateAvailable = isUpgradeAvailable(payload);
|
|
46994
47484
|
if (options.apply && updateAvailable) {
|
|
46995
47485
|
const result = runGlobalNpmInstall(payload.latestVersion);
|
|
@@ -47003,7 +47493,7 @@ function createUpdateCommand(commandName = "update") {
|
|
|
47003
47493
|
console.log(result.detail);
|
|
47004
47494
|
}
|
|
47005
47495
|
if (!result.ok) {
|
|
47006
|
-
|
|
47496
|
+
import_node_process21.default.exitCode = 1;
|
|
47007
47497
|
}
|
|
47008
47498
|
return;
|
|
47009
47499
|
}
|
|
@@ -47020,7 +47510,7 @@ function createUpdateCommand(commandName = "update") {
|
|
|
47020
47510
|
}
|
|
47021
47511
|
|
|
47022
47512
|
// src/commands/mcp.ts
|
|
47023
|
-
var
|
|
47513
|
+
var import_node_process22 = __toESM(require("node:process"), 1);
|
|
47024
47514
|
|
|
47025
47515
|
// src/mcp.ts
|
|
47026
47516
|
async function renderMcpServerList(cwd) {
|
|
@@ -47184,7 +47674,7 @@ function collectValues(value, previous = []) {
|
|
|
47184
47674
|
function createMcpCommand() {
|
|
47185
47675
|
const command = new Command("mcp").description("Manage project-local MCP servers in .mcp.json.");
|
|
47186
47676
|
command.command("list").description("List configured MCP servers.").action(async () => {
|
|
47187
|
-
for (const line of await renderMcpServerList(
|
|
47677
|
+
for (const line of await renderMcpServerList(import_node_process22.default.cwd())) {
|
|
47188
47678
|
console.log(line);
|
|
47189
47679
|
}
|
|
47190
47680
|
});
|
|
@@ -47192,7 +47682,7 @@ function createMcpCommand() {
|
|
|
47192
47682
|
const env = Object.fromEntries(
|
|
47193
47683
|
options.env.map((pair) => pair.split("=", 2)).filter((entry) => entry.length === 2 && entry[0].length > 0)
|
|
47194
47684
|
);
|
|
47195
|
-
const outputPath = await addMcpServer(
|
|
47685
|
+
const outputPath = await addMcpServer(import_node_process22.default.cwd(), name, {
|
|
47196
47686
|
command: options.command,
|
|
47197
47687
|
args: options.arg,
|
|
47198
47688
|
env,
|
|
@@ -47206,34 +47696,34 @@ function createMcpCommand() {
|
|
|
47206
47696
|
console.log(`Updated ${outputPath}`);
|
|
47207
47697
|
});
|
|
47208
47698
|
command.command("remove").description("Remove an MCP server.").argument("<name>", "Server name").action(async (name) => {
|
|
47209
|
-
const outputPath = await removeMcpServerByName(
|
|
47699
|
+
const outputPath = await removeMcpServerByName(import_node_process22.default.cwd(), name);
|
|
47210
47700
|
console.log(`Updated ${outputPath}`);
|
|
47211
47701
|
});
|
|
47212
47702
|
command.command("enable").description("Enable an MCP server.").argument("<name>", "Server name").action(async (name) => {
|
|
47213
|
-
const outputPath = await toggleMcpServer(
|
|
47703
|
+
const outputPath = await toggleMcpServer(import_node_process22.default.cwd(), name, true);
|
|
47214
47704
|
console.log(`Updated ${outputPath}`);
|
|
47215
47705
|
});
|
|
47216
47706
|
command.command("disable").description("Disable an MCP server.").argument("<name>", "Server name").action(async (name) => {
|
|
47217
|
-
const outputPath = await toggleMcpServer(
|
|
47707
|
+
const outputPath = await toggleMcpServer(import_node_process22.default.cwd(), name, false);
|
|
47218
47708
|
console.log(`Updated ${outputPath}`);
|
|
47219
47709
|
});
|
|
47220
47710
|
command.command("tools").description("Inspect MCP tool, prompt, and resource inventory.").argument("[name]", "Optional server name").action(async (name) => {
|
|
47221
|
-
for (const line of await renderMcpInventory(
|
|
47711
|
+
for (const line of await renderMcpInventory(import_node_process22.default.cwd(), name)) {
|
|
47222
47712
|
console.log(line);
|
|
47223
47713
|
}
|
|
47224
47714
|
});
|
|
47225
47715
|
command.command("discover").description("Show MCP tools, prompts-as-commands, and resource attachment syntax.").argument("[name]", "Optional server name").action(async (name) => {
|
|
47226
|
-
for (const line of await renderMcpInventory(
|
|
47716
|
+
for (const line of await renderMcpInventory(import_node_process22.default.cwd(), name)) {
|
|
47227
47717
|
console.log(line);
|
|
47228
47718
|
}
|
|
47229
47719
|
});
|
|
47230
47720
|
command.command("prompts").description("List MCP prompts.").argument("[name]", "Optional server name").action(async (name) => {
|
|
47231
|
-
for (const line of await renderMcpPromptList(
|
|
47721
|
+
for (const line of await renderMcpPromptList(import_node_process22.default.cwd(), name)) {
|
|
47232
47722
|
console.log(line);
|
|
47233
47723
|
}
|
|
47234
47724
|
});
|
|
47235
47725
|
command.command("resources").description("List MCP resources and resource templates.").argument("[name]", "Optional server name").action(async (name) => {
|
|
47236
|
-
for (const line of await renderMcpResourceList(
|
|
47726
|
+
for (const line of await renderMcpResourceList(import_node_process22.default.cwd(), name)) {
|
|
47237
47727
|
console.log(line);
|
|
47238
47728
|
}
|
|
47239
47729
|
});
|
|
@@ -47241,12 +47731,12 @@ function createMcpCommand() {
|
|
|
47241
47731
|
const args = Object.fromEntries(
|
|
47242
47732
|
rawArgs.map((entry) => entry.split("=", 2)).filter((parts) => parts.length === 2 && parts[0].length > 0)
|
|
47243
47733
|
);
|
|
47244
|
-
for (const line of await renderMcpPromptInvocation(
|
|
47734
|
+
for (const line of await renderMcpPromptInvocation(import_node_process22.default.cwd(), server, prompt, args)) {
|
|
47245
47735
|
console.log(line);
|
|
47246
47736
|
}
|
|
47247
47737
|
});
|
|
47248
47738
|
command.command("read").description("Read one MCP resource by URI.").argument("<server>", "Server name").argument("<uri>", "Resource URI").action(async (server, uri) => {
|
|
47249
|
-
for (const line of await renderMcpResourceRead(
|
|
47739
|
+
for (const line of await renderMcpResourceRead(import_node_process22.default.cwd(), server, uri)) {
|
|
47250
47740
|
console.log(line);
|
|
47251
47741
|
}
|
|
47252
47742
|
});
|
|
@@ -47254,20 +47744,20 @@ function createMcpCommand() {
|
|
|
47254
47744
|
}
|
|
47255
47745
|
|
|
47256
47746
|
// src/commands/mcp-server.ts
|
|
47257
|
-
var
|
|
47747
|
+
var import_node_process23 = __toESM(require("node:process"), 1);
|
|
47258
47748
|
function createMcpServerCommand() {
|
|
47259
47749
|
return new Command("mcp-server").description("Run Kimbho as an MCP server over stdio.").action(async () => {
|
|
47260
|
-
await runMcpServer(
|
|
47750
|
+
await runMcpServer(import_node_process23.default.cwd());
|
|
47261
47751
|
});
|
|
47262
47752
|
}
|
|
47263
47753
|
|
|
47264
47754
|
// src/commands/memory.ts
|
|
47265
|
-
var
|
|
47266
|
-
var
|
|
47755
|
+
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
47756
|
+
var import_node_process24 = __toESM(require("node:process"), 1);
|
|
47267
47757
|
function createMemoryCommand() {
|
|
47268
47758
|
const command = new Command("memory").description("Manage markdown-backed Kimbho memory files.");
|
|
47269
47759
|
command.command("status").description("Show the memory file locations.").action(async () => {
|
|
47270
|
-
const paths = await listMemoryPaths(
|
|
47760
|
+
const paths = await listMemoryPaths(import_node_process24.default.cwd());
|
|
47271
47761
|
console.log(`init: ${paths.initFilePath}`);
|
|
47272
47762
|
console.log(`project: ${paths.projectMemoryPath}`);
|
|
47273
47763
|
console.log(`user: ${paths.userMemoryPath}`);
|
|
@@ -47277,7 +47767,7 @@ function createMemoryCommand() {
|
|
|
47277
47767
|
console.log(`agents: ${paths.agentMemoryDir}`);
|
|
47278
47768
|
});
|
|
47279
47769
|
command.command("refresh").description("Refresh kimbho_init.md and project memory.").action(async () => {
|
|
47280
|
-
const result = await refreshMemoryFiles(
|
|
47770
|
+
const result = await refreshMemoryFiles(import_node_process24.default.cwd());
|
|
47281
47771
|
console.log(result.summary);
|
|
47282
47772
|
console.log(`Wrote ${result.initFilePath}`);
|
|
47283
47773
|
console.log(`Wrote ${result.projectMemoryPath}`);
|
|
@@ -47286,16 +47776,16 @@ function createMemoryCommand() {
|
|
|
47286
47776
|
command.command("show").description("Print one memory file.").argument("<scope>", "init, project, user, or agent").argument("[agentId]", "Agent id when scope is agent").action(async (scope, agentId) => {
|
|
47287
47777
|
let filePath;
|
|
47288
47778
|
if (scope === "init") {
|
|
47289
|
-
filePath =
|
|
47779
|
+
filePath = import_node_path30.default.join(import_node_process24.default.cwd(), "kimbho_init.md");
|
|
47290
47780
|
} else if (scope === "project") {
|
|
47291
|
-
filePath = resolveProjectMemoryPath(
|
|
47781
|
+
filePath = resolveProjectMemoryPath(import_node_process24.default.cwd());
|
|
47292
47782
|
} else if (scope === "user") {
|
|
47293
47783
|
filePath = resolveUserMemoryPath();
|
|
47294
47784
|
} else if (scope === "agent") {
|
|
47295
47785
|
if (!agentId) {
|
|
47296
47786
|
throw new Error("Pass an agent id when using scope=agent.");
|
|
47297
47787
|
}
|
|
47298
|
-
filePath =
|
|
47788
|
+
filePath = import_node_path30.default.join(resolveAgentMemoryDir(import_node_process24.default.cwd()), `${agentId}.md`);
|
|
47299
47789
|
} else {
|
|
47300
47790
|
throw new Error("Scope must be one of: init, project, user, agent.");
|
|
47301
47791
|
}
|
|
@@ -47308,7 +47798,7 @@ function createMemoryCommand() {
|
|
|
47308
47798
|
});
|
|
47309
47799
|
command.command("add").description("Append a memory note.").argument("<scope>", "project, user, or agent").argument("<first>", "Text or agent id when scope=agent").argument("[rest...]", "Remaining note text").action(async (scope, first, rest = []) => {
|
|
47310
47800
|
if (scope === "project" || scope === "user") {
|
|
47311
|
-
const outputPath = await appendMemoryNote(
|
|
47801
|
+
const outputPath = await appendMemoryNote(import_node_process24.default.cwd(), scope, [
|
|
47312
47802
|
first,
|
|
47313
47803
|
...rest
|
|
47314
47804
|
].join(" "));
|
|
@@ -47316,7 +47806,7 @@ function createMemoryCommand() {
|
|
|
47316
47806
|
return;
|
|
47317
47807
|
}
|
|
47318
47808
|
if (scope === "agent") {
|
|
47319
|
-
const outputPath = await appendMemoryNote(
|
|
47809
|
+
const outputPath = await appendMemoryNote(import_node_process24.default.cwd(), "agent", rest.join(" "), first);
|
|
47320
47810
|
console.log(`Updated ${outputPath}`);
|
|
47321
47811
|
return;
|
|
47322
47812
|
}
|
|
@@ -47326,7 +47816,7 @@ function createMemoryCommand() {
|
|
|
47326
47816
|
}
|
|
47327
47817
|
|
|
47328
47818
|
// src/commands/model.ts
|
|
47329
|
-
var
|
|
47819
|
+
var import_node_process25 = __toESM(require("node:process"), 1);
|
|
47330
47820
|
function requireConfig() {
|
|
47331
47821
|
throw new Error("No config found. Run `kimbho init` first.");
|
|
47332
47822
|
}
|
|
@@ -47349,7 +47839,7 @@ async function fetchModels(provider, options) {
|
|
|
47349
47839
|
models: cachedModels
|
|
47350
47840
|
};
|
|
47351
47841
|
}
|
|
47352
|
-
const registry2 = createDefaultBrainProviderRegistry(
|
|
47842
|
+
const registry2 = createDefaultBrainProviderRegistry(import_node_process25.default.cwd());
|
|
47353
47843
|
try {
|
|
47354
47844
|
const models = await registry2.listModels(provider, {
|
|
47355
47845
|
...options.search ? {
|
|
@@ -47391,14 +47881,14 @@ function printAssignments(config2) {
|
|
|
47391
47881
|
function createModelCommand() {
|
|
47392
47882
|
const command = new Command("model").description("Use one MECE surface for providers, models, and role assignments.");
|
|
47393
47883
|
command.command("show").description("Show current provider/model assignments.").action(async () => {
|
|
47394
|
-
const config2 = await loadConfig(
|
|
47884
|
+
const config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47395
47885
|
if (!config2) {
|
|
47396
47886
|
requireConfig();
|
|
47397
47887
|
}
|
|
47398
47888
|
printAssignments(config2);
|
|
47399
47889
|
});
|
|
47400
47890
|
command.command("providers").description("List configured providers.").action(async () => {
|
|
47401
|
-
const config2 = await loadConfig(
|
|
47891
|
+
const config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47402
47892
|
if (!config2) {
|
|
47403
47893
|
requireConfig();
|
|
47404
47894
|
}
|
|
@@ -47421,7 +47911,7 @@ function createModelCommand() {
|
|
|
47421
47911
|
}
|
|
47422
47912
|
});
|
|
47423
47913
|
command.command("add").description("Add a provider from a template.").argument("<template>", "Template id").argument("[providerId]", "Optional provider id").option("--label <label>", "Provider label").option("--base-url <url>", "Base URL override").option("--api-key-env <env>", "API key environment variable").option("--model <id>", "Default model").action(async (templateId, providerId, options) => {
|
|
47424
|
-
const config2 = await loadConfig(
|
|
47914
|
+
const config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47425
47915
|
if (!config2) {
|
|
47426
47916
|
requireConfig();
|
|
47427
47917
|
}
|
|
@@ -47432,12 +47922,12 @@ function createModelCommand() {
|
|
|
47432
47922
|
apiKeyEnv: options.apiKeyEnv,
|
|
47433
47923
|
model: options.model
|
|
47434
47924
|
});
|
|
47435
|
-
const outputPath = await saveConfig(upsertProvider(config2, provider),
|
|
47925
|
+
const outputPath = await saveConfig(upsertProvider(config2, provider), import_node_process25.default.cwd());
|
|
47436
47926
|
console.log(`Updated ${outputPath}`);
|
|
47437
47927
|
console.log(`Added ${provider.id} via ${templateId}`);
|
|
47438
47928
|
});
|
|
47439
47929
|
command.command("find").description("Find models on a provider.").argument("[search]", "Optional search text").option("--provider <id>", "Provider id; defaults to coder provider").option("--limit <count>", "Max number of models", parseInteger, 20).option("--cached", "Use cached provider models", false).action(async (search, options) => {
|
|
47440
|
-
const config2 = await loadConfig(
|
|
47930
|
+
const config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47441
47931
|
if (!config2) {
|
|
47442
47932
|
requireConfig();
|
|
47443
47933
|
}
|
|
@@ -47462,7 +47952,7 @@ function createModelCommand() {
|
|
|
47462
47952
|
}
|
|
47463
47953
|
});
|
|
47464
47954
|
command.command("use").description("Assign one provider/model globally or to one role.").argument("<provider>", "Provider id").argument("[model]", "Optional model id").option("--role <role>", "Optional role override").action(async (providerId, modelId, options) => {
|
|
47465
|
-
let config2 = await loadConfig(
|
|
47955
|
+
let config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47466
47956
|
if (!config2) {
|
|
47467
47957
|
requireConfig();
|
|
47468
47958
|
}
|
|
@@ -47479,7 +47969,7 @@ function createModelCommand() {
|
|
|
47479
47969
|
} else {
|
|
47480
47970
|
config2 = assignProviderToAllBrains(config2, providerId);
|
|
47481
47971
|
}
|
|
47482
|
-
const outputPath2 = await saveConfig(config2,
|
|
47972
|
+
const outputPath2 = await saveConfig(config2, import_node_process25.default.cwd());
|
|
47483
47973
|
console.log(`Updated ${outputPath2}`);
|
|
47484
47974
|
console.log(options.role ? `Assigned ${providerId} to ${options.role}` : `Assigned ${providerId} to all roles`);
|
|
47485
47975
|
return;
|
|
@@ -47517,16 +48007,16 @@ function createModelCommand() {
|
|
|
47517
48007
|
model: modelId
|
|
47518
48008
|
});
|
|
47519
48009
|
}
|
|
47520
|
-
const outputPath = await saveConfig(config2,
|
|
48010
|
+
const outputPath = await saveConfig(config2, import_node_process25.default.cwd());
|
|
47521
48011
|
console.log(`Updated ${outputPath}`);
|
|
47522
48012
|
console.log(options.role ? `Assigned ${providerId}/${modelId} to ${options.role}` : `Assigned ${providerId}/${modelId} to all roles`);
|
|
47523
48013
|
});
|
|
47524
48014
|
command.command("check").description("Run health checks for configured providers.").action(async () => {
|
|
47525
|
-
const config2 = await loadConfig(
|
|
48015
|
+
const config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47526
48016
|
if (!config2) {
|
|
47527
48017
|
requireConfig();
|
|
47528
48018
|
}
|
|
47529
|
-
const registry2 = createDefaultBrainProviderRegistry(
|
|
48019
|
+
const registry2 = createDefaultBrainProviderRegistry(import_node_process25.default.cwd());
|
|
47530
48020
|
for (const provider of config2.providers) {
|
|
47531
48021
|
try {
|
|
47532
48022
|
const result = await registry2.healthCheck(provider);
|
|
@@ -47538,7 +48028,7 @@ function createModelCommand() {
|
|
|
47538
48028
|
}
|
|
47539
48029
|
});
|
|
47540
48030
|
command.action(async () => {
|
|
47541
|
-
const config2 = await loadConfig(
|
|
48031
|
+
const config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47542
48032
|
if (!config2) {
|
|
47543
48033
|
requireConfig();
|
|
47544
48034
|
}
|
|
@@ -47548,7 +48038,7 @@ function createModelCommand() {
|
|
|
47548
48038
|
}
|
|
47549
48039
|
|
|
47550
48040
|
// src/commands/models.ts
|
|
47551
|
-
var
|
|
48041
|
+
var import_node_process26 = __toESM(require("node:process"), 1);
|
|
47552
48042
|
function parseInteger2(value) {
|
|
47553
48043
|
const parsed = Number.parseInt(value, 10);
|
|
47554
48044
|
if (!Number.isFinite(parsed)) {
|
|
@@ -47607,7 +48097,7 @@ async function fetchProviderModels(provider, options) {
|
|
|
47607
48097
|
models: cachedModels
|
|
47608
48098
|
};
|
|
47609
48099
|
}
|
|
47610
|
-
const registry2 = createDefaultBrainProviderRegistry(
|
|
48100
|
+
const registry2 = createDefaultBrainProviderRegistry(import_node_process26.default.cwd());
|
|
47611
48101
|
try {
|
|
47612
48102
|
const models = await registry2.listModels(provider, {
|
|
47613
48103
|
...options.search ? {
|
|
@@ -47634,7 +48124,7 @@ async function fetchProviderModels(provider, options) {
|
|
|
47634
48124
|
function createModelsCommand() {
|
|
47635
48125
|
const command = new Command("models").description("[legacy] Discover and select models from configured providers.");
|
|
47636
48126
|
command.command("list").description("List models for one provider or all configured providers.").argument("[provider]", "Optional provider id to inspect").option("--search <term>", "Filter the returned models by search text").option("--limit <count>", "Maximum number of models to print", parseInteger2, 25).option("--cached", "Use cached models from config instead of remote discovery", false).option("--sync", "Persist discovered model ids back into config", false).option("--json", "Print models as JSON", false).action(async (providerId, options) => {
|
|
47637
|
-
let config2 = await loadConfig(
|
|
48127
|
+
let config2 = await loadConfig(import_node_process26.default.cwd());
|
|
47638
48128
|
if (!config2) {
|
|
47639
48129
|
requireConfigMessage2();
|
|
47640
48130
|
}
|
|
@@ -47663,7 +48153,7 @@ function createModelsCommand() {
|
|
|
47663
48153
|
}
|
|
47664
48154
|
}
|
|
47665
48155
|
if (mutated) {
|
|
47666
|
-
await saveConfig(config2,
|
|
48156
|
+
await saveConfig(config2, import_node_process26.default.cwd());
|
|
47667
48157
|
}
|
|
47668
48158
|
if (options.json) {
|
|
47669
48159
|
console.log(renderJson(groups));
|
|
@@ -47680,7 +48170,7 @@ function createModelsCommand() {
|
|
|
47680
48170
|
}
|
|
47681
48171
|
});
|
|
47682
48172
|
command.command("sync").description("Fetch remote models for one provider and cache the ids in config.").argument("<provider>", "Provider id to sync").option("--search <term>", "Optional search filter to limit what gets cached").option("--limit <count>", "Maximum number of models to cache", parseInteger2, 200).action(async (providerId, options) => {
|
|
47683
|
-
const config2 = await loadConfig(
|
|
48173
|
+
const config2 = await loadConfig(import_node_process26.default.cwd());
|
|
47684
48174
|
if (!config2) {
|
|
47685
48175
|
requireConfigMessage2();
|
|
47686
48176
|
}
|
|
@@ -47688,7 +48178,7 @@ function createModelsCommand() {
|
|
|
47688
48178
|
if (!provider) {
|
|
47689
48179
|
throw new Error(`Unknown provider "${providerId}".`);
|
|
47690
48180
|
}
|
|
47691
|
-
const registry2 = createDefaultBrainProviderRegistry(
|
|
48181
|
+
const registry2 = createDefaultBrainProviderRegistry(import_node_process26.default.cwd());
|
|
47692
48182
|
const models = await registry2.listModels(provider, {
|
|
47693
48183
|
...options.search ? {
|
|
47694
48184
|
search: options.search
|
|
@@ -47699,12 +48189,12 @@ function createModelsCommand() {
|
|
|
47699
48189
|
...provider,
|
|
47700
48190
|
models: Array.from(new Set(models.map((model) => model.id)))
|
|
47701
48191
|
});
|
|
47702
|
-
const outputPath = await saveConfig(nextConfig,
|
|
48192
|
+
const outputPath = await saveConfig(nextConfig, import_node_process26.default.cwd());
|
|
47703
48193
|
console.log(`Updated ${outputPath}`);
|
|
47704
48194
|
console.log(`Synced ${models.length} models for ${provider.id}`);
|
|
47705
48195
|
});
|
|
47706
48196
|
command.command("use").description("Select a model for a provider and assign it globally unless a specific role is requested.").argument("<model>", "Model id to select").requiredOption("--provider <provider>", "Provider id to use").option("--role <role>", "Brain role to assign: planner, coder, reviewer, or fast").option("--set-default", "Also set this model as the provider default", false).option("--force", "Skip remote model validation", false).option("--temperature <value>", "Temperature override for the role", parseNumber2).option("--max-tokens <value>", "Max token override for the role", parseInteger2).action(async (model, options) => {
|
|
47707
|
-
let config2 = await loadConfig(
|
|
48197
|
+
let config2 = await loadConfig(import_node_process26.default.cwd());
|
|
47708
48198
|
if (!config2) {
|
|
47709
48199
|
requireConfigMessage2();
|
|
47710
48200
|
}
|
|
@@ -47714,7 +48204,7 @@ function createModelsCommand() {
|
|
|
47714
48204
|
}
|
|
47715
48205
|
if (!options.force) {
|
|
47716
48206
|
try {
|
|
47717
|
-
const registry2 = createDefaultBrainProviderRegistry(
|
|
48207
|
+
const registry2 = createDefaultBrainProviderRegistry(import_node_process26.default.cwd());
|
|
47718
48208
|
const models = await registry2.listModels(provider, {
|
|
47719
48209
|
search: model,
|
|
47720
48210
|
limit: 500
|
|
@@ -47756,7 +48246,7 @@ function createModelsCommand() {
|
|
|
47756
48246
|
} else {
|
|
47757
48247
|
config2 = assignProviderToAllBrains(config2, provider.id, model);
|
|
47758
48248
|
}
|
|
47759
|
-
const outputPath = await saveConfig(config2,
|
|
48249
|
+
const outputPath = await saveConfig(config2, import_node_process26.default.cwd());
|
|
47760
48250
|
console.log(`Updated ${outputPath}`);
|
|
47761
48251
|
console.log(`Selected ${provider.id}/${model}`);
|
|
47762
48252
|
if (options.role) {
|
|
@@ -47772,7 +48262,7 @@ function createModelsCommand() {
|
|
|
47772
48262
|
}
|
|
47773
48263
|
|
|
47774
48264
|
// src/commands/plan.ts
|
|
47775
|
-
var
|
|
48265
|
+
var import_node_process27 = __toESM(require("node:process"), 1);
|
|
47776
48266
|
function createPlanCommand() {
|
|
47777
48267
|
return new Command("plan").description("Generate a structured Kimbho execution plan for the provided goal.").argument("<goal>", "High-level product or engineering goal").option("--stack <stack>", "Preferred stack or preset").option(
|
|
47778
48268
|
"--constraint <constraint>",
|
|
@@ -47780,7 +48270,7 @@ function createPlanCommand() {
|
|
|
47780
48270
|
(value, previous = []) => [...previous, value],
|
|
47781
48271
|
[]
|
|
47782
48272
|
).option("--json", "Print the plan as JSON", false).action(async (goal, options) => {
|
|
47783
|
-
const cwd =
|
|
48273
|
+
const cwd = import_node_process27.default.cwd();
|
|
47784
48274
|
const request = {
|
|
47785
48275
|
goal,
|
|
47786
48276
|
mode: "plan",
|
|
@@ -47837,8 +48327,8 @@ function createPlanCommand() {
|
|
|
47837
48327
|
}
|
|
47838
48328
|
|
|
47839
48329
|
// src/commands/permissions.ts
|
|
47840
|
-
var
|
|
47841
|
-
var
|
|
48330
|
+
var import_node_process28 = __toESM(require("node:process"), 1);
|
|
48331
|
+
var import_node_path31 = __toESM(require("node:path"), 1);
|
|
47842
48332
|
function getScope2(options) {
|
|
47843
48333
|
return options.scope === "user" ? "user" : "project";
|
|
47844
48334
|
}
|
|
@@ -47857,7 +48347,7 @@ function createPermissionsCommand() {
|
|
|
47857
48347
|
const command = new Command("permissions").description("Manage approval mode, sandbox mode, and trusted directories.");
|
|
47858
48348
|
command.command("status").description("Show permission settings.").option("--scope <scope>", "project or user", "project").action(async (options) => {
|
|
47859
48349
|
const scope = getScope2(options);
|
|
47860
|
-
const { direct, resolved } = await loadScopedConfig2(scope,
|
|
48350
|
+
const { direct, resolved } = await loadScopedConfig2(scope, import_node_process28.default.cwd());
|
|
47861
48351
|
console.log(`scope: ${scope}`);
|
|
47862
48352
|
console.log(`direct config: ${direct ? "present" : "missing"}`);
|
|
47863
48353
|
if (!resolved) {
|
|
@@ -47879,7 +48369,7 @@ function createPermissionsCommand() {
|
|
|
47879
48369
|
});
|
|
47880
48370
|
command.command("set").description("Set approval mode or sandbox mode.").option("--scope <scope>", "project or user", "project").option("--approval <mode>", "manual, on-request, plan, auto, dontAsk, acceptEdits, or bypassPermissions").option("--sandbox <mode>", "read-only, workspace-write, or full").action(async (options) => {
|
|
47881
48371
|
const scope = getScope2(options);
|
|
47882
|
-
const cwd =
|
|
48372
|
+
const cwd = import_node_process28.default.cwd();
|
|
47883
48373
|
const { direct, resolved } = await loadScopedConfig2(scope, cwd);
|
|
47884
48374
|
if (!resolved && !direct) {
|
|
47885
48375
|
throw new Error("No config found. Run `kimbho init` first.");
|
|
@@ -47899,13 +48389,13 @@ function createPermissionsCommand() {
|
|
|
47899
48389
|
});
|
|
47900
48390
|
command.command("trust").description("Add a trusted directory.").argument("<path>", "Directory to trust").option("--scope <scope>", "project or user", "project").action(async (trustedPath, options) => {
|
|
47901
48391
|
const scope = getScope2(options);
|
|
47902
|
-
const cwd =
|
|
48392
|
+
const cwd = import_node_process28.default.cwd();
|
|
47903
48393
|
const { direct, resolved } = await loadScopedConfig2(scope, cwd);
|
|
47904
48394
|
if (!resolved && !direct) {
|
|
47905
48395
|
throw new Error("No config found. Run `kimbho init` first.");
|
|
47906
48396
|
}
|
|
47907
48397
|
const base = direct ?? resolved ?? createDefaultConfig();
|
|
47908
|
-
const normalizedPath =
|
|
48398
|
+
const normalizedPath = import_node_path31.default.resolve(cwd, trustedPath);
|
|
47909
48399
|
const outputPath = await saveScopedConfig2(scope, cwd, {
|
|
47910
48400
|
...base,
|
|
47911
48401
|
trustedDirectories: Array.from(/* @__PURE__ */ new Set([
|
|
@@ -47917,13 +48407,13 @@ function createPermissionsCommand() {
|
|
|
47917
48407
|
});
|
|
47918
48408
|
command.command("untrust").description("Remove a trusted directory.").argument("<path>", "Directory to remove").option("--scope <scope>", "project or user", "project").action(async (trustedPath, options) => {
|
|
47919
48409
|
const scope = getScope2(options);
|
|
47920
|
-
const cwd =
|
|
48410
|
+
const cwd = import_node_process28.default.cwd();
|
|
47921
48411
|
const { direct, resolved } = await loadScopedConfig2(scope, cwd);
|
|
47922
48412
|
if (!resolved && !direct) {
|
|
47923
48413
|
throw new Error("No config found. Run `kimbho init` first.");
|
|
47924
48414
|
}
|
|
47925
48415
|
const base = direct ?? resolved ?? createDefaultConfig();
|
|
47926
|
-
const normalizedPath =
|
|
48416
|
+
const normalizedPath = import_node_path31.default.resolve(cwd, trustedPath);
|
|
47927
48417
|
const outputPath = await saveScopedConfig2(scope, cwd, {
|
|
47928
48418
|
...base,
|
|
47929
48419
|
trustedDirectories: base.trustedDirectories.filter((directory) => directory !== trustedPath && directory !== normalizedPath)
|
|
@@ -47934,14 +48424,14 @@ function createPermissionsCommand() {
|
|
|
47934
48424
|
}
|
|
47935
48425
|
|
|
47936
48426
|
// src/commands/providers.ts
|
|
47937
|
-
var
|
|
48427
|
+
var import_node_process29 = __toESM(require("node:process"), 1);
|
|
47938
48428
|
function requireConfigMessage3() {
|
|
47939
48429
|
throw new Error("No config found. Run `kimbho init` first.");
|
|
47940
48430
|
}
|
|
47941
48431
|
function createProvidersCommand() {
|
|
47942
48432
|
const command = new Command("providers").description("[legacy] Manage configured model providers and built-in templates.");
|
|
47943
48433
|
command.command("list").description("List configured providers.").option("--json", "Print providers as JSON", false).action(async (options) => {
|
|
47944
|
-
const config2 = await loadConfig(
|
|
48434
|
+
const config2 = await loadConfig(import_node_process29.default.cwd());
|
|
47945
48435
|
if (!config2) {
|
|
47946
48436
|
requireConfigMessage3();
|
|
47947
48437
|
}
|
|
@@ -47982,7 +48472,7 @@ function createProvidersCommand() {
|
|
|
47982
48472
|
(value, previous = []) => [...previous, value],
|
|
47983
48473
|
[]
|
|
47984
48474
|
).option("--module-path <path>", "Module path for a custom provider driver").action(async (options) => {
|
|
47985
|
-
const config2 = await loadConfig(
|
|
48475
|
+
const config2 = await loadConfig(import_node_process29.default.cwd());
|
|
47986
48476
|
if (!config2) {
|
|
47987
48477
|
requireConfigMessage3();
|
|
47988
48478
|
}
|
|
@@ -48016,16 +48506,16 @@ function createProvidersCommand() {
|
|
|
48016
48506
|
} : {}
|
|
48017
48507
|
});
|
|
48018
48508
|
const nextConfig = upsertProvider(config2, provider);
|
|
48019
|
-
const outputPath = await saveConfig(nextConfig,
|
|
48509
|
+
const outputPath = await saveConfig(nextConfig, import_node_process29.default.cwd());
|
|
48020
48510
|
console.log(`Updated ${outputPath}`);
|
|
48021
48511
|
console.log(`Provider ${provider.id} -> ${provider.driver}`);
|
|
48022
48512
|
});
|
|
48023
48513
|
command.command("check").description("Run health checks for the configured providers.").action(async () => {
|
|
48024
|
-
const config2 = await loadConfig(
|
|
48514
|
+
const config2 = await loadConfig(import_node_process29.default.cwd());
|
|
48025
48515
|
if (!config2) {
|
|
48026
48516
|
requireConfigMessage3();
|
|
48027
48517
|
}
|
|
48028
|
-
const registry2 = createDefaultBrainProviderRegistry(
|
|
48518
|
+
const registry2 = createDefaultBrainProviderRegistry(import_node_process29.default.cwd());
|
|
48029
48519
|
for (const provider of config2.providers) {
|
|
48030
48520
|
try {
|
|
48031
48521
|
const result = await registry2.healthCheck(provider);
|
|
@@ -48040,10 +48530,10 @@ function createProvidersCommand() {
|
|
|
48040
48530
|
}
|
|
48041
48531
|
|
|
48042
48532
|
// src/commands/review.ts
|
|
48043
|
-
var
|
|
48533
|
+
var import_node_process30 = __toESM(require("node:process"), 1);
|
|
48044
48534
|
function createReviewCommand() {
|
|
48045
48535
|
return new Command("review").description("Review the current diff, summarize changed files, and surface risks.").option("--json", "Print the review payload as JSON", false).option("--patch <path>", "Review a patch file instead of the current git diff").action(async (options) => {
|
|
48046
|
-
const cwd =
|
|
48536
|
+
const cwd = import_node_process30.default.cwd();
|
|
48047
48537
|
const payload = await reviewWorkspace(cwd, {
|
|
48048
48538
|
patchPath: options.patch
|
|
48049
48539
|
});
|
|
@@ -48076,8 +48566,8 @@ function createReviewCommand() {
|
|
|
48076
48566
|
}
|
|
48077
48567
|
|
|
48078
48568
|
// src/commands/resume.ts
|
|
48079
|
-
var
|
|
48080
|
-
function
|
|
48569
|
+
var import_node_process31 = __toESM(require("node:process"), 1);
|
|
48570
|
+
function parseCount5(value) {
|
|
48081
48571
|
const parsed = Number(value);
|
|
48082
48572
|
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
48083
48573
|
throw new Error(`Expected a positive integer, received "${value}".`);
|
|
@@ -48085,8 +48575,8 @@ function parseCount4(value) {
|
|
|
48085
48575
|
return parsed;
|
|
48086
48576
|
}
|
|
48087
48577
|
function createResumeCommand() {
|
|
48088
|
-
return new Command("resume").alias("continue").description("Resume the latest saved Kimbho session snapshot.").argument("[sessionId]", "Optional session id; defaults to the latest session").option("--json", "Print the latest session as JSON", false).option("--last", "Resume the most recent session", false).option("--list", "List recent sessions and exit", false).option("--search <query>", "Filter sessions by id, goal, cwd, or labels").option("--pr <query>", "Filter sessions by linked PR url, repo, or number").option("--execute", "Continue auto-executing the ready-task frontier", false).option("--approve <approvalId>", "Approve a pending action before continuing").option("--deny <approvalId>", "Deny a pending action before continuing").option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute",
|
|
48089
|
-
const cwd =
|
|
48578
|
+
return new Command("resume").alias("continue").description("Resume the latest saved Kimbho session snapshot.").argument("[sessionId]", "Optional session id; defaults to the latest session").option("--json", "Print the latest session as JSON", false).option("--last", "Resume the most recent session", false).option("--list", "List recent sessions and exit", false).option("--search <query>", "Filter sessions by id, goal, cwd, or labels").option("--pr <query>", "Filter sessions by linked PR url, repo, or number").option("--execute", "Continue auto-executing the ready-task frontier", false).option("--approve <approvalId>", "Approve a pending action before continuing").option("--deny <approvalId>", "Deny a pending action before continuing").option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount5, 4).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount5, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount5, 2).option("--max-tool-calls <count>", "Maximum tool calls per autonomous task", parseCount5).option("--max-model-calls <count>", "Maximum model calls per autonomous task", parseCount5).option("--max-input-tokens <count>", "Maximum input tokens per autonomous task", parseCount5).option("--max-output-tokens <count>", "Maximum output tokens per autonomous task", parseCount5).action(async (sessionId, options) => {
|
|
48579
|
+
const cwd = import_node_process31.default.cwd();
|
|
48090
48580
|
const effectiveSearch = options.pr?.trim() || options.search?.trim();
|
|
48091
48581
|
const firstSearchMatch = effectiveSearch ? (await searchSessions(effectiveSearch, cwd, 1)).at(0) ?? null : null;
|
|
48092
48582
|
if (options.list) {
|
|
@@ -48111,12 +48601,12 @@ function createResumeCommand() {
|
|
|
48111
48601
|
const session = effectiveSearch && !sessionId && !options.last ? firstSearchMatch ? await loadSessionById(firstSearchMatch.id, cwd) : null : options.last || !sessionId ? await loadLatestSession(cwd) : await loadSessionById(sessionId, cwd);
|
|
48112
48602
|
if (!session) {
|
|
48113
48603
|
console.error("No saved session found. Run `kimbho run` first.");
|
|
48114
|
-
|
|
48604
|
+
import_node_process31.default.exitCode = 1;
|
|
48115
48605
|
return;
|
|
48116
48606
|
}
|
|
48117
48607
|
if (options.approve && options.deny) {
|
|
48118
48608
|
console.error("Pass only one of --approve or --deny.");
|
|
48119
|
-
|
|
48609
|
+
import_node_process31.default.exitCode = 1;
|
|
48120
48610
|
return;
|
|
48121
48611
|
}
|
|
48122
48612
|
const snapshot = options.execute ? await new ExecutionOrchestrator().continueSession(session, {
|
|
@@ -48163,7 +48653,7 @@ function createResumeCommand() {
|
|
|
48163
48653
|
}
|
|
48164
48654
|
|
|
48165
48655
|
// src/commands/run.ts
|
|
48166
|
-
var
|
|
48656
|
+
var import_node_process32 = __toESM(require("node:process"), 1);
|
|
48167
48657
|
|
|
48168
48658
|
// src/pr-link.ts
|
|
48169
48659
|
function inferProvider(hostname2) {
|
|
@@ -48206,7 +48696,7 @@ function parsePrLinkFromUrl(value, overrides = {}) {
|
|
|
48206
48696
|
}
|
|
48207
48697
|
|
|
48208
48698
|
// src/commands/run.ts
|
|
48209
|
-
function
|
|
48699
|
+
function parseCount6(value) {
|
|
48210
48700
|
const parsed = Number(value);
|
|
48211
48701
|
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
48212
48702
|
throw new Error(`Expected a positive integer, received "${value}".`);
|
|
@@ -48219,8 +48709,8 @@ function createRunCommand() {
|
|
|
48219
48709
|
"Explicit execution constraint; can be provided multiple times",
|
|
48220
48710
|
(value, previous = []) => [...previous, value],
|
|
48221
48711
|
[]
|
|
48222
|
-
).option("--json", "Print the session snapshot as JSON", false).option("--snapshot-only", "Create the session without auto-executing ready tasks", false).option("--agent <id>", "Prefer one custom or plugin agent id for this session").option("--agents <jsonOrPath>", "Inline agent definitions as JSON or a path to a JSON file").option("--session-id <id>", "Use an explicit session id").option("--pr-url <url>", "Link this session to a pull request URL").option("--ephemeral", "Do not persist plans or sessions for this invocation", false).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute",
|
|
48223
|
-
const cwd =
|
|
48712
|
+
).option("--json", "Print the session snapshot as JSON", false).option("--snapshot-only", "Create the session without auto-executing ready tasks", false).option("--agent <id>", "Prefer one custom or plugin agent id for this session").option("--agents <jsonOrPath>", "Inline agent definitions as JSON or a path to a JSON file").option("--session-id <id>", "Use an explicit session id").option("--pr-url <url>", "Link this session to a pull request URL").option("--ephemeral", "Do not persist plans or sessions for this invocation", false).option("--max-auto-tasks <count>", "Maximum ready tasks to auto-execute", parseCount6, 4).option("--max-agent-steps <count>", "Maximum tool/model steps per autonomous task", parseCount6, 8).option("--max-repair-attempts <count>", "Maximum failed verification cycles per autonomous task", parseCount6, 2).option("--max-tool-calls <count>", "Maximum tool calls per autonomous task", parseCount6).option("--max-model-calls <count>", "Maximum model calls per autonomous task", parseCount6).option("--max-input-tokens <count>", "Maximum input tokens per autonomous task", parseCount6).option("--max-output-tokens <count>", "Maximum output tokens per autonomous task", parseCount6).action(async (goal, options) => {
|
|
48713
|
+
const cwd = import_node_process32.default.cwd();
|
|
48224
48714
|
const orchestrator = new ExecutionOrchestrator();
|
|
48225
48715
|
const agentSelection = await resolveAgentSelection(cwd, {
|
|
48226
48716
|
agent: options.agent,
|
|
@@ -48232,7 +48722,7 @@ function createRunCommand() {
|
|
|
48232
48722
|
let planResult = null;
|
|
48233
48723
|
if (!plan && !goal) {
|
|
48234
48724
|
console.error("No saved plan found. Pass a goal or run `kimbho plan` first.");
|
|
48235
|
-
|
|
48725
|
+
import_node_process32.default.exitCode = 1;
|
|
48236
48726
|
return;
|
|
48237
48727
|
}
|
|
48238
48728
|
if (goal) {
|
|
@@ -48337,7 +48827,7 @@ function createRunCommand() {
|
|
|
48337
48827
|
}
|
|
48338
48828
|
|
|
48339
48829
|
// src/commands/skills.ts
|
|
48340
|
-
var
|
|
48830
|
+
var import_node_process33 = __toESM(require("node:process"), 1);
|
|
48341
48831
|
function renderMetadataBlock(metadata) {
|
|
48342
48832
|
return [
|
|
48343
48833
|
` userInvocable: ${String(metadata.userInvocable)}`,
|
|
@@ -48355,7 +48845,7 @@ function renderOriginLabel(definition) {
|
|
|
48355
48845
|
function createSkillsCommand() {
|
|
48356
48846
|
const command = new Command("skills").description("Inspect Kimbho-native skill packs and command packs, with .claude fallback compatibility.");
|
|
48357
48847
|
command.action(async () => {
|
|
48358
|
-
const skills = await listClaudeSkills(
|
|
48848
|
+
const skills = await listClaudeSkills(import_node_process33.default.cwd());
|
|
48359
48849
|
if (skills.length === 0) {
|
|
48360
48850
|
console.log("No skill packs discovered.");
|
|
48361
48851
|
return;
|
|
@@ -48366,7 +48856,7 @@ function createSkillsCommand() {
|
|
|
48366
48856
|
}
|
|
48367
48857
|
});
|
|
48368
48858
|
command.command("list").description("List discovered skill packs from .kimbho/skills and .claude/skills.").action(async () => {
|
|
48369
|
-
const skills = await listClaudeSkills(
|
|
48859
|
+
const skills = await listClaudeSkills(import_node_process33.default.cwd());
|
|
48370
48860
|
if (skills.length === 0) {
|
|
48371
48861
|
console.log("No skill packs discovered.");
|
|
48372
48862
|
return;
|
|
@@ -48377,7 +48867,7 @@ function createSkillsCommand() {
|
|
|
48377
48867
|
}
|
|
48378
48868
|
});
|
|
48379
48869
|
command.command("commands").description("List discovered command packs from .kimbho/commands and .claude/commands.").option("--all", "Include commands marked user-invocable=false", false).action(async (options) => {
|
|
48380
|
-
const commands = await listClaudeCommands(
|
|
48870
|
+
const commands = await listClaudeCommands(import_node_process33.default.cwd(), {
|
|
48381
48871
|
includeHidden: Boolean(options.all)
|
|
48382
48872
|
});
|
|
48383
48873
|
if (commands.length === 0) {
|
|
@@ -48390,7 +48880,7 @@ function createSkillsCommand() {
|
|
|
48390
48880
|
}
|
|
48391
48881
|
});
|
|
48392
48882
|
command.command("inspect").description("Inspect one skill pack entry.").argument("<id>", "Skill id").action(async (id) => {
|
|
48393
|
-
const skill = await loadClaudeSkillById(
|
|
48883
|
+
const skill = await loadClaudeSkillById(import_node_process33.default.cwd(), id);
|
|
48394
48884
|
if (!skill) {
|
|
48395
48885
|
throw new Error(`Unknown skill "${id}".`);
|
|
48396
48886
|
}
|
|
@@ -48403,7 +48893,7 @@ function createSkillsCommand() {
|
|
|
48403
48893
|
}
|
|
48404
48894
|
});
|
|
48405
48895
|
command.command("inspect-command").description("Inspect one command pack entry.").argument("<name>", "Command name").action(async (name) => {
|
|
48406
|
-
const definition = await loadClaudeCommandByName(
|
|
48896
|
+
const definition = await loadClaudeCommandByName(import_node_process33.default.cwd(), name, {
|
|
48407
48897
|
includeHidden: true
|
|
48408
48898
|
});
|
|
48409
48899
|
if (!definition) {
|
|
@@ -48418,7 +48908,7 @@ function createSkillsCommand() {
|
|
|
48418
48908
|
}
|
|
48419
48909
|
});
|
|
48420
48910
|
command.command("render-command").description("Render one command pack entry with arguments, without executing it.").argument("<name>", "Command name").argument("[args...]", "Arguments to substitute into the command body").action(async (name, args = []) => {
|
|
48421
|
-
const invocation = await resolveClaudeCommandInvocation(
|
|
48911
|
+
const invocation = await resolveClaudeCommandInvocation(import_node_process33.default.cwd(), [
|
|
48422
48912
|
name,
|
|
48423
48913
|
...args
|
|
48424
48914
|
]);
|
|
@@ -48432,8 +48922,8 @@ function createSkillsCommand() {
|
|
|
48432
48922
|
|
|
48433
48923
|
// src/commands/worktree.ts
|
|
48434
48924
|
var import_promises26 = require("node:fs/promises");
|
|
48435
|
-
var
|
|
48436
|
-
var
|
|
48925
|
+
var import_node_path32 = __toESM(require("node:path"), 1);
|
|
48926
|
+
var import_node_process34 = __toESM(require("node:process"), 1);
|
|
48437
48927
|
var import_node_child_process12 = require("node:child_process");
|
|
48438
48928
|
function sanitizeName3(value) {
|
|
48439
48929
|
return value.replace(/[^a-zA-Z0-9._-]+/g, "-").slice(0, 80);
|
|
@@ -48442,10 +48932,10 @@ function storedWorktreeName(name) {
|
|
|
48442
48932
|
return sanitizeName3(`manual-${name}`);
|
|
48443
48933
|
}
|
|
48444
48934
|
function resolveStoredWorktreePath(cwd, name) {
|
|
48445
|
-
return
|
|
48935
|
+
return import_node_path32.default.join(resolveKimbhoDir(cwd), "worktrees", storedWorktreeName(name));
|
|
48446
48936
|
}
|
|
48447
48937
|
function resolveStoredPatchPath(cwd, name) {
|
|
48448
|
-
return
|
|
48938
|
+
return import_node_path32.default.join(resolveKimbhoDir(cwd), "logs", `${storedWorktreeName(name)}.patch`);
|
|
48449
48939
|
}
|
|
48450
48940
|
async function resolveStoredWorktree(cwd, name) {
|
|
48451
48941
|
const worktreePath = resolveStoredWorktreePath(cwd, name);
|
|
@@ -48471,14 +48961,14 @@ function gitRun(cwd, args) {
|
|
|
48471
48961
|
function createWorktreeCommand() {
|
|
48472
48962
|
const command = new Command("worktree").description("Manage user-visible isolated worktrees and apply their diffs back.");
|
|
48473
48963
|
command.command("list").description("List Kimbho-managed worktrees.").option("--json", "Print the worktree payload as JSON", false).action(async (options) => {
|
|
48474
|
-
const dir =
|
|
48964
|
+
const dir = import_node_path32.default.join(resolveKimbhoDir(import_node_process34.default.cwd()), "worktrees");
|
|
48475
48965
|
const entries = await (0, import_promises26.readdir)(dir, {
|
|
48476
48966
|
withFileTypes: true
|
|
48477
48967
|
}).catch(() => []);
|
|
48478
48968
|
const worktrees = entries.filter((entry) => entry.isDirectory()).map((entry) => ({
|
|
48479
48969
|
id: entry.name.replace(/^manual-/, ""),
|
|
48480
|
-
worktreePath:
|
|
48481
|
-
patchPath:
|
|
48970
|
+
worktreePath: import_node_path32.default.join(dir, entry.name),
|
|
48971
|
+
patchPath: import_node_path32.default.join(resolveKimbhoDir(import_node_process34.default.cwd()), "logs", `${entry.name}.patch`)
|
|
48482
48972
|
}));
|
|
48483
48973
|
if (options.json) {
|
|
48484
48974
|
console.log(JSON.stringify(worktrees, null, 2));
|
|
@@ -48495,7 +48985,7 @@ function createWorktreeCommand() {
|
|
|
48495
48985
|
}
|
|
48496
48986
|
});
|
|
48497
48987
|
command.command("create").description("Create one user-visible isolated worktree.").argument("<name>", "Worktree name").option("--json", "Print the worktree payload as JSON", false).action(async (name, options) => {
|
|
48498
|
-
const worktree = await createIsolatedWorktree(
|
|
48988
|
+
const worktree = await createIsolatedWorktree(import_node_process34.default.cwd(), "manual", name);
|
|
48499
48989
|
if (!worktree) {
|
|
48500
48990
|
throw new Error("This workspace is not a git repo with a valid HEAD. Worktrees require git history.");
|
|
48501
48991
|
}
|
|
@@ -48507,19 +48997,19 @@ function createWorktreeCommand() {
|
|
|
48507
48997
|
console.log(`Patch artifact: ${worktree.patchArtifactPath}`);
|
|
48508
48998
|
});
|
|
48509
48999
|
command.command("diff").description("Inspect the current diff inside one managed worktree.").argument("<name>", "Worktree name").option("--stat", "Show only diff stats", false).action(async (name, options) => {
|
|
48510
|
-
const worktree = await resolveStoredWorktree(
|
|
49000
|
+
const worktree = await resolveStoredWorktree(import_node_process34.default.cwd(), name);
|
|
48511
49001
|
const args = options.stat ? ["diff", "--stat", "HEAD"] : ["diff", "--binary", "--full-index", "--no-ext-diff", "--stat", "--patch", "HEAD"];
|
|
48512
49002
|
const result = gitRun(worktree.worktreePath, args);
|
|
48513
49003
|
if (!result.ok) {
|
|
48514
49004
|
console.error(result.detail);
|
|
48515
|
-
|
|
49005
|
+
import_node_process34.default.exitCode = 1;
|
|
48516
49006
|
return;
|
|
48517
49007
|
}
|
|
48518
49008
|
console.log(result.stdout.trim() || "No diff.");
|
|
48519
49009
|
});
|
|
48520
49010
|
command.command("apply").description("Apply one managed worktree back into the main workspace and clean it up.").argument("<name>", "Worktree name").option("--json", "Print the integration payload as JSON", false).action(async (name, options) => {
|
|
48521
|
-
const worktree = await resolveStoredWorktree(
|
|
48522
|
-
const result = await integrateIsolatedWorktree(
|
|
49011
|
+
const worktree = await resolveStoredWorktree(import_node_process34.default.cwd(), name);
|
|
49012
|
+
const result = await integrateIsolatedWorktree(import_node_process34.default.cwd(), worktree, [], []);
|
|
48523
49013
|
if (options.json) {
|
|
48524
49014
|
console.log(JSON.stringify(result, null, 2));
|
|
48525
49015
|
return;
|
|
@@ -48531,11 +49021,11 @@ function createWorktreeCommand() {
|
|
|
48531
49021
|
console.log(`artifact: ${artifact}`);
|
|
48532
49022
|
}
|
|
48533
49023
|
if (result.integrationFailed) {
|
|
48534
|
-
|
|
49024
|
+
import_node_process34.default.exitCode = 1;
|
|
48535
49025
|
}
|
|
48536
49026
|
});
|
|
48537
49027
|
command.command("remove").description("Delete one managed worktree without applying it back.").argument("<name>", "Worktree name").option("--json", "Print the removal payload as JSON", false).action(async (name, options) => {
|
|
48538
|
-
const cwd =
|
|
49028
|
+
const cwd = import_node_process34.default.cwd();
|
|
48539
49029
|
const worktreePath = resolveStoredWorktreePath(cwd, name);
|
|
48540
49030
|
const removal = gitRun(cwd, [
|
|
48541
49031
|
"worktree",
|
|
@@ -48565,20 +49055,6 @@ function createWorktreeCommand() {
|
|
|
48565
49055
|
return command;
|
|
48566
49056
|
}
|
|
48567
49057
|
|
|
48568
|
-
// src/commands/placeholders.ts
|
|
48569
|
-
function createPlaceholder(name, description, milestone) {
|
|
48570
|
-
return new Command(name).description(description).action(() => {
|
|
48571
|
-
console.log(`${name} is planned for ${milestone}.`);
|
|
48572
|
-
});
|
|
48573
|
-
}
|
|
48574
|
-
function createFixCommand() {
|
|
48575
|
-
return createPlaceholder(
|
|
48576
|
-
"fix",
|
|
48577
|
-
"Diagnose and repair a failing repository state.",
|
|
48578
|
-
"Milestone 4: Executor Loop"
|
|
48579
|
-
);
|
|
48580
|
-
}
|
|
48581
|
-
|
|
48582
49058
|
// src/program.ts
|
|
48583
49059
|
var MODELS_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
48584
49060
|
"help",
|
|
@@ -48705,10 +49181,10 @@ function createProgram(onOpenShell) {
|
|
|
48705
49181
|
}
|
|
48706
49182
|
|
|
48707
49183
|
// src/runtime-flags.ts
|
|
48708
|
-
var
|
|
48709
|
-
var
|
|
49184
|
+
var import_node_path33 = __toESM(require("node:path"), 1);
|
|
49185
|
+
var import_node_process35 = __toESM(require("node:process"), 1);
|
|
48710
49186
|
function parseJsonEnv2(name, fallback) {
|
|
48711
|
-
const raw =
|
|
49187
|
+
const raw = import_node_process35.default.env[name];
|
|
48712
49188
|
if (!raw || raw.trim().length === 0) {
|
|
48713
49189
|
return fallback;
|
|
48714
49190
|
}
|
|
@@ -48792,7 +49268,7 @@ function readOptionValue(tokens, index, label) {
|
|
|
48792
49268
|
return value;
|
|
48793
49269
|
}
|
|
48794
49270
|
function applyRuntimeFlags(tokens) {
|
|
48795
|
-
const initialCwd =
|
|
49271
|
+
const initialCwd = import_node_process35.default.cwd();
|
|
48796
49272
|
const remaining = [];
|
|
48797
49273
|
const overrides = parseJsonEnv2(
|
|
48798
49274
|
KIMBHO_RUNTIME_OVERRIDES_ENV,
|
|
@@ -48803,7 +49279,7 @@ function applyRuntimeFlags(tokens) {
|
|
|
48803
49279
|
[]
|
|
48804
49280
|
);
|
|
48805
49281
|
let nextCwd = null;
|
|
48806
|
-
let selectedProfile =
|
|
49282
|
+
let selectedProfile = import_node_process35.default.env[KIMBHO_RUNTIME_PROFILE_ENV] ?? null;
|
|
48807
49283
|
let forceExec = false;
|
|
48808
49284
|
let index = 0;
|
|
48809
49285
|
while (index < tokens.length) {
|
|
@@ -48901,14 +49377,14 @@ function applyRuntimeFlags(tokens) {
|
|
|
48901
49377
|
break;
|
|
48902
49378
|
}
|
|
48903
49379
|
if (nextCwd) {
|
|
48904
|
-
|
|
49380
|
+
import_node_process35.default.chdir(import_node_path33.default.resolve(initialCwd, nextCwd));
|
|
48905
49381
|
}
|
|
48906
49382
|
if (selectedProfile) {
|
|
48907
|
-
|
|
49383
|
+
import_node_process35.default.env[KIMBHO_RUNTIME_PROFILE_ENV] = selectedProfile;
|
|
48908
49384
|
}
|
|
48909
|
-
|
|
48910
|
-
|
|
48911
|
-
additionalDirectories.map((directory) =>
|
|
49385
|
+
import_node_process35.default.env[KIMBHO_RUNTIME_OVERRIDES_ENV] = JSON.stringify(overrides);
|
|
49386
|
+
import_node_process35.default.env[KIMBHO_RUNTIME_ADDITIONAL_DIRS_ENV] = JSON.stringify(
|
|
49387
|
+
additionalDirectories.map((directory) => import_node_path33.default.resolve(import_node_process35.default.cwd(), directory))
|
|
48912
49388
|
);
|
|
48913
49389
|
return {
|
|
48914
49390
|
tokens: remaining,
|
|
@@ -48920,8 +49396,8 @@ function applyRuntimeFlags(tokens) {
|
|
|
48920
49396
|
var import_node_child_process13 = require("node:child_process");
|
|
48921
49397
|
var import_node_readline2 = require("node:readline");
|
|
48922
49398
|
var import_promises27 = require("node:readline/promises");
|
|
48923
|
-
var
|
|
48924
|
-
var
|
|
49399
|
+
var import_node_path34 = __toESM(require("node:path"), 1);
|
|
49400
|
+
var import_node_process36 = __toESM(require("node:process"), 1);
|
|
48925
49401
|
|
|
48926
49402
|
// src/agent-management.ts
|
|
48927
49403
|
async function renderCustomAgents(cwd) {
|
|
@@ -49095,7 +49571,7 @@ function renderShimmeringLabel(label, frameIndex) {
|
|
|
49095
49571
|
}).join("");
|
|
49096
49572
|
}
|
|
49097
49573
|
function readRuntimeOverrideEntries() {
|
|
49098
|
-
const raw =
|
|
49574
|
+
const raw = import_node_process36.default.env[KIMBHO_RUNTIME_OVERRIDES_ENV];
|
|
49099
49575
|
if (!raw || raw.trim().length === 0) {
|
|
49100
49576
|
return [];
|
|
49101
49577
|
}
|
|
@@ -49113,7 +49589,7 @@ function readRuntimeOverrideEntries() {
|
|
|
49113
49589
|
}
|
|
49114
49590
|
}
|
|
49115
49591
|
function readAdditionalDirectories2() {
|
|
49116
|
-
const raw =
|
|
49592
|
+
const raw = import_node_process36.default.env[KIMBHO_RUNTIME_ADDITIONAL_DIRS_ENV];
|
|
49117
49593
|
if (!raw || raw.trim().length === 0) {
|
|
49118
49594
|
return [];
|
|
49119
49595
|
}
|
|
@@ -49149,17 +49625,17 @@ function syncShellRuntimeOverrides(runtime) {
|
|
|
49149
49625
|
] : []
|
|
49150
49626
|
];
|
|
49151
49627
|
if (merged.length === 0) {
|
|
49152
|
-
delete
|
|
49628
|
+
delete import_node_process36.default.env[KIMBHO_RUNTIME_OVERRIDES_ENV];
|
|
49153
49629
|
return;
|
|
49154
49630
|
}
|
|
49155
|
-
|
|
49631
|
+
import_node_process36.default.env[KIMBHO_RUNTIME_OVERRIDES_ENV] = JSON.stringify(merged);
|
|
49156
49632
|
}
|
|
49157
49633
|
function syncShellAdditionalDirectories(runtime) {
|
|
49158
49634
|
if (runtime.additionalDirectories.length === 0) {
|
|
49159
|
-
delete
|
|
49635
|
+
delete import_node_process36.default.env[KIMBHO_RUNTIME_ADDITIONAL_DIRS_ENV];
|
|
49160
49636
|
return;
|
|
49161
49637
|
}
|
|
49162
|
-
|
|
49638
|
+
import_node_process36.default.env[KIMBHO_RUNTIME_ADDITIONAL_DIRS_ENV] = JSON.stringify(runtime.additionalDirectories);
|
|
49163
49639
|
}
|
|
49164
49640
|
function resolveRuntimeOverrideApprovalMode(runtime) {
|
|
49165
49641
|
if (runtime.sessionApprovalModeOverride) {
|
|
@@ -49341,7 +49817,7 @@ var ShellActivityIndicator = class {
|
|
|
49341
49817
|
this.label = label;
|
|
49342
49818
|
}
|
|
49343
49819
|
start() {
|
|
49344
|
-
if (!
|
|
49820
|
+
if (!import_node_process36.default.stdout.isTTY || this.interval) {
|
|
49345
49821
|
return;
|
|
49346
49822
|
}
|
|
49347
49823
|
this.activeLine = true;
|
|
@@ -49362,13 +49838,13 @@ var ShellActivityIndicator = class {
|
|
|
49362
49838
|
}
|
|
49363
49839
|
}
|
|
49364
49840
|
suspend() {
|
|
49365
|
-
if (!
|
|
49841
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49366
49842
|
return;
|
|
49367
49843
|
}
|
|
49368
49844
|
this.clear();
|
|
49369
49845
|
}
|
|
49370
49846
|
resume() {
|
|
49371
|
-
if (!
|
|
49847
|
+
if (!import_node_process36.default.stdout.isTTY || !this.interval) {
|
|
49372
49848
|
return;
|
|
49373
49849
|
}
|
|
49374
49850
|
this.render();
|
|
@@ -49382,7 +49858,7 @@ var ShellActivityIndicator = class {
|
|
|
49382
49858
|
this.activeLine = false;
|
|
49383
49859
|
}
|
|
49384
49860
|
render() {
|
|
49385
|
-
if (!
|
|
49861
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49386
49862
|
return;
|
|
49387
49863
|
}
|
|
49388
49864
|
const frame = color(AMBER, SPINNER_FRAMES[this.animationTick % SPINNER_FRAMES.length]);
|
|
@@ -49390,15 +49866,15 @@ var ShellActivityIndicator = class {
|
|
|
49390
49866
|
const dots = color(DIM, ELLIPSIS_FRAMES[this.animationTick % ELLIPSIS_FRAMES.length]);
|
|
49391
49867
|
const raw = `${frame} ${status}${dots}`;
|
|
49392
49868
|
this.clear();
|
|
49393
|
-
(0, import_node_readline2.cursorTo)(
|
|
49394
|
-
|
|
49869
|
+
(0, import_node_readline2.cursorTo)(import_node_process36.default.stdout, 0);
|
|
49870
|
+
import_node_process36.default.stdout.write(raw);
|
|
49395
49871
|
}
|
|
49396
49872
|
clear() {
|
|
49397
|
-
if (!
|
|
49873
|
+
if (!import_node_process36.default.stdout.isTTY || !this.activeLine) {
|
|
49398
49874
|
return;
|
|
49399
49875
|
}
|
|
49400
|
-
(0, import_node_readline2.cursorTo)(
|
|
49401
|
-
(0, import_node_readline2.clearLine)(
|
|
49876
|
+
(0, import_node_readline2.cursorTo)(import_node_process36.default.stdout, 0);
|
|
49877
|
+
(0, import_node_readline2.clearLine)(import_node_process36.default.stdout, 0);
|
|
49402
49878
|
}
|
|
49403
49879
|
};
|
|
49404
49880
|
var ShellExecutionTui = class {
|
|
@@ -49417,12 +49893,12 @@ var ShellExecutionTui = class {
|
|
|
49417
49893
|
this.render();
|
|
49418
49894
|
};
|
|
49419
49895
|
start() {
|
|
49420
|
-
if (!
|
|
49896
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49421
49897
|
return;
|
|
49422
49898
|
}
|
|
49423
49899
|
if (this.ownsScreen) {
|
|
49424
|
-
|
|
49425
|
-
|
|
49900
|
+
import_node_process36.default.stdout.write(`${ALT_SCREEN_ENTER}${HIDE_CURSOR}${CLEAR_SCREEN}${HOME_CURSOR}`);
|
|
49901
|
+
import_node_process36.default.stdout.on("resize", this.handleResize);
|
|
49426
49902
|
}
|
|
49427
49903
|
this.render();
|
|
49428
49904
|
this.interval = setInterval(() => {
|
|
@@ -49436,12 +49912,12 @@ var ShellExecutionTui = class {
|
|
|
49436
49912
|
clearInterval(this.interval);
|
|
49437
49913
|
this.interval = null;
|
|
49438
49914
|
}
|
|
49439
|
-
if (!
|
|
49915
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49440
49916
|
return;
|
|
49441
49917
|
}
|
|
49442
49918
|
if (this.ownsScreen) {
|
|
49443
|
-
|
|
49444
|
-
|
|
49919
|
+
import_node_process36.default.stdout.off("resize", this.handleResize);
|
|
49920
|
+
import_node_process36.default.stdout.write(`${SHOW_CURSOR}${ALT_SCREEN_EXIT}`);
|
|
49445
49921
|
}
|
|
49446
49922
|
}
|
|
49447
49923
|
updateActivity(label) {
|
|
@@ -49462,11 +49938,11 @@ var ShellExecutionTui = class {
|
|
|
49462
49938
|
this.render();
|
|
49463
49939
|
}
|
|
49464
49940
|
render() {
|
|
49465
|
-
if (!
|
|
49941
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49466
49942
|
return;
|
|
49467
49943
|
}
|
|
49468
|
-
const columns = Math.max(
|
|
49469
|
-
const rows = Math.max(
|
|
49944
|
+
const columns = Math.max(import_node_process36.default.stdout.columns ?? 100, 72);
|
|
49945
|
+
const rows = Math.max(import_node_process36.default.stdout.rows ?? 36, 24);
|
|
49470
49946
|
const headerLines = [
|
|
49471
49947
|
color(BOLD, "Kimbho Execution"),
|
|
49472
49948
|
color(DIM, `session ${shortenMiddle(this.board.sessionId, Math.max(20, columns - 12))}`),
|
|
@@ -49477,6 +49953,10 @@ var ShellExecutionTui = class {
|
|
|
49477
49953
|
const footerLines = [
|
|
49478
49954
|
"",
|
|
49479
49955
|
`${color(AMBER, SPINNER_FRAMES[this.animationTick % SPINNER_FRAMES.length])} ${renderShimmeringLabel(this.activityLabel, this.animationTick)}${color(DIM, ELLIPSIS_FRAMES[this.animationTick % ELLIPSIS_FRAMES.length])} `,
|
|
49956
|
+
...this.board.approvals > 0 ? [
|
|
49957
|
+
color(DIM, renderApprovalCommandHint()),
|
|
49958
|
+
color(DIM, renderApprovalShortcutHint(this.board.approvals))
|
|
49959
|
+
] : [],
|
|
49480
49960
|
color(DIM, "Ctrl+C pauses the run and returns to the shell. A concise summary prints after the run exits.")
|
|
49481
49961
|
];
|
|
49482
49962
|
const chromeLines = headerLines.length + boardLines.length + footerLines.length + 1;
|
|
@@ -49494,7 +49974,7 @@ var ShellExecutionTui = class {
|
|
|
49494
49974
|
while (paddedLines.length < rows) {
|
|
49495
49975
|
paddedLines.push("");
|
|
49496
49976
|
}
|
|
49497
|
-
|
|
49977
|
+
import_node_process36.default.stdout.write(`${CLEAR_SCREEN}${HOME_CURSOR}${paddedLines.join("\n")}`);
|
|
49498
49978
|
}
|
|
49499
49979
|
};
|
|
49500
49980
|
function renderExecutionTelemetry(telemetry, startedAt) {
|
|
@@ -49631,6 +50111,8 @@ function renderBanner() {
|
|
|
49631
50111
|
}
|
|
49632
50112
|
async function getShellSessionState(cwd, focusRole, runtime) {
|
|
49633
50113
|
const config2 = await loadConfig(cwd);
|
|
50114
|
+
const latestSession = await loadLatestSession(cwd).catch(() => null);
|
|
50115
|
+
const pendingApprovals = latestSession?.pendingApprovals ?? [];
|
|
49634
50116
|
if (!config2) {
|
|
49635
50117
|
return {
|
|
49636
50118
|
focusRole,
|
|
@@ -49642,7 +50124,8 @@ async function getShellSessionState(cwd, focusRole, runtime) {
|
|
|
49642
50124
|
approvalMode: "manual",
|
|
49643
50125
|
sandboxMode: "workspace-write",
|
|
49644
50126
|
stackPreset: "next-prisma-postgres",
|
|
49645
|
-
configured: false
|
|
50127
|
+
configured: false,
|
|
50128
|
+
pendingApprovals
|
|
49646
50129
|
};
|
|
49647
50130
|
}
|
|
49648
50131
|
const focusSettings = config2.brains[focusRole];
|
|
@@ -49657,7 +50140,8 @@ async function getShellSessionState(cwd, focusRole, runtime) {
|
|
|
49657
50140
|
approvalMode: runtime?.sessionApprovalModeOverride ? `${runtime.sessionApprovalModeOverride} (session override)` : config2.approvalMode,
|
|
49658
50141
|
sandboxMode: runtime?.sessionSandboxModeOverride ? `${runtime.sessionSandboxModeOverride} (session override)` : config2.sandboxMode,
|
|
49659
50142
|
stackPreset: config2.stackPresets[0] ?? "none",
|
|
49660
|
-
configured: true
|
|
50143
|
+
configured: true,
|
|
50144
|
+
pendingApprovals
|
|
49661
50145
|
};
|
|
49662
50146
|
}
|
|
49663
50147
|
function renderCardLine(label, value) {
|
|
@@ -49746,8 +50230,8 @@ function renderHelp() {
|
|
|
49746
50230
|
"/permissions sandbox <mode> Set read-only, workspace-write, or full.",
|
|
49747
50231
|
"/permissions trust <path> Add a trusted directory.",
|
|
49748
50232
|
"/permissions untrust <path> Remove a trusted directory.",
|
|
49749
|
-
"/approve [id] Approve a pending risky action and continue.",
|
|
49750
|
-
"/approve-all [full-auto|full] Approve pending actions
|
|
50233
|
+
"/approve [id] Approve a pending risky action and continue once.",
|
|
50234
|
+
"/approve-all [auto|full-auto|full|once] Approve pending actions. Default: auto for the rest of this shell.",
|
|
49751
50235
|
"/deny [id] Deny a pending risky action.",
|
|
49752
50236
|
"",
|
|
49753
50237
|
`${color(BOLD, "Memory")}`,
|
|
@@ -49809,6 +50293,10 @@ function renderStartupCard(cwd, state) {
|
|
|
49809
50293
|
renderCardLine("approval", state.approvalMode),
|
|
49810
50294
|
renderCardLine("sandbox", state.sandboxMode),
|
|
49811
50295
|
renderCardLine("preset", state.stackPreset),
|
|
50296
|
+
...state.pendingApprovals.length > 0 ? [
|
|
50297
|
+
renderCardLine("pending approvals", String(state.pendingApprovals.length)),
|
|
50298
|
+
renderCardLine("next", "select 1 approve once | 2 approve all | 3 deny")
|
|
50299
|
+
] : [],
|
|
49812
50300
|
renderCardLine("shortcuts", "/ask /run /model /permissions /memory /mcp /quit")
|
|
49813
50301
|
];
|
|
49814
50302
|
if (!state.configured) {
|
|
@@ -49850,9 +50338,83 @@ function renderShellRuntimeOverview(runtime) {
|
|
|
49850
50338
|
return lines;
|
|
49851
50339
|
}
|
|
49852
50340
|
function formatPrompt(state) {
|
|
50341
|
+
if (state.pendingApprovals.length > 0) {
|
|
50342
|
+
return state.pendingApprovals.length > 1 ? `${color(AMBER, "select approvals")} ${color(DIM, "[1 current | 2 current+future | 3 deny]")} > ` : `${color(AMBER, "select approval")} ${color(DIM, "[1 approve | 2 all | 3 deny]")} > `;
|
|
50343
|
+
}
|
|
49853
50344
|
const model = state.focusModel === "not set" ? "unconfigured" : shortenMiddle(state.focusModel, 18);
|
|
49854
50345
|
return `${color(AMBER, "kimbho")} ${color(DIM, `[${state.focusRole}:${model}]`)} > `;
|
|
49855
50346
|
}
|
|
50347
|
+
async function readSelectionPrompt(prompt) {
|
|
50348
|
+
if (!import_node_process36.default.stdin.isTTY || !import_node_process36.default.stdout.isTTY) {
|
|
50349
|
+
return "";
|
|
50350
|
+
}
|
|
50351
|
+
return new Promise((resolve) => {
|
|
50352
|
+
const stdin = import_node_process36.default.stdin;
|
|
50353
|
+
const stdout = import_node_process36.default.stdout;
|
|
50354
|
+
const previousRawMode = stdin.isRaw;
|
|
50355
|
+
let buffer = "";
|
|
50356
|
+
const redraw = () => {
|
|
50357
|
+
(0, import_node_readline2.cursorTo)(stdout, 0);
|
|
50358
|
+
(0, import_node_readline2.clearLine)(stdout, 0);
|
|
50359
|
+
stdout.write(`${prompt}${buffer}`);
|
|
50360
|
+
};
|
|
50361
|
+
const cleanup = () => {
|
|
50362
|
+
stdin.off("keypress", onKeypress);
|
|
50363
|
+
stdin.setRawMode?.(Boolean(previousRawMode));
|
|
50364
|
+
};
|
|
50365
|
+
const finish = (value, options = {}) => {
|
|
50366
|
+
cleanup();
|
|
50367
|
+
if (options.printNewline ?? true) {
|
|
50368
|
+
stdout.write("\n");
|
|
50369
|
+
}
|
|
50370
|
+
resolve(value);
|
|
50371
|
+
};
|
|
50372
|
+
const onKeypress = (character, key) => {
|
|
50373
|
+
if (key.ctrl && key.name === "c") {
|
|
50374
|
+
finish("__kimbho_sigint__");
|
|
50375
|
+
return;
|
|
50376
|
+
}
|
|
50377
|
+
if (buffer.length === 0 && (character === "1" || character === "2" || character === "3")) {
|
|
50378
|
+
stdout.write(`${character}
|
|
50379
|
+
`);
|
|
50380
|
+
finish(character, {
|
|
50381
|
+
printNewline: false
|
|
50382
|
+
});
|
|
50383
|
+
return;
|
|
50384
|
+
}
|
|
50385
|
+
if (key.name === "return" || key.name === "enter") {
|
|
50386
|
+
finish(buffer.trim());
|
|
50387
|
+
return;
|
|
50388
|
+
}
|
|
50389
|
+
if (key.name === "backspace") {
|
|
50390
|
+
buffer = buffer.slice(0, -1);
|
|
50391
|
+
redraw();
|
|
50392
|
+
return;
|
|
50393
|
+
}
|
|
50394
|
+
if (key.name === "escape") {
|
|
50395
|
+
buffer = "";
|
|
50396
|
+
redraw();
|
|
50397
|
+
return;
|
|
50398
|
+
}
|
|
50399
|
+
if (key.ctrl || key.meta || !character || key.name === "tab") {
|
|
50400
|
+
return;
|
|
50401
|
+
}
|
|
50402
|
+
buffer += character;
|
|
50403
|
+
redraw();
|
|
50404
|
+
};
|
|
50405
|
+
(0, import_node_readline2.emitKeypressEvents)(stdin);
|
|
50406
|
+
stdin.setRawMode?.(true);
|
|
50407
|
+
stdout.write(prompt);
|
|
50408
|
+
stdin.on("keypress", onKeypress);
|
|
50409
|
+
});
|
|
50410
|
+
}
|
|
50411
|
+
async function readShellInput(readline, state) {
|
|
50412
|
+
const prompt = formatPrompt(state);
|
|
50413
|
+
if (state.pendingApprovals.length > 0) {
|
|
50414
|
+
return readSelectionPrompt(prompt);
|
|
50415
|
+
}
|
|
50416
|
+
return readline.question(prompt);
|
|
50417
|
+
}
|
|
49856
50418
|
function printHeader(cwd, state) {
|
|
49857
50419
|
console.log(renderBanner());
|
|
49858
50420
|
console.log(color(DIM, "Terminal-native coding agent"));
|
|
@@ -49876,8 +50438,8 @@ function appendShellLog(runtime, value) {
|
|
|
49876
50438
|
}
|
|
49877
50439
|
}
|
|
49878
50440
|
function renderShellDashboard(cwd, state, runtime) {
|
|
49879
|
-
const columns = Math.max(
|
|
49880
|
-
const rows = Math.max(
|
|
50441
|
+
const columns = Math.max(import_node_process36.default.stdout.columns ?? 100, 76);
|
|
50442
|
+
const rows = Math.max(import_node_process36.default.stdout.rows ?? 30, 20);
|
|
49881
50443
|
const lines = [
|
|
49882
50444
|
`${color(BOLD, "Kimbho CLI")} ${color(DIM, `(v${KIMBHO_VERSION})`)}`,
|
|
49883
50445
|
color(DIM, `focus ${state.focusRole} | model ${shortenMiddle(state.focusModel, 28)} | provider ${state.providerId}`),
|
|
@@ -49900,6 +50462,16 @@ function renderShellDashboard(cwd, state, runtime) {
|
|
|
49900
50462
|
lines.push(`\u2022 ${shortenMiddle(runtime.pendingHookElicitation.question, Math.max(24, columns - 10))}`);
|
|
49901
50463
|
lines.push(color(DIM, "next: /answer <text> or /skip"));
|
|
49902
50464
|
}
|
|
50465
|
+
if (state.pendingApprovals.length > 0) {
|
|
50466
|
+
lines.push("");
|
|
50467
|
+
lines.push(color(BOLD, state.pendingApprovals.length === 1 ? "Pending Approval" : "Pending Approvals"));
|
|
50468
|
+
lines.push(...renderPendingApprovalLines(
|
|
50469
|
+
state.pendingApprovals.slice(0, 3),
|
|
50470
|
+
Math.max(32, columns - 18)
|
|
50471
|
+
));
|
|
50472
|
+
lines.push(color(DIM, renderApprovalCommandHint()));
|
|
50473
|
+
lines.push(color(DIM, renderApprovalShortcutHint(state.pendingApprovals.length)));
|
|
50474
|
+
}
|
|
49903
50475
|
if (runtime.activeExecution) {
|
|
49904
50476
|
lines.push("");
|
|
49905
50477
|
lines.push(color(BOLD, "Active Execution"));
|
|
@@ -49921,9 +50493,10 @@ function renderShellDashboard(cwd, state, runtime) {
|
|
|
49921
50493
|
}
|
|
49922
50494
|
lines.push("");
|
|
49923
50495
|
lines.push(color(BOLD, "Recent Output"));
|
|
50496
|
+
const footerActionLabel = runtime.pendingRunProposal ? "Direct request to act | /ask chat | /run approve | /run revise | /status | /quit" : "Direct request to act | /ask chat | /run <goal> | /queue list | /status | /quit";
|
|
49924
50497
|
const footerLines = [
|
|
49925
50498
|
"",
|
|
49926
|
-
color(DIM,
|
|
50499
|
+
color(DIM, footerActionLabel)
|
|
49927
50500
|
];
|
|
49928
50501
|
const activityBudget = Math.max(6, rows - lines.length - footerLines.length - 2);
|
|
49929
50502
|
const activity = runtime.shellLog.slice(-activityBudget);
|
|
@@ -49942,23 +50515,54 @@ function renderShellDashboard(cwd, state, runtime) {
|
|
|
49942
50515
|
return `${CLEAR_SCREEN}${HOME_CURSOR}${frame.join("\n")}
|
|
49943
50516
|
`;
|
|
49944
50517
|
}
|
|
50518
|
+
function renderApprovalCommandHint() {
|
|
50519
|
+
return "next: /approve once, /approve-all to stop future prompts in this shell, /deny to stop";
|
|
50520
|
+
}
|
|
50521
|
+
function renderApprovalShortcutHint(pendingCount = 1) {
|
|
50522
|
+
return pendingCount > 1 ? "choices: 1 approve current set | 2 approve current + future for this shell | 3 deny current set" : "choices: 1 approve once | 2 approve all for this shell | 3 deny";
|
|
50523
|
+
}
|
|
50524
|
+
function summarizeApprovalInput(input) {
|
|
50525
|
+
if (typeof input.command === "string" && input.command.trim().length > 0) {
|
|
50526
|
+
return shortenMiddle(input.command.trim(), 90);
|
|
50527
|
+
}
|
|
50528
|
+
if (typeof input.path === "string" && input.path.trim().length > 0) {
|
|
50529
|
+
return shortenMiddle(input.path.trim(), 90);
|
|
50530
|
+
}
|
|
50531
|
+
if (typeof input.url === "string" && input.url.trim().length > 0) {
|
|
50532
|
+
return shortenMiddle(input.url.trim(), 90);
|
|
50533
|
+
}
|
|
50534
|
+
const serialized = Object.entries(input).slice(0, 3).map(([key, value]) => `${key}=${String(value)}`).join(" ");
|
|
50535
|
+
return serialized.length > 0 ? shortenMiddle(serialized, 90) : null;
|
|
50536
|
+
}
|
|
50537
|
+
function renderPendingApprovalLines(approvals, maxReasonWidth = 110) {
|
|
50538
|
+
const lines = [];
|
|
50539
|
+
for (const approval of approvals) {
|
|
50540
|
+
lines.push(`\u2022 ${approval.toolId} for ${approval.taskId} (${approval.permission})`);
|
|
50541
|
+
lines.push(` reason: ${shortenMiddle(approval.reason, maxReasonWidth)}`);
|
|
50542
|
+
const request = summarizeApprovalInput(approval.input);
|
|
50543
|
+
if (request) {
|
|
50544
|
+
lines.push(` request: ${request}`);
|
|
50545
|
+
}
|
|
50546
|
+
}
|
|
50547
|
+
return lines;
|
|
50548
|
+
}
|
|
49945
50549
|
var ShellDashboardTui = class {
|
|
49946
50550
|
constructor(runtime) {
|
|
49947
50551
|
this.runtime = runtime;
|
|
49948
50552
|
}
|
|
49949
|
-
cwd =
|
|
50553
|
+
cwd = import_node_process36.default.cwd();
|
|
49950
50554
|
state = null;
|
|
49951
50555
|
handleResize = () => {
|
|
49952
50556
|
this.render();
|
|
49953
50557
|
};
|
|
49954
50558
|
start(cwd, state) {
|
|
49955
|
-
if (!
|
|
50559
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49956
50560
|
return;
|
|
49957
50561
|
}
|
|
49958
50562
|
this.cwd = cwd;
|
|
49959
50563
|
this.state = state;
|
|
49960
|
-
|
|
49961
|
-
|
|
50564
|
+
import_node_process36.default.stdout.write(`${ALT_SCREEN_ENTER}${HIDE_CURSOR}`);
|
|
50565
|
+
import_node_process36.default.stdout.on("resize", this.handleResize);
|
|
49962
50566
|
this.render();
|
|
49963
50567
|
}
|
|
49964
50568
|
update(cwd, state) {
|
|
@@ -49967,17 +50571,17 @@ var ShellDashboardTui = class {
|
|
|
49967
50571
|
this.render();
|
|
49968
50572
|
}
|
|
49969
50573
|
render() {
|
|
49970
|
-
if (!
|
|
50574
|
+
if (!import_node_process36.default.stdout.isTTY || !this.state || this.runtime.activeExecution) {
|
|
49971
50575
|
return;
|
|
49972
50576
|
}
|
|
49973
|
-
|
|
50577
|
+
import_node_process36.default.stdout.write(renderShellDashboard(this.cwd, this.state, this.runtime));
|
|
49974
50578
|
}
|
|
49975
50579
|
stop() {
|
|
49976
|
-
if (!
|
|
50580
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49977
50581
|
return;
|
|
49978
50582
|
}
|
|
49979
|
-
|
|
49980
|
-
|
|
50583
|
+
import_node_process36.default.stdout.off("resize", this.handleResize);
|
|
50584
|
+
import_node_process36.default.stdout.write(`${SHOW_CURSOR}${ALT_SCREEN_EXIT}`);
|
|
49981
50585
|
}
|
|
49982
50586
|
};
|
|
49983
50587
|
function renderInlineMarkdown(value) {
|
|
@@ -50414,7 +51018,7 @@ function renderShellSessionSummary(snapshot, planPath, sessionPath) {
|
|
|
50414
51018
|
snapshot.events.flatMap((event) => [
|
|
50415
51019
|
...event.artifacts,
|
|
50416
51020
|
...event.toolResults.flatMap((toolResult) => toolResult.artifacts)
|
|
50417
|
-
]).filter((artifact) => !artifact.includes(`${
|
|
51021
|
+
]).filter((artifact) => !artifact.includes(`${import_node_path34.default.sep}.kimbho${import_node_path34.default.sep}`))
|
|
50418
51022
|
));
|
|
50419
51023
|
const visibleNotes = snapshot.notes.filter(
|
|
50420
51024
|
(note) => /limit reached|approval|blocked|failed|error|conflict|denied/i.test(note)
|
|
@@ -50441,9 +51045,7 @@ function renderShellSessionSummary(snapshot, planPath, sessionPath) {
|
|
|
50441
51045
|
if (snapshot.pendingApprovals.length > 0) {
|
|
50442
51046
|
lines.push("");
|
|
50443
51047
|
lines.push(color(BOLD, "Waiting For Approval"));
|
|
50444
|
-
|
|
50445
|
-
lines.push(`\u2022 ${approval.reason}`);
|
|
50446
|
-
}
|
|
51048
|
+
lines.push(...renderPendingApprovalLines(snapshot.pendingApprovals.slice(0, 4)));
|
|
50447
51049
|
}
|
|
50448
51050
|
if (visibleNotes.length > 0) {
|
|
50449
51051
|
lines.push("");
|
|
@@ -50458,7 +51060,8 @@ function renderShellSessionSummary(snapshot, planPath, sessionPath) {
|
|
|
50458
51060
|
}
|
|
50459
51061
|
lines.push(color(DIM, `saved session: ${sessionPath}`));
|
|
50460
51062
|
if (snapshot.pendingApprovals.length > 0) {
|
|
50461
|
-
lines.push(
|
|
51063
|
+
lines.push(renderApprovalCommandHint());
|
|
51064
|
+
lines.push(color(DIM, renderApprovalShortcutHint(snapshot.pendingApprovals.length)));
|
|
50462
51065
|
} else if (snapshot.status === "paused" || snapshot.status === "running" || snapshot.status === "ready") {
|
|
50463
51066
|
lines.push("next: /resume to continue a paused run or start another request");
|
|
50464
51067
|
} else if (snapshot.status === "blocked") {
|
|
@@ -50570,7 +51173,8 @@ function renderLiveExecutionEvent(event, board, startedAt, options = {}) {
|
|
|
50570
51173
|
case "approval-requested":
|
|
50571
51174
|
return [
|
|
50572
51175
|
`${color(AMBER, "Approval Needed")} ${event.approval.reason}`,
|
|
50573
|
-
color(DIM,
|
|
51176
|
+
color(DIM, renderApprovalCommandHint()),
|
|
51177
|
+
color(DIM, renderApprovalShortcutHint(board.approvals)),
|
|
50574
51178
|
...progressLines
|
|
50575
51179
|
];
|
|
50576
51180
|
case "approval-resolved":
|
|
@@ -50757,12 +51361,12 @@ function rewindConversation(runtime, role, turns) {
|
|
|
50757
51361
|
return removed;
|
|
50758
51362
|
}
|
|
50759
51363
|
async function writeTextToClipboard(value) {
|
|
50760
|
-
const candidates =
|
|
51364
|
+
const candidates = import_node_process36.default.platform === "darwin" ? [
|
|
50761
51365
|
{
|
|
50762
51366
|
command: "pbcopy",
|
|
50763
51367
|
args: []
|
|
50764
51368
|
}
|
|
50765
|
-
] :
|
|
51369
|
+
] : import_node_process36.default.platform === "win32" ? [
|
|
50766
51370
|
{
|
|
50767
51371
|
command: "clip",
|
|
50768
51372
|
args: []
|
|
@@ -50810,7 +51414,7 @@ async function writeTextToClipboard(value) {
|
|
|
50810
51414
|
}
|
|
50811
51415
|
function createShellExportPath(cwd, role, kind) {
|
|
50812
51416
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
50813
|
-
return
|
|
51417
|
+
return import_node_path34.default.join(cwd, ".kimbho", "exports", `${kind}-${role}-${stamp}.md`);
|
|
50814
51418
|
}
|
|
50815
51419
|
function clearConversation(runtime, role) {
|
|
50816
51420
|
runtime.conversations[role] = [];
|
|
@@ -50913,6 +51517,22 @@ async function handleChatPrompt(cwd, prompt, runtime) {
|
|
|
50913
51517
|
maxCharsPerFile: 3e3
|
|
50914
51518
|
});
|
|
50915
51519
|
const skillContext = await resolveActivatedSkillContext(cwd, hydrated.prompt);
|
|
51520
|
+
const workspaceInfoPrompt = looksLikeWorkspaceInfoPrompt(hydrated.prompt);
|
|
51521
|
+
let workspaceOverview = null;
|
|
51522
|
+
if (workspaceInfoPrompt) {
|
|
51523
|
+
const existingOverview = await readMarkdownIfExists(import_node_path34.default.join(cwd, "kimbho_init.md"));
|
|
51524
|
+
if (existingOverview) {
|
|
51525
|
+
workspaceOverview = existingOverview.slice(0, 6e3);
|
|
51526
|
+
} else {
|
|
51527
|
+
try {
|
|
51528
|
+
const generated = await generateProjectInitFile(cwd, "kimbho_init.md");
|
|
51529
|
+
const generatedOverview = await readMarkdownIfExists(generated.outputPath);
|
|
51530
|
+
workspaceOverview = generatedOverview?.slice(0, 6e3) ?? null;
|
|
51531
|
+
} catch {
|
|
51532
|
+
workspaceOverview = null;
|
|
51533
|
+
}
|
|
51534
|
+
}
|
|
51535
|
+
}
|
|
50916
51536
|
const compactionPath = await compactConversationIfNeeded(cwd, runtime, runtime.focusRole);
|
|
50917
51537
|
if (compactionPath) {
|
|
50918
51538
|
console.log(color(DIM, `[compacting] condensed ${runtime.focusRole} chat context -> ${compactionPath}`));
|
|
@@ -50928,27 +51548,34 @@ async function handleChatPrompt(cwd, prompt, runtime) {
|
|
|
50928
51548
|
let result;
|
|
50929
51549
|
const activity = new ShellActivityIndicator(pickIdleStatusLabel(prompt));
|
|
50930
51550
|
activity.start();
|
|
51551
|
+
const systemPromptSections = [
|
|
51552
|
+
brain.settings.promptPreamble,
|
|
51553
|
+
adaptiveMemory.chatSummary.length > 0 ? `Adaptive memory:
|
|
51554
|
+
${adaptiveMemory.chatSummary}` : null,
|
|
51555
|
+
memoryContext.length > 0 ? [
|
|
51556
|
+
"Workspace memory:",
|
|
51557
|
+
...memoryContext.map((record2) => `File: ${record2.filePath}
|
|
51558
|
+
${record2.content}`)
|
|
51559
|
+
].join("\n\n") : null,
|
|
51560
|
+
workspaceOverview ? [
|
|
51561
|
+
"Workspace question handling:",
|
|
51562
|
+
"The user is asking about the current repository. Ground the answer in the workspace context below and do not reply with a generic assistant introduction.",
|
|
51563
|
+
`Workspace overview:
|
|
51564
|
+
${workspaceOverview}`
|
|
51565
|
+
].join("\n\n") : null,
|
|
51566
|
+
skillContext.systemPromptSections.length > 0 ? [
|
|
51567
|
+
"Active skill packs:",
|
|
51568
|
+
...skillContext.systemPromptSections
|
|
51569
|
+
].join("\n\n") : null,
|
|
51570
|
+
runtime.conversationSummaries[runtime.focusRole] ? `Compacted conversation summary:
|
|
51571
|
+
${runtime.conversationSummaries[runtime.focusRole]}` : null
|
|
51572
|
+
].filter((value) => Boolean(value));
|
|
50931
51573
|
try {
|
|
50932
51574
|
result = await brain.client.generateText({
|
|
50933
51575
|
model: brain.model,
|
|
50934
51576
|
messages,
|
|
50935
|
-
...
|
|
50936
|
-
systemPrompt:
|
|
50937
|
-
brain.settings.promptPreamble,
|
|
50938
|
-
adaptiveMemory.chatSummary.length > 0 ? `Adaptive memory:
|
|
50939
|
-
${adaptiveMemory.chatSummary}` : null,
|
|
50940
|
-
memoryContext.length > 0 ? [
|
|
50941
|
-
"Workspace memory:",
|
|
50942
|
-
...memoryContext.map((record2) => `File: ${record2.filePath}
|
|
50943
|
-
${record2.content}`)
|
|
50944
|
-
].join("\n\n") : null,
|
|
50945
|
-
skillContext.systemPromptSections.length > 0 ? [
|
|
50946
|
-
"Active skill packs:",
|
|
50947
|
-
...skillContext.systemPromptSections
|
|
50948
|
-
].join("\n\n") : null,
|
|
50949
|
-
runtime.conversationSummaries[runtime.focusRole] ? `Compacted conversation summary:
|
|
50950
|
-
${runtime.conversationSummaries[runtime.focusRole]}` : null
|
|
50951
|
-
].filter((value) => Boolean(value)).join("\n\n")
|
|
51577
|
+
...systemPromptSections.length > 0 ? {
|
|
51578
|
+
systemPrompt: systemPromptSections.join("\n\n")
|
|
50952
51579
|
} : {},
|
|
50953
51580
|
...typeof brain.settings.temperature === "number" ? {
|
|
50954
51581
|
temperature: brain.settings.temperature
|
|
@@ -51079,7 +51706,7 @@ async function executePendingRunProposal(runtime) {
|
|
|
51079
51706
|
resolveShellMaxAgentSteps(runtime),
|
|
51080
51707
|
DEFAULT_MAX_REPAIR_ATTEMPTS2
|
|
51081
51708
|
);
|
|
51082
|
-
const tui =
|
|
51709
|
+
const tui = import_node_process36.default.stdout.isTTY ? new ShellExecutionTui(liveBoard, telemetry, startedAt, "starting", !runtime.dashboard) : null;
|
|
51083
51710
|
const activity = tui ? null : new ShellActivityIndicator("starting");
|
|
51084
51711
|
if (tui) {
|
|
51085
51712
|
tui.start();
|
|
@@ -51147,6 +51774,126 @@ async function executePendingRunProposal(runtime) {
|
|
|
51147
51774
|
void drainQueuedWork(runtime);
|
|
51148
51775
|
return request.cwd;
|
|
51149
51776
|
}
|
|
51777
|
+
async function handleWorkspaceAnalysisPrompt(cwd, prompt, runtime) {
|
|
51778
|
+
const hydrated = await hydratePromptWithMcpResources(cwd, prompt);
|
|
51779
|
+
await recordAdaptiveTextObservation(cwd, hydrated.prompt, "chat");
|
|
51780
|
+
const skillAwareRequest = await preparePlanningRequest({
|
|
51781
|
+
goal: `Analyze the current repository and answer the user's question: ${hydrated.prompt}`,
|
|
51782
|
+
mode: "run",
|
|
51783
|
+
cwd,
|
|
51784
|
+
workspaceState: "existing",
|
|
51785
|
+
constraints: [
|
|
51786
|
+
"Read-only repository analysis only.",
|
|
51787
|
+
"Do not modify source files, install packages, or start development servers.",
|
|
51788
|
+
"Use multiple agents to inspect the workspace and synthesize the answer when helpful."
|
|
51789
|
+
]
|
|
51790
|
+
});
|
|
51791
|
+
const request = skillAwareRequest.request;
|
|
51792
|
+
const plan = buildWorkspaceAnalysisPlan(request, hydrated.prompt);
|
|
51793
|
+
const planPath = await savePlan(plan, request.cwd);
|
|
51794
|
+
const orchestrator = new ExecutionOrchestrator();
|
|
51795
|
+
const initialSnapshot = orchestrator.createSessionSnapshot(
|
|
51796
|
+
orchestrator.buildEnvelope(request, plan)
|
|
51797
|
+
);
|
|
51798
|
+
const startedAt = Date.now();
|
|
51799
|
+
const telemetry = createExecutionTelemetry();
|
|
51800
|
+
const controller = new AbortController();
|
|
51801
|
+
runtime.activeExecution = {
|
|
51802
|
+
controller,
|
|
51803
|
+
label: hydrated.prompt
|
|
51804
|
+
};
|
|
51805
|
+
const liveBoard = createLiveRunBoard(
|
|
51806
|
+
initialSnapshot.id,
|
|
51807
|
+
hydrated.prompt,
|
|
51808
|
+
request,
|
|
51809
|
+
plan,
|
|
51810
|
+
resolveShellMaxAutoTasks(runtime),
|
|
51811
|
+
resolveShellMaxAgentSteps(runtime),
|
|
51812
|
+
DEFAULT_MAX_REPAIR_ATTEMPTS2
|
|
51813
|
+
);
|
|
51814
|
+
const tui = import_node_process36.default.stdout.isTTY ? new ShellExecutionTui(liveBoard, telemetry, startedAt, "analyzing", !runtime.dashboard) : null;
|
|
51815
|
+
const activity = tui ? null : new ShellActivityIndicator("analyzing");
|
|
51816
|
+
if (tui) {
|
|
51817
|
+
tui.start();
|
|
51818
|
+
tui.pushEvent(renderLiveExecutionEvent({
|
|
51819
|
+
type: "task-note",
|
|
51820
|
+
sessionId: initialSnapshot.id,
|
|
51821
|
+
message: "Read-only repository analysis session started."
|
|
51822
|
+
}, liveBoard, startedAt, {
|
|
51823
|
+
includeProgress: false
|
|
51824
|
+
}));
|
|
51825
|
+
} else {
|
|
51826
|
+
console.log(renderRunStartCard(liveBoard));
|
|
51827
|
+
console.log("");
|
|
51828
|
+
activity?.start();
|
|
51829
|
+
}
|
|
51830
|
+
let snapshot;
|
|
51831
|
+
try {
|
|
51832
|
+
snapshot = await orchestrator.continueSession(initialSnapshot, {
|
|
51833
|
+
maxAutoTasks: resolveShellMaxAutoTasks(runtime),
|
|
51834
|
+
maxAgentSteps: resolveShellMaxAgentSteps(runtime),
|
|
51835
|
+
maxRepairAttempts: DEFAULT_MAX_REPAIR_ATTEMPTS2,
|
|
51836
|
+
signal: controller.signal,
|
|
51837
|
+
onProgress: async (event) => {
|
|
51838
|
+
updateLiveRunBoard(liveBoard, event);
|
|
51839
|
+
if (event.type === "tool-started") {
|
|
51840
|
+
telemetry.toolCalls += 1;
|
|
51841
|
+
}
|
|
51842
|
+
if (event.type === "model-usage") {
|
|
51843
|
+
telemetry.modelCalls += 1;
|
|
51844
|
+
telemetry.inputTokens += event.usage?.inputTokens ?? 0;
|
|
51845
|
+
telemetry.outputTokens += event.usage?.outputTokens ?? 0;
|
|
51846
|
+
}
|
|
51847
|
+
if (tui) {
|
|
51848
|
+
tui.updateActivity(statusLabelForEvent(event));
|
|
51849
|
+
tui.pushEvent(renderLiveExecutionEvent(event, liveBoard, startedAt, {
|
|
51850
|
+
includeProgress: false
|
|
51851
|
+
}));
|
|
51852
|
+
} else {
|
|
51853
|
+
activity?.update(statusLabelForEvent(event));
|
|
51854
|
+
activity?.suspend();
|
|
51855
|
+
for (const line of renderLiveExecutionEvent(event, liveBoard, startedAt)) {
|
|
51856
|
+
console.log(line);
|
|
51857
|
+
}
|
|
51858
|
+
activity?.resume();
|
|
51859
|
+
}
|
|
51860
|
+
}
|
|
51861
|
+
});
|
|
51862
|
+
} finally {
|
|
51863
|
+
tui?.stop();
|
|
51864
|
+
activity?.stop();
|
|
51865
|
+
runtime.activeExecution = null;
|
|
51866
|
+
}
|
|
51867
|
+
const sessionPath = await saveSession(snapshot, request.cwd);
|
|
51868
|
+
await recordAdaptiveSessionOutcome(request.cwd, snapshot);
|
|
51869
|
+
runtime.currentCwd = request.cwd;
|
|
51870
|
+
const answer = await synthesizeWorkspaceAnalysisAnswer(
|
|
51871
|
+
request.cwd,
|
|
51872
|
+
hydrated.prompt,
|
|
51873
|
+
runtime.focusRole,
|
|
51874
|
+
snapshot
|
|
51875
|
+
);
|
|
51876
|
+
const conversation = trimConversation([
|
|
51877
|
+
...getConversation(runtime, runtime.focusRole),
|
|
51878
|
+
{
|
|
51879
|
+
role: "user",
|
|
51880
|
+
content: hydrated.prompt
|
|
51881
|
+
},
|
|
51882
|
+
{
|
|
51883
|
+
role: "assistant",
|
|
51884
|
+
content: answer
|
|
51885
|
+
}
|
|
51886
|
+
]);
|
|
51887
|
+
runtime.conversations[runtime.focusRole] = conversation;
|
|
51888
|
+
console.log("");
|
|
51889
|
+
console.log(color(DIM, `elapsed: ${((Date.now() - startedAt) / 1e3).toFixed(1)}s`));
|
|
51890
|
+
console.log(color(DIM, renderExecutionTelemetry(telemetry, startedAt)));
|
|
51891
|
+
console.log(renderShellSessionSummary(snapshot, planPath, sessionPath));
|
|
51892
|
+
console.log("");
|
|
51893
|
+
console.log(color(DIM, "[analysis answer]"));
|
|
51894
|
+
console.log(renderTerminalMarkdown(answer));
|
|
51895
|
+
void drainQueuedWork(runtime);
|
|
51896
|
+
}
|
|
51150
51897
|
async function resumeGoalExecution(cwd, runtime) {
|
|
51151
51898
|
const session = await loadLatestSession(cwd);
|
|
51152
51899
|
if (!session) {
|
|
@@ -51169,7 +51916,7 @@ async function resumeGoalExecution(cwd, runtime) {
|
|
|
51169
51916
|
controller,
|
|
51170
51917
|
label: session.id
|
|
51171
51918
|
};
|
|
51172
|
-
const tui =
|
|
51919
|
+
const tui = import_node_process36.default.stdout.isTTY ? new ShellExecutionTui(liveBoard, telemetry, startedAt, "resuming", !runtime.dashboard) : null;
|
|
51173
51920
|
const activity = tui ? null : new ShellActivityIndicator("resuming");
|
|
51174
51921
|
if (tui) {
|
|
51175
51922
|
tui.start();
|
|
@@ -51285,7 +52032,7 @@ async function resolvePendingApproval(cwd, runtime, decision, approvalId, option
|
|
|
51285
52032
|
controller,
|
|
51286
52033
|
label: approvals.length === 1 ? `${session.id}:${approvals[0].id}` : `${session.id}:batch-approval`
|
|
51287
52034
|
};
|
|
51288
|
-
const tui =
|
|
52035
|
+
const tui = import_node_process36.default.stdout.isTTY ? new ShellExecutionTui(liveBoard, telemetry, startedAt, decision === "approve" ? "approving" : "denying", !runtime.dashboard) : null;
|
|
51289
52036
|
const activity = tui ? null : new ShellActivityIndicator(decision === "approve" ? "approving" : "denying");
|
|
51290
52037
|
if (tui) {
|
|
51291
52038
|
tui.start();
|
|
@@ -51349,16 +52096,74 @@ async function resolvePendingApproval(cwd, runtime, decision, approvalId, option
|
|
|
51349
52096
|
void drainQueuedWork(runtime);
|
|
51350
52097
|
}
|
|
51351
52098
|
async function applyApproveAllPreset(cwd, runtime, rawPreset) {
|
|
51352
|
-
|
|
51353
|
-
|
|
52099
|
+
const normalized = rawPreset?.trim().toLowerCase();
|
|
52100
|
+
if (!normalized) {
|
|
52101
|
+
runtime.sessionApprovalModeOverride = "auto";
|
|
52102
|
+
syncShellRuntimeOverrides(runtime);
|
|
52103
|
+
console.log("Shell permission override: auto approvals for the rest of this shell.");
|
|
52104
|
+
await recordAdaptiveTextObservation(cwd, "User approval preference: auto approvals for the rest of this shell.", "approval");
|
|
52105
|
+
const session2 = await loadLatestSession(cwd);
|
|
52106
|
+
return Boolean(session2 && session2.pendingApprovals.length > 0);
|
|
52107
|
+
}
|
|
52108
|
+
if (normalized === "once" || normalized === "current") {
|
|
52109
|
+
const session2 = await loadLatestSession(cwd);
|
|
52110
|
+
if (!session2 || session2.pendingApprovals.length === 0) {
|
|
52111
|
+
return false;
|
|
52112
|
+
}
|
|
52113
|
+
console.log("Approving all currently pending actions once. Future actions will keep the current approval mode.");
|
|
52114
|
+
return true;
|
|
51354
52115
|
}
|
|
51355
|
-
const preset = resolvePermissionPreset(rawPreset);
|
|
52116
|
+
const preset = resolvePermissionPreset(rawPreset ?? "auto");
|
|
51356
52117
|
setShellSessionPermissions(runtime, preset);
|
|
51357
52118
|
console.log(`Shell permission override: ${preset.label}`);
|
|
51358
52119
|
await recordAdaptiveTextObservation(cwd, `User approval preference: ${preset.label}`, "approval");
|
|
51359
52120
|
const session = await loadLatestSession(cwd);
|
|
51360
52121
|
return Boolean(session && session.pendingApprovals.length > 0);
|
|
51361
52122
|
}
|
|
52123
|
+
async function tryResolveApprovalShortcut(cwd, runtime, input) {
|
|
52124
|
+
if (input !== "1" && input !== "2" && input !== "3") {
|
|
52125
|
+
return false;
|
|
52126
|
+
}
|
|
52127
|
+
const session = await loadLatestSession(cwd);
|
|
52128
|
+
if (!session || session.pendingApprovals.length === 0) {
|
|
52129
|
+
return false;
|
|
52130
|
+
}
|
|
52131
|
+
if (input === "1") {
|
|
52132
|
+
await resolvePendingApproval(
|
|
52133
|
+
cwd,
|
|
52134
|
+
runtime,
|
|
52135
|
+
"approve",
|
|
52136
|
+
session.pendingApprovals.length > 1 ? "all" : void 0,
|
|
52137
|
+
{
|
|
52138
|
+
allowAll: session.pendingApprovals.length > 1
|
|
52139
|
+
}
|
|
52140
|
+
);
|
|
52141
|
+
return true;
|
|
52142
|
+
}
|
|
52143
|
+
if (input === "2") {
|
|
52144
|
+
await applyApproveAllPreset(cwd, runtime);
|
|
52145
|
+
await resolvePendingApproval(
|
|
52146
|
+
cwd,
|
|
52147
|
+
runtime,
|
|
52148
|
+
"approve",
|
|
52149
|
+
"all",
|
|
52150
|
+
{
|
|
52151
|
+
allowAll: true
|
|
52152
|
+
}
|
|
52153
|
+
);
|
|
52154
|
+
return true;
|
|
52155
|
+
}
|
|
52156
|
+
await resolvePendingApproval(
|
|
52157
|
+
cwd,
|
|
52158
|
+
runtime,
|
|
52159
|
+
"deny",
|
|
52160
|
+
session.pendingApprovals.length > 1 ? "all" : void 0,
|
|
52161
|
+
{
|
|
52162
|
+
allowAll: session.pendingApprovals.length > 1
|
|
52163
|
+
}
|
|
52164
|
+
);
|
|
52165
|
+
return true;
|
|
52166
|
+
}
|
|
51362
52167
|
async function printLatestPlanSummary(cwd) {
|
|
51363
52168
|
const plan = await loadLatestPlan(cwd);
|
|
51364
52169
|
if (!plan) {
|
|
@@ -51505,7 +52310,7 @@ async function handlePermissionsCommand(cwd, tokens, runtime) {
|
|
|
51505
52310
|
if (!target) {
|
|
51506
52311
|
throw new Error(`Usage: /permissions ${subcommand} <path>`);
|
|
51507
52312
|
}
|
|
51508
|
-
const normalizedTarget =
|
|
52313
|
+
const normalizedTarget = import_node_path34.default.resolve(cwd, target);
|
|
51509
52314
|
const trustedDirectories = subcommand === "trust" ? Array.from(/* @__PURE__ */ new Set([
|
|
51510
52315
|
...effective.trustedDirectories,
|
|
51511
52316
|
normalizedTarget
|
|
@@ -51621,7 +52426,7 @@ async function handleExportCommand(cwd, tokens, runtime) {
|
|
|
51621
52426
|
);
|
|
51622
52427
|
const destinationToken = knownKind ? tokens[2] : tokens[1];
|
|
51623
52428
|
const outputPath = await writeMarkdownFile(
|
|
51624
|
-
destinationToken ?
|
|
52429
|
+
destinationToken ? import_node_path34.default.resolve(cwd, destinationToken) : createShellExportPath(cwd, runtime.focusRole, knownKind ? kindToken : "context"),
|
|
51625
52430
|
payload.content
|
|
51626
52431
|
);
|
|
51627
52432
|
console.log(`Exported ${payload.label} -> ${outputPath}`);
|
|
@@ -51631,7 +52436,7 @@ async function handleAddDirCommand(cwd, tokens, runtime) {
|
|
|
51631
52436
|
if (!target) {
|
|
51632
52437
|
throw new Error("Usage: /add-dir <path>");
|
|
51633
52438
|
}
|
|
51634
|
-
const resolved =
|
|
52439
|
+
const resolved = import_node_path34.default.resolve(cwd, target);
|
|
51635
52440
|
if (!runtime.additionalDirectories.includes(resolved)) {
|
|
51636
52441
|
runtime.additionalDirectories.push(resolved);
|
|
51637
52442
|
runtime.additionalDirectories.sort((left, right) => left.localeCompare(right));
|
|
@@ -51708,7 +52513,7 @@ async function handleHooksCommand(cwd, tokens) {
|
|
|
51708
52513
|
console.log(lines.join("\n"));
|
|
51709
52514
|
}
|
|
51710
52515
|
function shellHookSessionId(runtime, cwd) {
|
|
51711
|
-
return runtime.pendingRunProposal?.snapshot.id ?? `shell-${
|
|
52516
|
+
return runtime.pendingRunProposal?.snapshot.id ?? `shell-${import_node_process36.default.pid}-${import_node_path34.default.basename(cwd) || "workspace"}`;
|
|
51712
52517
|
}
|
|
51713
52518
|
async function createShellHookRunner(cwd, config2) {
|
|
51714
52519
|
const resolvedConfig = config2 ?? await loadConfig(cwd).catch(() => null);
|
|
@@ -51892,7 +52697,7 @@ async function handleMemoryCommand(cwd, tokens) {
|
|
|
51892
52697
|
}
|
|
51893
52698
|
let filePath;
|
|
51894
52699
|
if (scope === "init") {
|
|
51895
|
-
filePath =
|
|
52700
|
+
filePath = import_node_path34.default.join(cwd, "kimbho_init.md");
|
|
51896
52701
|
} else if (scope === "project") {
|
|
51897
52702
|
filePath = resolveProjectMemoryPath(cwd);
|
|
51898
52703
|
} else if (scope === "user") {
|
|
@@ -51902,7 +52707,7 @@ async function handleMemoryCommand(cwd, tokens) {
|
|
|
51902
52707
|
if (!agentId) {
|
|
51903
52708
|
throw new Error("Usage: /memory show agent <agent-id>");
|
|
51904
52709
|
}
|
|
51905
|
-
filePath =
|
|
52710
|
+
filePath = import_node_path34.default.join(resolveAgentMemoryDir(cwd), `${agentId}.md`);
|
|
51906
52711
|
} else {
|
|
51907
52712
|
throw new Error("Usage: /memory show <init|project|user|agent> [id]");
|
|
51908
52713
|
}
|
|
@@ -52511,7 +53316,7 @@ async function printProviderList(cwd, focusRole) {
|
|
|
52511
53316
|
const activeProviderId = config2.brains[focusRole].providerId;
|
|
52512
53317
|
for (const provider of config2.providers) {
|
|
52513
53318
|
const marker = provider.id === activeProviderId ? "*" : " ";
|
|
52514
|
-
const envState = provider.apiKeyEnv ?
|
|
53319
|
+
const envState = provider.apiKeyEnv ? import_node_process36.default.env[provider.apiKeyEnv] ? "present" : `missing ${provider.apiKeyEnv}` : "no key required";
|
|
52515
53320
|
console.log(`${marker} ${provider.id}`);
|
|
52516
53321
|
console.log(` label: ${provider.label ?? "-"}`);
|
|
52517
53322
|
console.log(` driver: ${provider.driver}`);
|
|
@@ -52848,6 +53653,10 @@ async function startPendingRunExecution(cwd, runtime) {
|
|
|
52848
53653
|
console.log(color(DIM, "Waiting on a hook question before starting the plan."));
|
|
52849
53654
|
return;
|
|
52850
53655
|
}
|
|
53656
|
+
if (!proposal) {
|
|
53657
|
+
console.log("No pending run proposal. Start with a build/change request or /run <goal>.");
|
|
53658
|
+
return;
|
|
53659
|
+
}
|
|
52851
53660
|
if (proposal && planRequiresOperatorReview(proposal.plan)) {
|
|
52852
53661
|
await emitShellHookEvent(
|
|
52853
53662
|
proposal.request.cwd,
|
|
@@ -52864,6 +53673,15 @@ async function startPendingRunExecution(cwd, runtime) {
|
|
|
52864
53673
|
}
|
|
52865
53674
|
);
|
|
52866
53675
|
}
|
|
53676
|
+
const confirmedProposal = runtime.pendingRunProposal;
|
|
53677
|
+
if (runtime.pendingHookElicitation) {
|
|
53678
|
+
console.log(color(DIM, "Waiting on a hook question before starting the plan."));
|
|
53679
|
+
return;
|
|
53680
|
+
}
|
|
53681
|
+
if (!confirmedProposal) {
|
|
53682
|
+
console.log(color(DIM, "Pending plan was cleared before execution could start."));
|
|
53683
|
+
return;
|
|
53684
|
+
}
|
|
52867
53685
|
console.log(color(DIM, "Starting the approved plan..."));
|
|
52868
53686
|
void executePendingRunProposal(runtime).catch((error2) => {
|
|
52869
53687
|
console.error(error2 instanceof Error ? error2.message : String(error2));
|
|
@@ -52953,6 +53771,9 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
52953
53771
|
await resolvePendingHookElicitation(cwd, runtime, "answer", trimmed);
|
|
52954
53772
|
return cwd;
|
|
52955
53773
|
}
|
|
53774
|
+
if (!isSlashCommand && !runtime.pendingRunProposal && await tryResolveApprovalShortcut(cwd, runtime, trimmed)) {
|
|
53775
|
+
return cwd;
|
|
53776
|
+
}
|
|
52956
53777
|
if (head.startsWith("mcp__")) {
|
|
52957
53778
|
const parts = head.split("__").filter((part) => part.length > 0);
|
|
52958
53779
|
if (parts.length < 3) {
|
|
@@ -52971,6 +53792,14 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
52971
53792
|
return cwd;
|
|
52972
53793
|
}
|
|
52973
53794
|
if (!firstToken?.startsWith("/") && !TOP_LEVEL_COMMANDS.has(head) && !head.startsWith("-")) {
|
|
53795
|
+
if (looksLikeWorkspaceInfoPrompt(trimmed)) {
|
|
53796
|
+
if (runtime.activeExecution || runtime.queueDrainPromise || runtime.pendingRunProposal) {
|
|
53797
|
+
queuePlannerRequest(cwd, `Analyze the current repository and answer: ${trimmed}`, runtime, "run");
|
|
53798
|
+
return cwd;
|
|
53799
|
+
}
|
|
53800
|
+
await handleWorkspaceAnalysisPrompt(cwd, trimmed, runtime);
|
|
53801
|
+
return cwd;
|
|
53802
|
+
}
|
|
52974
53803
|
const intent = inferPromptIntent(trimmed);
|
|
52975
53804
|
if (intent === "run") {
|
|
52976
53805
|
if (runtime.activeExecution || runtime.queueDrainPromise || runtime.pendingRunProposal) {
|
|
@@ -53248,7 +54077,7 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
53248
54077
|
await createPlanOnly(cwd, goal);
|
|
53249
54078
|
return cwd;
|
|
53250
54079
|
}
|
|
53251
|
-
if (head === "resume") {
|
|
54080
|
+
if (head === "resume" || head === "continue") {
|
|
53252
54081
|
queueResumeRequest(cwd, runtime);
|
|
53253
54082
|
return cwd;
|
|
53254
54083
|
}
|
|
@@ -53261,16 +54090,16 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
53261
54090
|
}
|
|
53262
54091
|
if (head === "approve-all") {
|
|
53263
54092
|
const shouldResolvePending = await applyApproveAllPreset(cwd, runtime, tokens[1]?.trim());
|
|
53264
|
-
if (
|
|
54093
|
+
if (!shouldResolvePending) {
|
|
53265
54094
|
if (runtime.pendingRunProposal) {
|
|
53266
54095
|
void startPendingRunExecution(cwd, runtime);
|
|
53267
54096
|
return cwd;
|
|
53268
54097
|
}
|
|
53269
|
-
|
|
53270
|
-
|
|
53271
|
-
|
|
53272
|
-
|
|
53273
|
-
|
|
54098
|
+
if (tokens[1]?.trim()) {
|
|
54099
|
+
console.log("No pending approvals right now. Future actions in this shell will use the new permission mode.");
|
|
54100
|
+
} else {
|
|
54101
|
+
console.log("No pending approvals right now. Future actions in this shell will use auto approvals.");
|
|
54102
|
+
}
|
|
53274
54103
|
return cwd;
|
|
53275
54104
|
}
|
|
53276
54105
|
await resolvePendingApproval(
|
|
@@ -53286,6 +54115,27 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
53286
54115
|
}
|
|
53287
54116
|
if (head === "approve" || head === "deny") {
|
|
53288
54117
|
const approvalId = tokens[1]?.trim();
|
|
54118
|
+
if (head === "approve" && approvalId === "all") {
|
|
54119
|
+
const shouldResolvePending = await applyApproveAllPreset(cwd, runtime);
|
|
54120
|
+
if (!shouldResolvePending) {
|
|
54121
|
+
if (runtime.pendingRunProposal) {
|
|
54122
|
+
void startPendingRunExecution(cwd, runtime);
|
|
54123
|
+
return cwd;
|
|
54124
|
+
}
|
|
54125
|
+
console.log("No pending approvals right now. Future actions in this shell will use auto approvals.");
|
|
54126
|
+
return cwd;
|
|
54127
|
+
}
|
|
54128
|
+
await resolvePendingApproval(
|
|
54129
|
+
cwd,
|
|
54130
|
+
runtime,
|
|
54131
|
+
"approve",
|
|
54132
|
+
"all",
|
|
54133
|
+
{
|
|
54134
|
+
allowAll: true
|
|
54135
|
+
}
|
|
54136
|
+
);
|
|
54137
|
+
return cwd;
|
|
54138
|
+
}
|
|
53289
54139
|
if (!approvalId && runtime.pendingRunProposal) {
|
|
53290
54140
|
if (head === "approve") {
|
|
53291
54141
|
void startPendingRunExecution(cwd, runtime);
|
|
@@ -53316,9 +54166,9 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
53316
54166
|
}
|
|
53317
54167
|
async function runInteractiveShell(options) {
|
|
53318
54168
|
const readline = (0, import_promises27.createInterface)({
|
|
53319
|
-
input:
|
|
53320
|
-
output:
|
|
53321
|
-
terminal: Boolean(
|
|
54169
|
+
input: import_node_process36.default.stdin,
|
|
54170
|
+
output: import_node_process36.default.stdout,
|
|
54171
|
+
terminal: Boolean(import_node_process36.default.stdin.isTTY && import_node_process36.default.stdout.isTTY)
|
|
53322
54172
|
});
|
|
53323
54173
|
const runtime = {
|
|
53324
54174
|
focusRole: "coder",
|
|
@@ -53350,7 +54200,7 @@ async function runInteractiveShell(options) {
|
|
|
53350
54200
|
};
|
|
53351
54201
|
let currentCwd = options.cwd;
|
|
53352
54202
|
let closed = false;
|
|
53353
|
-
const useDashboard = Boolean(
|
|
54203
|
+
const useDashboard = Boolean(import_node_process36.default.stdin.isTTY && import_node_process36.default.stdout.isTTY);
|
|
53354
54204
|
const originalLog = console.log;
|
|
53355
54205
|
const originalError = console.error;
|
|
53356
54206
|
if (useDashboard) {
|
|
@@ -53366,7 +54216,7 @@ async function runInteractiveShell(options) {
|
|
|
53366
54216
|
readline.on("SIGINT", () => {
|
|
53367
54217
|
if (runtime.activeExecution) {
|
|
53368
54218
|
runtime.activeExecution.controller.abort();
|
|
53369
|
-
|
|
54219
|
+
import_node_process36.default.stdout.write("\n");
|
|
53370
54220
|
console.log(color(DIM, `Interrupt requested. Pausing ${runtime.activeExecution.label} after the current step...`));
|
|
53371
54221
|
return;
|
|
53372
54222
|
}
|
|
@@ -53387,10 +54237,14 @@ async function runInteractiveShell(options) {
|
|
|
53387
54237
|
try {
|
|
53388
54238
|
state = await getShellSessionState(currentCwd, runtime.focusRole, runtime);
|
|
53389
54239
|
runtime.dashboard?.update(currentCwd, state);
|
|
53390
|
-
line = await readline
|
|
54240
|
+
line = await readShellInput(readline, state);
|
|
53391
54241
|
} catch {
|
|
53392
54242
|
break;
|
|
53393
54243
|
}
|
|
54244
|
+
if (line === "__kimbho_sigint__") {
|
|
54245
|
+
closed = true;
|
|
54246
|
+
break;
|
|
54247
|
+
}
|
|
53394
54248
|
try {
|
|
53395
54249
|
currentCwd = await handleShellCommand(currentCwd, line, state, runtime, options.execute);
|
|
53396
54250
|
runtime.currentCwd = currentCwd;
|
|
@@ -53402,7 +54256,7 @@ async function runInteractiveShell(options) {
|
|
|
53402
54256
|
}
|
|
53403
54257
|
console.error(message);
|
|
53404
54258
|
} finally {
|
|
53405
|
-
|
|
54259
|
+
import_node_process36.default.exitCode = 0;
|
|
53406
54260
|
}
|
|
53407
54261
|
if (!closed && !useDashboard) {
|
|
53408
54262
|
console.log("");
|
|
@@ -53413,7 +54267,7 @@ async function runInteractiveShell(options) {
|
|
|
53413
54267
|
if (runtime.activeExecution) {
|
|
53414
54268
|
runtime.activeExecution.controller.abort();
|
|
53415
54269
|
}
|
|
53416
|
-
|
|
54270
|
+
import_node_process36.default.exitCode = 0;
|
|
53417
54271
|
if (useDashboard) {
|
|
53418
54272
|
runtime.dashboard?.stop();
|
|
53419
54273
|
console.log = originalLog;
|