@kimbho/kimbho-cli 0.1.32 → 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 +1023 -534
- 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 ",
|
|
@@ -42478,13 +42481,26 @@ function looksLikeInformationalRequest(input) {
|
|
|
42478
42481
|
if (/\b(tell me|describe|walk me through|help me understand)\b/.test(input)) {
|
|
42479
42482
|
return true;
|
|
42480
42483
|
}
|
|
42481
|
-
if (/\b(details?|overview|summary|walkthrough|explanation)\b/.test(input) &&
|
|
42484
|
+
if (/\b(details?|overview|summary|walkthrough|explanation|structure|layout|contents?)\b/.test(input) && (WORKSPACE_NOUN_PATTERN.test(input) || WORKSPACE_CONTENT_PATTERN.test(input))) {
|
|
42482
42485
|
return true;
|
|
42483
42486
|
}
|
|
42484
|
-
return
|
|
42487
|
+
return WORKSPACE_REFERENCE_PATTERN.test(input) && /\b(details?|overview|summary|about|inside|in|contents?|structure|layout)\b/.test(input);
|
|
42485
42488
|
}
|
|
42486
42489
|
function looksLikeWorkspaceInfoPrompt(input) {
|
|
42487
|
-
|
|
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;
|
|
42488
42504
|
}
|
|
42489
42505
|
function stripConversationalLead(input) {
|
|
42490
42506
|
let normalized = input.trim().toLowerCase();
|
|
@@ -42804,10 +42820,265 @@ async function resolveExecutionWorkspace(cwd, goal) {
|
|
|
42804
42820
|
};
|
|
42805
42821
|
}
|
|
42806
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
|
+
|
|
42807
43072
|
// src/commands/exec.ts
|
|
42808
43073
|
function resolveSkillPromptSource(input) {
|
|
42809
43074
|
return input.prompt || input.messages.at(-1)?.content || "";
|
|
42810
43075
|
}
|
|
43076
|
+
function shouldRouteToWorkspaceAnalysis(input, explicitIntent) {
|
|
43077
|
+
if (explicitIntent) {
|
|
43078
|
+
return false;
|
|
43079
|
+
}
|
|
43080
|
+
return looksLikeWorkspaceInfoPrompt(resolveSkillPromptSource(input));
|
|
43081
|
+
}
|
|
42811
43082
|
var IMAGE_EXTENSIONS = /* @__PURE__ */ new Map([
|
|
42812
43083
|
[".png", "image/png"],
|
|
42813
43084
|
[".jpg", "image/jpeg"],
|
|
@@ -42902,14 +43173,14 @@ async function pathExists4(filePath) {
|
|
|
42902
43173
|
}
|
|
42903
43174
|
}
|
|
42904
43175
|
function inferMimeType(name, fallback = "application/octet-stream") {
|
|
42905
|
-
const extension =
|
|
43176
|
+
const extension = import_node_path23.default.extname(name).toLowerCase();
|
|
42906
43177
|
return IMAGE_EXTENSIONS.get(extension) ?? TEXT_EXTENSIONS.get(extension) ?? fallback;
|
|
42907
43178
|
}
|
|
42908
43179
|
function isLikelyText(name, mimeType, buffer) {
|
|
42909
43180
|
if (mimeType.startsWith("text/") || mimeType === "application/json" || mimeType === "application/toml" || mimeType === "application/yaml" || mimeType === "application/xml") {
|
|
42910
43181
|
return true;
|
|
42911
43182
|
}
|
|
42912
|
-
if (TEXT_EXTENSIONS.has(
|
|
43183
|
+
if (TEXT_EXTENSIONS.has(import_node_path23.default.extname(name).toLowerCase())) {
|
|
42913
43184
|
return true;
|
|
42914
43185
|
}
|
|
42915
43186
|
return !buffer.includes(0);
|
|
@@ -42932,7 +43203,7 @@ async function fetchAttachment(value) {
|
|
|
42932
43203
|
throw new Error(`Failed to download attachment "${value}": ${response.status} ${response.statusText}`);
|
|
42933
43204
|
}
|
|
42934
43205
|
const url = new URL(value);
|
|
42935
|
-
const name2 =
|
|
43206
|
+
const name2 = import_node_path23.default.basename(url.pathname) || "attachment";
|
|
42936
43207
|
const mimeType = response.headers.get("content-type")?.split(";")[0]?.trim() ?? inferMimeType(name2);
|
|
42937
43208
|
const buffer2 = Buffer.from(await response.arrayBuffer());
|
|
42938
43209
|
return {
|
|
@@ -42941,9 +43212,9 @@ async function fetchAttachment(value) {
|
|
|
42941
43212
|
buffer: buffer2
|
|
42942
43213
|
};
|
|
42943
43214
|
}
|
|
42944
|
-
const filePath =
|
|
43215
|
+
const filePath = import_node_path23.default.resolve(import_node_process8.default.cwd(), value);
|
|
42945
43216
|
const buffer = await (0, import_promises22.readFile)(filePath);
|
|
42946
|
-
const name =
|
|
43217
|
+
const name = import_node_path23.default.basename(filePath);
|
|
42947
43218
|
return {
|
|
42948
43219
|
name,
|
|
42949
43220
|
mimeType: inferMimeType(name),
|
|
@@ -43140,7 +43411,7 @@ async function resolveJsonSchemaInput(cwd, schemaInput) {
|
|
|
43140
43411
|
if (!schemaInput) {
|
|
43141
43412
|
return null;
|
|
43142
43413
|
}
|
|
43143
|
-
const candidatePath =
|
|
43414
|
+
const candidatePath = import_node_path23.default.resolve(cwd, schemaInput);
|
|
43144
43415
|
if (await pathExists4(candidatePath)) {
|
|
43145
43416
|
const raw = await (0, import_promises22.readFile)(candidatePath, "utf8");
|
|
43146
43417
|
return JSON.parse(raw);
|
|
@@ -43169,7 +43440,7 @@ async function maybeWriteOutputFile(outputFile, format, payload, textOutput) {
|
|
|
43169
43440
|
if (!outputFile) {
|
|
43170
43441
|
return;
|
|
43171
43442
|
}
|
|
43172
|
-
const filePath =
|
|
43443
|
+
const filePath = import_node_path23.default.resolve(import_node_process8.default.cwd(), outputFile);
|
|
43173
43444
|
const serialized = format === "text" ? textOutput : `${renderJson(payload)}
|
|
43174
43445
|
`;
|
|
43175
43446
|
await (0, import_promises22.writeFile)(filePath, serialized, "utf8");
|
|
@@ -43397,8 +43668,104 @@ async function executeRunPrompt(cwd, input, format, options) {
|
|
|
43397
43668
|
textOutput
|
|
43398
43669
|
};
|
|
43399
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
|
+
}
|
|
43400
43741
|
async function executePromptByIntent(cwd, input, options = {}) {
|
|
43401
|
-
|
|
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));
|
|
43402
43769
|
if (intent === "chat") {
|
|
43403
43770
|
return executeChatPrompt(cwd, input);
|
|
43404
43771
|
}
|
|
@@ -43456,12 +43823,9 @@ function createExecCommand() {
|
|
|
43456
43823
|
file: options.file,
|
|
43457
43824
|
image: options.image
|
|
43458
43825
|
});
|
|
43459
|
-
const intent = inferPromptIntent(input.prompt || input.messages.at(-1)?.content || "");
|
|
43460
43826
|
const schema = await resolveJsonSchemaInput(cwd, options.jsonSchema);
|
|
43461
|
-
const result =
|
|
43462
|
-
|
|
43463
|
-
agentSelection
|
|
43464
|
-
}) : await executeRunPrompt(cwd, input, format, {
|
|
43827
|
+
const result = await executePromptByIntent(cwd, input, {
|
|
43828
|
+
outputFormat: format,
|
|
43465
43829
|
sessionId: options.sessionId,
|
|
43466
43830
|
ephemeral: options.ephemeral,
|
|
43467
43831
|
maxAutoTasks: options.maxAutoTasks,
|
|
@@ -43502,7 +43866,7 @@ function createExecCommand() {
|
|
|
43502
43866
|
|
|
43503
43867
|
// src/review-service.ts
|
|
43504
43868
|
var import_promises23 = require("node:fs/promises");
|
|
43505
|
-
var
|
|
43869
|
+
var import_node_path24 = __toESM(require("node:path"), 1);
|
|
43506
43870
|
function summarizeChangedFiles2(diff) {
|
|
43507
43871
|
const files = /* @__PURE__ */ new Set();
|
|
43508
43872
|
for (const line of diff.split("\n")) {
|
|
@@ -43571,20 +43935,20 @@ async function reviewWorkspace(cwd, options = {}) {
|
|
|
43571
43935
|
toolId: "file.read",
|
|
43572
43936
|
success: true,
|
|
43573
43937
|
summary: `Loaded review patch ${options.patchPath}.`,
|
|
43574
|
-
stdout: `patch:${
|
|
43938
|
+
stdout: `patch:${import_node_path24.default.resolve(cwd, options.patchPath)}`,
|
|
43575
43939
|
stderr: "",
|
|
43576
43940
|
artifacts: [
|
|
43577
|
-
|
|
43941
|
+
import_node_path24.default.resolve(cwd, options.patchPath)
|
|
43578
43942
|
]
|
|
43579
43943
|
} : await runtime.run("git.status", {}, { cwd });
|
|
43580
43944
|
const diff = options.patchPath ? {
|
|
43581
43945
|
toolId: "file.read",
|
|
43582
43946
|
success: true,
|
|
43583
43947
|
summary: `Loaded review patch ${options.patchPath}.`,
|
|
43584
|
-
stdout: await (0, import_promises23.readFile)(
|
|
43948
|
+
stdout: await (0, import_promises23.readFile)(import_node_path24.default.resolve(cwd, options.patchPath), "utf8"),
|
|
43585
43949
|
stderr: "",
|
|
43586
43950
|
artifacts: [
|
|
43587
|
-
|
|
43951
|
+
import_node_path24.default.resolve(cwd, options.patchPath)
|
|
43588
43952
|
]
|
|
43589
43953
|
} : await runtime.run("git.diff", {}, { cwd });
|
|
43590
43954
|
const repoIndex = await runtime.run("repo.index", {}, { cwd }).catch(() => null);
|
|
@@ -43651,7 +44015,7 @@ ${diff.stdout}`
|
|
|
43651
44015
|
}
|
|
43652
44016
|
}
|
|
43653
44017
|
await ensureKimbhoDir(cwd);
|
|
43654
|
-
const artifactPath =
|
|
44018
|
+
const artifactPath = import_node_path24.default.join(resolveKimbhoDir(cwd), "logs", `review-${Date.now()}.md`);
|
|
43655
44019
|
await (0, import_promises23.writeFile)(artifactPath, [
|
|
43656
44020
|
`# Review`,
|
|
43657
44021
|
``,
|
|
@@ -45245,7 +45609,7 @@ function createChromeCommand() {
|
|
|
45245
45609
|
|
|
45246
45610
|
// src/commands/cloud.ts
|
|
45247
45611
|
var import_promises24 = require("node:fs/promises");
|
|
45248
|
-
var
|
|
45612
|
+
var import_node_path25 = __toESM(require("node:path"), 1);
|
|
45249
45613
|
var import_node_process12 = __toESM(require("node:process"), 1);
|
|
45250
45614
|
var import_node_child_process8 = require("node:child_process");
|
|
45251
45615
|
function parseCount2(value) {
|
|
@@ -45317,15 +45681,15 @@ async function resolveSession(sessionId, last = false) {
|
|
|
45317
45681
|
return loadSessionById(sessionId, import_node_process12.default.cwd());
|
|
45318
45682
|
}
|
|
45319
45683
|
async function ensureCloudPatchDir(cwd) {
|
|
45320
|
-
const outputDir =
|
|
45684
|
+
const outputDir = import_node_path25.default.join(resolveKimbhoDir(cwd), "cloud");
|
|
45321
45685
|
await (0, import_promises24.mkdir)(outputDir, {
|
|
45322
45686
|
recursive: true
|
|
45323
45687
|
});
|
|
45324
45688
|
return outputDir;
|
|
45325
45689
|
}
|
|
45326
45690
|
async function writePatchArtifact(cwd, taskId, patchArtifact, output) {
|
|
45327
|
-
const outputPath = output ?
|
|
45328
|
-
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), {
|
|
45329
45693
|
recursive: true
|
|
45330
45694
|
});
|
|
45331
45695
|
await (0, import_promises24.writeFile)(outputPath, patchArtifact.content, "utf8");
|
|
@@ -45474,7 +45838,7 @@ function createCloudCommand() {
|
|
|
45474
45838
|
}
|
|
45475
45839
|
|
|
45476
45840
|
// src/commands/compat.ts
|
|
45477
|
-
var
|
|
45841
|
+
var import_node_path26 = __toESM(require("node:path"), 1);
|
|
45478
45842
|
var import_node_process13 = __toESM(require("node:process"), 1);
|
|
45479
45843
|
|
|
45480
45844
|
// src/plugin-commands.ts
|
|
@@ -45837,7 +46201,7 @@ function createPluginCommand() {
|
|
|
45837
46201
|
const cwd = import_node_process13.default.cwd();
|
|
45838
46202
|
const { direct, resolved } = await loadScopedConfig(scope, cwd);
|
|
45839
46203
|
const current = baseConfig(direct, resolved);
|
|
45840
|
-
const normalized =
|
|
46204
|
+
const normalized = import_node_path26.default.resolve(cwd, directory);
|
|
45841
46205
|
const outputPath = await saveScopedConfig(scope, cwd, {
|
|
45842
46206
|
...current,
|
|
45843
46207
|
pluginDirectories: Array.from(/* @__PURE__ */ new Set([
|
|
@@ -45852,7 +46216,7 @@ function createPluginCommand() {
|
|
|
45852
46216
|
const cwd = import_node_process13.default.cwd();
|
|
45853
46217
|
const { direct, resolved } = await loadScopedConfig(scope, cwd);
|
|
45854
46218
|
const current = baseConfig(direct, resolved);
|
|
45855
|
-
const normalized =
|
|
46219
|
+
const normalized = import_node_path26.default.resolve(cwd, directory);
|
|
45856
46220
|
const outputPath = await saveScopedConfig(scope, cwd, {
|
|
45857
46221
|
...current,
|
|
45858
46222
|
pluginDirectories: current.pluginDirectories.filter((entry) => entry !== directory && entry !== normalized)
|
|
@@ -46029,11 +46393,11 @@ function createSandboxCommand() {
|
|
|
46029
46393
|
var import_node_process14 = __toESM(require("node:process"), 1);
|
|
46030
46394
|
|
|
46031
46395
|
// src/memory.ts
|
|
46032
|
-
var
|
|
46396
|
+
var import_node_path28 = __toESM(require("node:path"), 1);
|
|
46033
46397
|
|
|
46034
46398
|
// src/project-init.ts
|
|
46035
46399
|
var import_promises25 = require("node:fs/promises");
|
|
46036
|
-
var
|
|
46400
|
+
var import_node_path27 = __toESM(require("node:path"), 1);
|
|
46037
46401
|
var import_node_child_process9 = require("node:child_process");
|
|
46038
46402
|
var import_node_util = require("node:util");
|
|
46039
46403
|
var execFileAsync = (0, import_node_util.promisify)(import_node_child_process9.execFile);
|
|
@@ -46046,16 +46410,16 @@ async function pathExists5(filePath) {
|
|
|
46046
46410
|
}
|
|
46047
46411
|
}
|
|
46048
46412
|
async function detectPackageManager(cwd) {
|
|
46049
|
-
if (await pathExists5(
|
|
46413
|
+
if (await pathExists5(import_node_path27.default.join(cwd, "pnpm-lock.yaml"))) {
|
|
46050
46414
|
return "pnpm";
|
|
46051
46415
|
}
|
|
46052
|
-
if (await pathExists5(
|
|
46416
|
+
if (await pathExists5(import_node_path27.default.join(cwd, "yarn.lock"))) {
|
|
46053
46417
|
return "yarn";
|
|
46054
46418
|
}
|
|
46055
|
-
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"))) {
|
|
46056
46420
|
return "bun";
|
|
46057
46421
|
}
|
|
46058
|
-
if (await pathExists5(
|
|
46422
|
+
if (await pathExists5(import_node_path27.default.join(cwd, "package-lock.json"))) {
|
|
46059
46423
|
return "npm";
|
|
46060
46424
|
}
|
|
46061
46425
|
return "npm";
|
|
@@ -46199,8 +46563,8 @@ async function generateProjectInitFile(cwd, outputFileName = "kimbho_init.md") {
|
|
|
46199
46563
|
const entrypoints = inferPrimaryEntrypoints(index);
|
|
46200
46564
|
const verificationCommands = inferVerificationCommands(rootPackage, packageManager);
|
|
46201
46565
|
const git = await captureGitSnapshot(cwd);
|
|
46202
|
-
const packageJson = await readJsonFile2(
|
|
46203
|
-
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);
|
|
46204
46568
|
const summaryLines = [
|
|
46205
46569
|
`- workspace: \`${cwd}\``,
|
|
46206
46570
|
`- generated: ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
@@ -46261,14 +46625,14 @@ async function generateProjectInitFile(cwd, outputFileName = "kimbho_init.md") {
|
|
|
46261
46625
|
renderSection("Schemas", schemaLines),
|
|
46262
46626
|
renderSection("Key Symbols", symbolLines),
|
|
46263
46627
|
renderSection("Agent Guidance", guidanceLines),
|
|
46264
|
-
`Repo index artifact: \`${
|
|
46628
|
+
`Repo index artifact: \`${import_node_path27.default.relative(cwd, artifactPath) || artifactPath}\``,
|
|
46265
46629
|
""
|
|
46266
46630
|
].join("\n");
|
|
46267
46631
|
await (0, import_promises25.writeFile)(outputPath, content, "utf8");
|
|
46268
46632
|
return {
|
|
46269
46633
|
outputPath,
|
|
46270
46634
|
indexArtifactPath: artifactPath,
|
|
46271
|
-
summary: `Generated ${outputFileName} with indexed project context for ${
|
|
46635
|
+
summary: `Generated ${outputFileName} with indexed project context for ${import_node_path27.default.basename(cwd)}.`,
|
|
46272
46636
|
purpose,
|
|
46273
46637
|
frameworks,
|
|
46274
46638
|
entrypoints,
|
|
@@ -46289,7 +46653,7 @@ function renderProjectMemory(initFilePath) {
|
|
|
46289
46653
|
"",
|
|
46290
46654
|
"## Canonical References",
|
|
46291
46655
|
"",
|
|
46292
|
-
`- bootstrap: \`${
|
|
46656
|
+
`- bootstrap: \`${import_node_path28.default.basename(initFilePath)}\``,
|
|
46293
46657
|
"- read the bootstrap file before large changes",
|
|
46294
46658
|
"- record important repo-specific rules here so future runs do not need to rediscover them",
|
|
46295
46659
|
"",
|
|
@@ -46333,7 +46697,7 @@ async function refreshMemoryFiles(cwd) {
|
|
|
46333
46697
|
initFilePath: init.outputPath,
|
|
46334
46698
|
projectMemoryPath,
|
|
46335
46699
|
userMemoryPath,
|
|
46336
|
-
summary: `Refreshed project bootstrap and memory files for ${
|
|
46700
|
+
summary: `Refreshed project bootstrap and memory files for ${import_node_path28.default.basename(cwd)}.`,
|
|
46337
46701
|
purpose: init.purpose,
|
|
46338
46702
|
frameworks: init.frameworks,
|
|
46339
46703
|
entrypoints: init.entrypoints,
|
|
@@ -46354,7 +46718,7 @@ async function appendMemoryNote(cwd, scope, text, agentId) {
|
|
|
46354
46718
|
throw new Error("Agent memory updates require an agent id.");
|
|
46355
46719
|
}
|
|
46356
46720
|
return appendMarkdownSection(
|
|
46357
|
-
|
|
46721
|
+
import_node_path28.default.join(resolveAgentMemoryDir(cwd), `${agentId}.md`),
|
|
46358
46722
|
"Note",
|
|
46359
46723
|
text
|
|
46360
46724
|
);
|
|
@@ -46364,7 +46728,7 @@ async function appendMemoryNote(cwd, scope, text, agentId) {
|
|
|
46364
46728
|
async function listMemoryPaths(cwd) {
|
|
46365
46729
|
await ensureMemoryDirs(cwd);
|
|
46366
46730
|
return {
|
|
46367
|
-
initFilePath:
|
|
46731
|
+
initFilePath: import_node_path28.default.join(cwd, "kimbho_init.md"),
|
|
46368
46732
|
projectMemoryPath: resolveProjectMemoryPath(cwd),
|
|
46369
46733
|
userMemoryPath: resolveUserMemoryPath(),
|
|
46370
46734
|
adaptiveProjectMemoryPath: resolveAdaptiveProjectMemoryPath(cwd),
|
|
@@ -46726,7 +47090,7 @@ function createDoctorCommand() {
|
|
|
46726
47090
|
});
|
|
46727
47091
|
}
|
|
46728
47092
|
|
|
46729
|
-
// src/commands/
|
|
47093
|
+
// src/commands/fix.ts
|
|
46730
47094
|
var import_node_process17 = __toESM(require("node:process"), 1);
|
|
46731
47095
|
function parseCount3(value) {
|
|
46732
47096
|
const parsed = Number(value);
|
|
@@ -46735,6 +47099,111 @@ function parseCount3(value) {
|
|
|
46735
47099
|
}
|
|
46736
47100
|
return parsed;
|
|
46737
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
|
+
}
|
|
46738
47207
|
function printSessionList(rows) {
|
|
46739
47208
|
if (rows.length === 0) {
|
|
46740
47209
|
console.log("No saved sessions found.");
|
|
@@ -46759,8 +47228,8 @@ async function resolveSourceSession(cwd, sessionId, last = false, search) {
|
|
|
46759
47228
|
return loadSessionById(sessionId, cwd);
|
|
46760
47229
|
}
|
|
46761
47230
|
function createForkCommand() {
|
|
46762
|
-
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",
|
|
46763
|
-
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();
|
|
46764
47233
|
if (options.list) {
|
|
46765
47234
|
const sessions = options.search ? await searchSessions(options.search, cwd) : await listSessions(cwd);
|
|
46766
47235
|
if (options.json) {
|
|
@@ -46773,7 +47242,7 @@ function createForkCommand() {
|
|
|
46773
47242
|
const source = await resolveSourceSession(cwd, sessionId, options.last, options.search);
|
|
46774
47243
|
if (!source) {
|
|
46775
47244
|
console.error("No saved session found.");
|
|
46776
|
-
|
|
47245
|
+
import_node_process18.default.exitCode = 1;
|
|
46777
47246
|
return;
|
|
46778
47247
|
}
|
|
46779
47248
|
const forked = forkSessionSnapshot(source);
|
|
@@ -46811,7 +47280,7 @@ function createForkCommand() {
|
|
|
46811
47280
|
}
|
|
46812
47281
|
|
|
46813
47282
|
// src/commands/init.ts
|
|
46814
|
-
var
|
|
47283
|
+
var import_node_process19 = __toESM(require("node:process"), 1);
|
|
46815
47284
|
function printProjectUnderstanding(result) {
|
|
46816
47285
|
console.log(result.summary);
|
|
46817
47286
|
console.log("Now I have a durable understanding of the current project structure.");
|
|
@@ -46830,7 +47299,7 @@ function printProjectUnderstanding(result) {
|
|
|
46830
47299
|
}
|
|
46831
47300
|
function createInitCommand() {
|
|
46832
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) => {
|
|
46833
|
-
const existing = await loadConfig(
|
|
47302
|
+
const existing = await loadConfig(import_node_process19.default.cwd());
|
|
46834
47303
|
const configMutationRequested = [
|
|
46835
47304
|
options.template,
|
|
46836
47305
|
options.providerId,
|
|
@@ -46844,12 +47313,12 @@ function createInitCommand() {
|
|
|
46844
47313
|
].some((value) => typeof value === "string" && value.trim().length > 0);
|
|
46845
47314
|
if (options.configOnly && options.memoryOnly) {
|
|
46846
47315
|
console.error("Choose either --config-only or --memory-only, not both.");
|
|
46847
|
-
|
|
47316
|
+
import_node_process19.default.exitCode = 1;
|
|
46848
47317
|
return;
|
|
46849
47318
|
}
|
|
46850
47319
|
if (existing && !options.force && configMutationRequested && !options.memoryOnly) {
|
|
46851
47320
|
console.error("Config already exists. Re-run with --force to overwrite it.");
|
|
46852
|
-
|
|
47321
|
+
import_node_process19.default.exitCode = 1;
|
|
46853
47322
|
return;
|
|
46854
47323
|
}
|
|
46855
47324
|
if (!options.memoryOnly) {
|
|
@@ -46887,20 +47356,20 @@ function createInitCommand() {
|
|
|
46887
47356
|
defaultModel: options.model ?? provider.defaultModel,
|
|
46888
47357
|
fastModel: options.fastModel ?? options.model ?? provider.defaultModel
|
|
46889
47358
|
});
|
|
46890
|
-
const outputPath = await saveConfig(nextConfig,
|
|
47359
|
+
const outputPath = await saveConfig(nextConfig, import_node_process19.default.cwd());
|
|
46891
47360
|
console.log(`Created ${outputPath}`);
|
|
46892
47361
|
}
|
|
46893
47362
|
}
|
|
46894
47363
|
if (!options.configOnly) {
|
|
46895
|
-
const result = await refreshMemoryFiles(
|
|
47364
|
+
const result = await refreshMemoryFiles(import_node_process19.default.cwd());
|
|
46896
47365
|
printProjectUnderstanding(result);
|
|
46897
47366
|
}
|
|
46898
47367
|
});
|
|
46899
47368
|
}
|
|
46900
47369
|
|
|
46901
47370
|
// src/commands/ide.ts
|
|
46902
|
-
var
|
|
46903
|
-
var
|
|
47371
|
+
var import_node_path29 = __toESM(require("node:path"), 1);
|
|
47372
|
+
var import_node_process20 = __toESM(require("node:process"), 1);
|
|
46904
47373
|
function renderIdeState(state) {
|
|
46905
47374
|
if (!state) {
|
|
46906
47375
|
return "No IDE companion is linked.";
|
|
@@ -46918,27 +47387,27 @@ function renderIdeState(state) {
|
|
|
46918
47387
|
function createIdeCommand() {
|
|
46919
47388
|
const command = new Command("ide").description("Discover, link, and open the active workspace in a local IDE companion.");
|
|
46920
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) => {
|
|
46921
|
-
const state = await detectIdeBridge(
|
|
47390
|
+
const state = await detectIdeBridge(import_node_process20.default.cwd());
|
|
46922
47391
|
if (options.json) {
|
|
46923
47392
|
console.log(JSON.stringify(state, null, 2));
|
|
46924
47393
|
return;
|
|
46925
47394
|
}
|
|
46926
47395
|
console.log(renderIdeState(state));
|
|
46927
47396
|
});
|
|
46928
|
-
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",
|
|
46929
|
-
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;
|
|
46930
47399
|
const state = {
|
|
46931
47400
|
editorId: options.command ? options.editor : detected?.editorId ?? options.editor,
|
|
46932
47401
|
label: options.label ?? detected?.label ?? options.editor,
|
|
46933
47402
|
command: options.command ?? detected?.command ?? options.editor,
|
|
46934
|
-
workspace:
|
|
47403
|
+
workspace: import_node_path29.default.resolve(import_node_process20.default.cwd(), options.workspace),
|
|
46935
47404
|
source: options.command ? "manual" : detected?.source ?? "detected",
|
|
46936
47405
|
linkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
46937
47406
|
...detected?.lastOpenedPath ? {
|
|
46938
47407
|
lastOpenedPath: detected.lastOpenedPath
|
|
46939
47408
|
} : {}
|
|
46940
47409
|
};
|
|
46941
|
-
const outputPath = await saveIdeBridgeState(
|
|
47410
|
+
const outputPath = await saveIdeBridgeState(import_node_process20.default.cwd(), state);
|
|
46942
47411
|
if (options.json) {
|
|
46943
47412
|
console.log(JSON.stringify({
|
|
46944
47413
|
state,
|
|
@@ -46950,13 +47419,13 @@ function createIdeCommand() {
|
|
|
46950
47419
|
console.log(`Saved: ${outputPath}`);
|
|
46951
47420
|
});
|
|
46952
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) => {
|
|
46953
|
-
const state = await openInIde(
|
|
47422
|
+
const state = await openInIde(import_node_process20.default.cwd(), target, {
|
|
46954
47423
|
line: Number.isInteger(options.line) && options.line > 0 ? options.line : void 0,
|
|
46955
47424
|
column: Number.isInteger(options.column) && options.column > 0 ? options.column : void 0
|
|
46956
47425
|
});
|
|
46957
47426
|
const payload = {
|
|
46958
47427
|
state,
|
|
46959
|
-
target:
|
|
47428
|
+
target: import_node_path29.default.resolve(import_node_process20.default.cwd(), target)
|
|
46960
47429
|
};
|
|
46961
47430
|
if (options.json) {
|
|
46962
47431
|
console.log(JSON.stringify(payload, null, 2));
|
|
@@ -46968,7 +47437,7 @@ function createIdeCommand() {
|
|
|
46968
47437
|
}
|
|
46969
47438
|
|
|
46970
47439
|
// src/commands/update.ts
|
|
46971
|
-
var
|
|
47440
|
+
var import_node_process21 = __toESM(require("node:process"), 1);
|
|
46972
47441
|
function renderUpdatePayload(payload) {
|
|
46973
47442
|
return [
|
|
46974
47443
|
`current: ${payload.currentVersion}`,
|
|
@@ -46997,7 +47466,7 @@ function createInstallCommand() {
|
|
|
46997
47466
|
console.log(result.detail);
|
|
46998
47467
|
}
|
|
46999
47468
|
if (!result.ok) {
|
|
47000
|
-
|
|
47469
|
+
import_node_process21.default.exitCode = 1;
|
|
47001
47470
|
}
|
|
47002
47471
|
return;
|
|
47003
47472
|
}
|
|
@@ -47010,7 +47479,7 @@ function createInstallCommand() {
|
|
|
47010
47479
|
}
|
|
47011
47480
|
function createUpdateCommand(commandName = "update") {
|
|
47012
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) => {
|
|
47013
|
-
const payload = await resolveUpdateManifest(
|
|
47482
|
+
const payload = await resolveUpdateManifest(import_node_process21.default.cwd());
|
|
47014
47483
|
const updateAvailable = isUpgradeAvailable(payload);
|
|
47015
47484
|
if (options.apply && updateAvailable) {
|
|
47016
47485
|
const result = runGlobalNpmInstall(payload.latestVersion);
|
|
@@ -47024,7 +47493,7 @@ function createUpdateCommand(commandName = "update") {
|
|
|
47024
47493
|
console.log(result.detail);
|
|
47025
47494
|
}
|
|
47026
47495
|
if (!result.ok) {
|
|
47027
|
-
|
|
47496
|
+
import_node_process21.default.exitCode = 1;
|
|
47028
47497
|
}
|
|
47029
47498
|
return;
|
|
47030
47499
|
}
|
|
@@ -47041,7 +47510,7 @@ function createUpdateCommand(commandName = "update") {
|
|
|
47041
47510
|
}
|
|
47042
47511
|
|
|
47043
47512
|
// src/commands/mcp.ts
|
|
47044
|
-
var
|
|
47513
|
+
var import_node_process22 = __toESM(require("node:process"), 1);
|
|
47045
47514
|
|
|
47046
47515
|
// src/mcp.ts
|
|
47047
47516
|
async function renderMcpServerList(cwd) {
|
|
@@ -47205,7 +47674,7 @@ function collectValues(value, previous = []) {
|
|
|
47205
47674
|
function createMcpCommand() {
|
|
47206
47675
|
const command = new Command("mcp").description("Manage project-local MCP servers in .mcp.json.");
|
|
47207
47676
|
command.command("list").description("List configured MCP servers.").action(async () => {
|
|
47208
|
-
for (const line of await renderMcpServerList(
|
|
47677
|
+
for (const line of await renderMcpServerList(import_node_process22.default.cwd())) {
|
|
47209
47678
|
console.log(line);
|
|
47210
47679
|
}
|
|
47211
47680
|
});
|
|
@@ -47213,7 +47682,7 @@ function createMcpCommand() {
|
|
|
47213
47682
|
const env = Object.fromEntries(
|
|
47214
47683
|
options.env.map((pair) => pair.split("=", 2)).filter((entry) => entry.length === 2 && entry[0].length > 0)
|
|
47215
47684
|
);
|
|
47216
|
-
const outputPath = await addMcpServer(
|
|
47685
|
+
const outputPath = await addMcpServer(import_node_process22.default.cwd(), name, {
|
|
47217
47686
|
command: options.command,
|
|
47218
47687
|
args: options.arg,
|
|
47219
47688
|
env,
|
|
@@ -47227,34 +47696,34 @@ function createMcpCommand() {
|
|
|
47227
47696
|
console.log(`Updated ${outputPath}`);
|
|
47228
47697
|
});
|
|
47229
47698
|
command.command("remove").description("Remove an MCP server.").argument("<name>", "Server name").action(async (name) => {
|
|
47230
|
-
const outputPath = await removeMcpServerByName(
|
|
47699
|
+
const outputPath = await removeMcpServerByName(import_node_process22.default.cwd(), name);
|
|
47231
47700
|
console.log(`Updated ${outputPath}`);
|
|
47232
47701
|
});
|
|
47233
47702
|
command.command("enable").description("Enable an MCP server.").argument("<name>", "Server name").action(async (name) => {
|
|
47234
|
-
const outputPath = await toggleMcpServer(
|
|
47703
|
+
const outputPath = await toggleMcpServer(import_node_process22.default.cwd(), name, true);
|
|
47235
47704
|
console.log(`Updated ${outputPath}`);
|
|
47236
47705
|
});
|
|
47237
47706
|
command.command("disable").description("Disable an MCP server.").argument("<name>", "Server name").action(async (name) => {
|
|
47238
|
-
const outputPath = await toggleMcpServer(
|
|
47707
|
+
const outputPath = await toggleMcpServer(import_node_process22.default.cwd(), name, false);
|
|
47239
47708
|
console.log(`Updated ${outputPath}`);
|
|
47240
47709
|
});
|
|
47241
47710
|
command.command("tools").description("Inspect MCP tool, prompt, and resource inventory.").argument("[name]", "Optional server name").action(async (name) => {
|
|
47242
|
-
for (const line of await renderMcpInventory(
|
|
47711
|
+
for (const line of await renderMcpInventory(import_node_process22.default.cwd(), name)) {
|
|
47243
47712
|
console.log(line);
|
|
47244
47713
|
}
|
|
47245
47714
|
});
|
|
47246
47715
|
command.command("discover").description("Show MCP tools, prompts-as-commands, and resource attachment syntax.").argument("[name]", "Optional server name").action(async (name) => {
|
|
47247
|
-
for (const line of await renderMcpInventory(
|
|
47716
|
+
for (const line of await renderMcpInventory(import_node_process22.default.cwd(), name)) {
|
|
47248
47717
|
console.log(line);
|
|
47249
47718
|
}
|
|
47250
47719
|
});
|
|
47251
47720
|
command.command("prompts").description("List MCP prompts.").argument("[name]", "Optional server name").action(async (name) => {
|
|
47252
|
-
for (const line of await renderMcpPromptList(
|
|
47721
|
+
for (const line of await renderMcpPromptList(import_node_process22.default.cwd(), name)) {
|
|
47253
47722
|
console.log(line);
|
|
47254
47723
|
}
|
|
47255
47724
|
});
|
|
47256
47725
|
command.command("resources").description("List MCP resources and resource templates.").argument("[name]", "Optional server name").action(async (name) => {
|
|
47257
|
-
for (const line of await renderMcpResourceList(
|
|
47726
|
+
for (const line of await renderMcpResourceList(import_node_process22.default.cwd(), name)) {
|
|
47258
47727
|
console.log(line);
|
|
47259
47728
|
}
|
|
47260
47729
|
});
|
|
@@ -47262,12 +47731,12 @@ function createMcpCommand() {
|
|
|
47262
47731
|
const args = Object.fromEntries(
|
|
47263
47732
|
rawArgs.map((entry) => entry.split("=", 2)).filter((parts) => parts.length === 2 && parts[0].length > 0)
|
|
47264
47733
|
);
|
|
47265
|
-
for (const line of await renderMcpPromptInvocation(
|
|
47734
|
+
for (const line of await renderMcpPromptInvocation(import_node_process22.default.cwd(), server, prompt, args)) {
|
|
47266
47735
|
console.log(line);
|
|
47267
47736
|
}
|
|
47268
47737
|
});
|
|
47269
47738
|
command.command("read").description("Read one MCP resource by URI.").argument("<server>", "Server name").argument("<uri>", "Resource URI").action(async (server, uri) => {
|
|
47270
|
-
for (const line of await renderMcpResourceRead(
|
|
47739
|
+
for (const line of await renderMcpResourceRead(import_node_process22.default.cwd(), server, uri)) {
|
|
47271
47740
|
console.log(line);
|
|
47272
47741
|
}
|
|
47273
47742
|
});
|
|
@@ -47275,20 +47744,20 @@ function createMcpCommand() {
|
|
|
47275
47744
|
}
|
|
47276
47745
|
|
|
47277
47746
|
// src/commands/mcp-server.ts
|
|
47278
|
-
var
|
|
47747
|
+
var import_node_process23 = __toESM(require("node:process"), 1);
|
|
47279
47748
|
function createMcpServerCommand() {
|
|
47280
47749
|
return new Command("mcp-server").description("Run Kimbho as an MCP server over stdio.").action(async () => {
|
|
47281
|
-
await runMcpServer(
|
|
47750
|
+
await runMcpServer(import_node_process23.default.cwd());
|
|
47282
47751
|
});
|
|
47283
47752
|
}
|
|
47284
47753
|
|
|
47285
47754
|
// src/commands/memory.ts
|
|
47286
|
-
var
|
|
47287
|
-
var
|
|
47755
|
+
var import_node_path30 = __toESM(require("node:path"), 1);
|
|
47756
|
+
var import_node_process24 = __toESM(require("node:process"), 1);
|
|
47288
47757
|
function createMemoryCommand() {
|
|
47289
47758
|
const command = new Command("memory").description("Manage markdown-backed Kimbho memory files.");
|
|
47290
47759
|
command.command("status").description("Show the memory file locations.").action(async () => {
|
|
47291
|
-
const paths = await listMemoryPaths(
|
|
47760
|
+
const paths = await listMemoryPaths(import_node_process24.default.cwd());
|
|
47292
47761
|
console.log(`init: ${paths.initFilePath}`);
|
|
47293
47762
|
console.log(`project: ${paths.projectMemoryPath}`);
|
|
47294
47763
|
console.log(`user: ${paths.userMemoryPath}`);
|
|
@@ -47298,7 +47767,7 @@ function createMemoryCommand() {
|
|
|
47298
47767
|
console.log(`agents: ${paths.agentMemoryDir}`);
|
|
47299
47768
|
});
|
|
47300
47769
|
command.command("refresh").description("Refresh kimbho_init.md and project memory.").action(async () => {
|
|
47301
|
-
const result = await refreshMemoryFiles(
|
|
47770
|
+
const result = await refreshMemoryFiles(import_node_process24.default.cwd());
|
|
47302
47771
|
console.log(result.summary);
|
|
47303
47772
|
console.log(`Wrote ${result.initFilePath}`);
|
|
47304
47773
|
console.log(`Wrote ${result.projectMemoryPath}`);
|
|
@@ -47307,16 +47776,16 @@ function createMemoryCommand() {
|
|
|
47307
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) => {
|
|
47308
47777
|
let filePath;
|
|
47309
47778
|
if (scope === "init") {
|
|
47310
|
-
filePath =
|
|
47779
|
+
filePath = import_node_path30.default.join(import_node_process24.default.cwd(), "kimbho_init.md");
|
|
47311
47780
|
} else if (scope === "project") {
|
|
47312
|
-
filePath = resolveProjectMemoryPath(
|
|
47781
|
+
filePath = resolveProjectMemoryPath(import_node_process24.default.cwd());
|
|
47313
47782
|
} else if (scope === "user") {
|
|
47314
47783
|
filePath = resolveUserMemoryPath();
|
|
47315
47784
|
} else if (scope === "agent") {
|
|
47316
47785
|
if (!agentId) {
|
|
47317
47786
|
throw new Error("Pass an agent id when using scope=agent.");
|
|
47318
47787
|
}
|
|
47319
|
-
filePath =
|
|
47788
|
+
filePath = import_node_path30.default.join(resolveAgentMemoryDir(import_node_process24.default.cwd()), `${agentId}.md`);
|
|
47320
47789
|
} else {
|
|
47321
47790
|
throw new Error("Scope must be one of: init, project, user, agent.");
|
|
47322
47791
|
}
|
|
@@ -47329,7 +47798,7 @@ function createMemoryCommand() {
|
|
|
47329
47798
|
});
|
|
47330
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 = []) => {
|
|
47331
47800
|
if (scope === "project" || scope === "user") {
|
|
47332
|
-
const outputPath = await appendMemoryNote(
|
|
47801
|
+
const outputPath = await appendMemoryNote(import_node_process24.default.cwd(), scope, [
|
|
47333
47802
|
first,
|
|
47334
47803
|
...rest
|
|
47335
47804
|
].join(" "));
|
|
@@ -47337,7 +47806,7 @@ function createMemoryCommand() {
|
|
|
47337
47806
|
return;
|
|
47338
47807
|
}
|
|
47339
47808
|
if (scope === "agent") {
|
|
47340
|
-
const outputPath = await appendMemoryNote(
|
|
47809
|
+
const outputPath = await appendMemoryNote(import_node_process24.default.cwd(), "agent", rest.join(" "), first);
|
|
47341
47810
|
console.log(`Updated ${outputPath}`);
|
|
47342
47811
|
return;
|
|
47343
47812
|
}
|
|
@@ -47347,7 +47816,7 @@ function createMemoryCommand() {
|
|
|
47347
47816
|
}
|
|
47348
47817
|
|
|
47349
47818
|
// src/commands/model.ts
|
|
47350
|
-
var
|
|
47819
|
+
var import_node_process25 = __toESM(require("node:process"), 1);
|
|
47351
47820
|
function requireConfig() {
|
|
47352
47821
|
throw new Error("No config found. Run `kimbho init` first.");
|
|
47353
47822
|
}
|
|
@@ -47370,7 +47839,7 @@ async function fetchModels(provider, options) {
|
|
|
47370
47839
|
models: cachedModels
|
|
47371
47840
|
};
|
|
47372
47841
|
}
|
|
47373
|
-
const registry2 = createDefaultBrainProviderRegistry(
|
|
47842
|
+
const registry2 = createDefaultBrainProviderRegistry(import_node_process25.default.cwd());
|
|
47374
47843
|
try {
|
|
47375
47844
|
const models = await registry2.listModels(provider, {
|
|
47376
47845
|
...options.search ? {
|
|
@@ -47412,14 +47881,14 @@ function printAssignments(config2) {
|
|
|
47412
47881
|
function createModelCommand() {
|
|
47413
47882
|
const command = new Command("model").description("Use one MECE surface for providers, models, and role assignments.");
|
|
47414
47883
|
command.command("show").description("Show current provider/model assignments.").action(async () => {
|
|
47415
|
-
const config2 = await loadConfig(
|
|
47884
|
+
const config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47416
47885
|
if (!config2) {
|
|
47417
47886
|
requireConfig();
|
|
47418
47887
|
}
|
|
47419
47888
|
printAssignments(config2);
|
|
47420
47889
|
});
|
|
47421
47890
|
command.command("providers").description("List configured providers.").action(async () => {
|
|
47422
|
-
const config2 = await loadConfig(
|
|
47891
|
+
const config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47423
47892
|
if (!config2) {
|
|
47424
47893
|
requireConfig();
|
|
47425
47894
|
}
|
|
@@ -47442,7 +47911,7 @@ function createModelCommand() {
|
|
|
47442
47911
|
}
|
|
47443
47912
|
});
|
|
47444
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) => {
|
|
47445
|
-
const config2 = await loadConfig(
|
|
47914
|
+
const config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47446
47915
|
if (!config2) {
|
|
47447
47916
|
requireConfig();
|
|
47448
47917
|
}
|
|
@@ -47453,12 +47922,12 @@ function createModelCommand() {
|
|
|
47453
47922
|
apiKeyEnv: options.apiKeyEnv,
|
|
47454
47923
|
model: options.model
|
|
47455
47924
|
});
|
|
47456
|
-
const outputPath = await saveConfig(upsertProvider(config2, provider),
|
|
47925
|
+
const outputPath = await saveConfig(upsertProvider(config2, provider), import_node_process25.default.cwd());
|
|
47457
47926
|
console.log(`Updated ${outputPath}`);
|
|
47458
47927
|
console.log(`Added ${provider.id} via ${templateId}`);
|
|
47459
47928
|
});
|
|
47460
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) => {
|
|
47461
|
-
const config2 = await loadConfig(
|
|
47930
|
+
const config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47462
47931
|
if (!config2) {
|
|
47463
47932
|
requireConfig();
|
|
47464
47933
|
}
|
|
@@ -47483,7 +47952,7 @@ function createModelCommand() {
|
|
|
47483
47952
|
}
|
|
47484
47953
|
});
|
|
47485
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) => {
|
|
47486
|
-
let config2 = await loadConfig(
|
|
47955
|
+
let config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47487
47956
|
if (!config2) {
|
|
47488
47957
|
requireConfig();
|
|
47489
47958
|
}
|
|
@@ -47500,7 +47969,7 @@ function createModelCommand() {
|
|
|
47500
47969
|
} else {
|
|
47501
47970
|
config2 = assignProviderToAllBrains(config2, providerId);
|
|
47502
47971
|
}
|
|
47503
|
-
const outputPath2 = await saveConfig(config2,
|
|
47972
|
+
const outputPath2 = await saveConfig(config2, import_node_process25.default.cwd());
|
|
47504
47973
|
console.log(`Updated ${outputPath2}`);
|
|
47505
47974
|
console.log(options.role ? `Assigned ${providerId} to ${options.role}` : `Assigned ${providerId} to all roles`);
|
|
47506
47975
|
return;
|
|
@@ -47538,16 +48007,16 @@ function createModelCommand() {
|
|
|
47538
48007
|
model: modelId
|
|
47539
48008
|
});
|
|
47540
48009
|
}
|
|
47541
|
-
const outputPath = await saveConfig(config2,
|
|
48010
|
+
const outputPath = await saveConfig(config2, import_node_process25.default.cwd());
|
|
47542
48011
|
console.log(`Updated ${outputPath}`);
|
|
47543
48012
|
console.log(options.role ? `Assigned ${providerId}/${modelId} to ${options.role}` : `Assigned ${providerId}/${modelId} to all roles`);
|
|
47544
48013
|
});
|
|
47545
48014
|
command.command("check").description("Run health checks for configured providers.").action(async () => {
|
|
47546
|
-
const config2 = await loadConfig(
|
|
48015
|
+
const config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47547
48016
|
if (!config2) {
|
|
47548
48017
|
requireConfig();
|
|
47549
48018
|
}
|
|
47550
|
-
const registry2 = createDefaultBrainProviderRegistry(
|
|
48019
|
+
const registry2 = createDefaultBrainProviderRegistry(import_node_process25.default.cwd());
|
|
47551
48020
|
for (const provider of config2.providers) {
|
|
47552
48021
|
try {
|
|
47553
48022
|
const result = await registry2.healthCheck(provider);
|
|
@@ -47559,7 +48028,7 @@ function createModelCommand() {
|
|
|
47559
48028
|
}
|
|
47560
48029
|
});
|
|
47561
48030
|
command.action(async () => {
|
|
47562
|
-
const config2 = await loadConfig(
|
|
48031
|
+
const config2 = await loadConfig(import_node_process25.default.cwd());
|
|
47563
48032
|
if (!config2) {
|
|
47564
48033
|
requireConfig();
|
|
47565
48034
|
}
|
|
@@ -47569,7 +48038,7 @@ function createModelCommand() {
|
|
|
47569
48038
|
}
|
|
47570
48039
|
|
|
47571
48040
|
// src/commands/models.ts
|
|
47572
|
-
var
|
|
48041
|
+
var import_node_process26 = __toESM(require("node:process"), 1);
|
|
47573
48042
|
function parseInteger2(value) {
|
|
47574
48043
|
const parsed = Number.parseInt(value, 10);
|
|
47575
48044
|
if (!Number.isFinite(parsed)) {
|
|
@@ -47628,7 +48097,7 @@ async function fetchProviderModels(provider, options) {
|
|
|
47628
48097
|
models: cachedModels
|
|
47629
48098
|
};
|
|
47630
48099
|
}
|
|
47631
|
-
const registry2 = createDefaultBrainProviderRegistry(
|
|
48100
|
+
const registry2 = createDefaultBrainProviderRegistry(import_node_process26.default.cwd());
|
|
47632
48101
|
try {
|
|
47633
48102
|
const models = await registry2.listModels(provider, {
|
|
47634
48103
|
...options.search ? {
|
|
@@ -47655,7 +48124,7 @@ async function fetchProviderModels(provider, options) {
|
|
|
47655
48124
|
function createModelsCommand() {
|
|
47656
48125
|
const command = new Command("models").description("[legacy] Discover and select models from configured providers.");
|
|
47657
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) => {
|
|
47658
|
-
let config2 = await loadConfig(
|
|
48127
|
+
let config2 = await loadConfig(import_node_process26.default.cwd());
|
|
47659
48128
|
if (!config2) {
|
|
47660
48129
|
requireConfigMessage2();
|
|
47661
48130
|
}
|
|
@@ -47684,7 +48153,7 @@ function createModelsCommand() {
|
|
|
47684
48153
|
}
|
|
47685
48154
|
}
|
|
47686
48155
|
if (mutated) {
|
|
47687
|
-
await saveConfig(config2,
|
|
48156
|
+
await saveConfig(config2, import_node_process26.default.cwd());
|
|
47688
48157
|
}
|
|
47689
48158
|
if (options.json) {
|
|
47690
48159
|
console.log(renderJson(groups));
|
|
@@ -47701,7 +48170,7 @@ function createModelsCommand() {
|
|
|
47701
48170
|
}
|
|
47702
48171
|
});
|
|
47703
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) => {
|
|
47704
|
-
const config2 = await loadConfig(
|
|
48173
|
+
const config2 = await loadConfig(import_node_process26.default.cwd());
|
|
47705
48174
|
if (!config2) {
|
|
47706
48175
|
requireConfigMessage2();
|
|
47707
48176
|
}
|
|
@@ -47709,7 +48178,7 @@ function createModelsCommand() {
|
|
|
47709
48178
|
if (!provider) {
|
|
47710
48179
|
throw new Error(`Unknown provider "${providerId}".`);
|
|
47711
48180
|
}
|
|
47712
|
-
const registry2 = createDefaultBrainProviderRegistry(
|
|
48181
|
+
const registry2 = createDefaultBrainProviderRegistry(import_node_process26.default.cwd());
|
|
47713
48182
|
const models = await registry2.listModels(provider, {
|
|
47714
48183
|
...options.search ? {
|
|
47715
48184
|
search: options.search
|
|
@@ -47720,12 +48189,12 @@ function createModelsCommand() {
|
|
|
47720
48189
|
...provider,
|
|
47721
48190
|
models: Array.from(new Set(models.map((model) => model.id)))
|
|
47722
48191
|
});
|
|
47723
|
-
const outputPath = await saveConfig(nextConfig,
|
|
48192
|
+
const outputPath = await saveConfig(nextConfig, import_node_process26.default.cwd());
|
|
47724
48193
|
console.log(`Updated ${outputPath}`);
|
|
47725
48194
|
console.log(`Synced ${models.length} models for ${provider.id}`);
|
|
47726
48195
|
});
|
|
47727
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) => {
|
|
47728
|
-
let config2 = await loadConfig(
|
|
48197
|
+
let config2 = await loadConfig(import_node_process26.default.cwd());
|
|
47729
48198
|
if (!config2) {
|
|
47730
48199
|
requireConfigMessage2();
|
|
47731
48200
|
}
|
|
@@ -47735,7 +48204,7 @@ function createModelsCommand() {
|
|
|
47735
48204
|
}
|
|
47736
48205
|
if (!options.force) {
|
|
47737
48206
|
try {
|
|
47738
|
-
const registry2 = createDefaultBrainProviderRegistry(
|
|
48207
|
+
const registry2 = createDefaultBrainProviderRegistry(import_node_process26.default.cwd());
|
|
47739
48208
|
const models = await registry2.listModels(provider, {
|
|
47740
48209
|
search: model,
|
|
47741
48210
|
limit: 500
|
|
@@ -47777,7 +48246,7 @@ function createModelsCommand() {
|
|
|
47777
48246
|
} else {
|
|
47778
48247
|
config2 = assignProviderToAllBrains(config2, provider.id, model);
|
|
47779
48248
|
}
|
|
47780
|
-
const outputPath = await saveConfig(config2,
|
|
48249
|
+
const outputPath = await saveConfig(config2, import_node_process26.default.cwd());
|
|
47781
48250
|
console.log(`Updated ${outputPath}`);
|
|
47782
48251
|
console.log(`Selected ${provider.id}/${model}`);
|
|
47783
48252
|
if (options.role) {
|
|
@@ -47793,7 +48262,7 @@ function createModelsCommand() {
|
|
|
47793
48262
|
}
|
|
47794
48263
|
|
|
47795
48264
|
// src/commands/plan.ts
|
|
47796
|
-
var
|
|
48265
|
+
var import_node_process27 = __toESM(require("node:process"), 1);
|
|
47797
48266
|
function createPlanCommand() {
|
|
47798
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(
|
|
47799
48268
|
"--constraint <constraint>",
|
|
@@ -47801,7 +48270,7 @@ function createPlanCommand() {
|
|
|
47801
48270
|
(value, previous = []) => [...previous, value],
|
|
47802
48271
|
[]
|
|
47803
48272
|
).option("--json", "Print the plan as JSON", false).action(async (goal, options) => {
|
|
47804
|
-
const cwd =
|
|
48273
|
+
const cwd = import_node_process27.default.cwd();
|
|
47805
48274
|
const request = {
|
|
47806
48275
|
goal,
|
|
47807
48276
|
mode: "plan",
|
|
@@ -47858,8 +48327,8 @@ function createPlanCommand() {
|
|
|
47858
48327
|
}
|
|
47859
48328
|
|
|
47860
48329
|
// src/commands/permissions.ts
|
|
47861
|
-
var
|
|
47862
|
-
var
|
|
48330
|
+
var import_node_process28 = __toESM(require("node:process"), 1);
|
|
48331
|
+
var import_node_path31 = __toESM(require("node:path"), 1);
|
|
47863
48332
|
function getScope2(options) {
|
|
47864
48333
|
return options.scope === "user" ? "user" : "project";
|
|
47865
48334
|
}
|
|
@@ -47878,7 +48347,7 @@ function createPermissionsCommand() {
|
|
|
47878
48347
|
const command = new Command("permissions").description("Manage approval mode, sandbox mode, and trusted directories.");
|
|
47879
48348
|
command.command("status").description("Show permission settings.").option("--scope <scope>", "project or user", "project").action(async (options) => {
|
|
47880
48349
|
const scope = getScope2(options);
|
|
47881
|
-
const { direct, resolved } = await loadScopedConfig2(scope,
|
|
48350
|
+
const { direct, resolved } = await loadScopedConfig2(scope, import_node_process28.default.cwd());
|
|
47882
48351
|
console.log(`scope: ${scope}`);
|
|
47883
48352
|
console.log(`direct config: ${direct ? "present" : "missing"}`);
|
|
47884
48353
|
if (!resolved) {
|
|
@@ -47900,7 +48369,7 @@ function createPermissionsCommand() {
|
|
|
47900
48369
|
});
|
|
47901
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) => {
|
|
47902
48371
|
const scope = getScope2(options);
|
|
47903
|
-
const cwd =
|
|
48372
|
+
const cwd = import_node_process28.default.cwd();
|
|
47904
48373
|
const { direct, resolved } = await loadScopedConfig2(scope, cwd);
|
|
47905
48374
|
if (!resolved && !direct) {
|
|
47906
48375
|
throw new Error("No config found. Run `kimbho init` first.");
|
|
@@ -47920,13 +48389,13 @@ function createPermissionsCommand() {
|
|
|
47920
48389
|
});
|
|
47921
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) => {
|
|
47922
48391
|
const scope = getScope2(options);
|
|
47923
|
-
const cwd =
|
|
48392
|
+
const cwd = import_node_process28.default.cwd();
|
|
47924
48393
|
const { direct, resolved } = await loadScopedConfig2(scope, cwd);
|
|
47925
48394
|
if (!resolved && !direct) {
|
|
47926
48395
|
throw new Error("No config found. Run `kimbho init` first.");
|
|
47927
48396
|
}
|
|
47928
48397
|
const base = direct ?? resolved ?? createDefaultConfig();
|
|
47929
|
-
const normalizedPath =
|
|
48398
|
+
const normalizedPath = import_node_path31.default.resolve(cwd, trustedPath);
|
|
47930
48399
|
const outputPath = await saveScopedConfig2(scope, cwd, {
|
|
47931
48400
|
...base,
|
|
47932
48401
|
trustedDirectories: Array.from(/* @__PURE__ */ new Set([
|
|
@@ -47938,13 +48407,13 @@ function createPermissionsCommand() {
|
|
|
47938
48407
|
});
|
|
47939
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) => {
|
|
47940
48409
|
const scope = getScope2(options);
|
|
47941
|
-
const cwd =
|
|
48410
|
+
const cwd = import_node_process28.default.cwd();
|
|
47942
48411
|
const { direct, resolved } = await loadScopedConfig2(scope, cwd);
|
|
47943
48412
|
if (!resolved && !direct) {
|
|
47944
48413
|
throw new Error("No config found. Run `kimbho init` first.");
|
|
47945
48414
|
}
|
|
47946
48415
|
const base = direct ?? resolved ?? createDefaultConfig();
|
|
47947
|
-
const normalizedPath =
|
|
48416
|
+
const normalizedPath = import_node_path31.default.resolve(cwd, trustedPath);
|
|
47948
48417
|
const outputPath = await saveScopedConfig2(scope, cwd, {
|
|
47949
48418
|
...base,
|
|
47950
48419
|
trustedDirectories: base.trustedDirectories.filter((directory) => directory !== trustedPath && directory !== normalizedPath)
|
|
@@ -47955,14 +48424,14 @@ function createPermissionsCommand() {
|
|
|
47955
48424
|
}
|
|
47956
48425
|
|
|
47957
48426
|
// src/commands/providers.ts
|
|
47958
|
-
var
|
|
48427
|
+
var import_node_process29 = __toESM(require("node:process"), 1);
|
|
47959
48428
|
function requireConfigMessage3() {
|
|
47960
48429
|
throw new Error("No config found. Run `kimbho init` first.");
|
|
47961
48430
|
}
|
|
47962
48431
|
function createProvidersCommand() {
|
|
47963
48432
|
const command = new Command("providers").description("[legacy] Manage configured model providers and built-in templates.");
|
|
47964
48433
|
command.command("list").description("List configured providers.").option("--json", "Print providers as JSON", false).action(async (options) => {
|
|
47965
|
-
const config2 = await loadConfig(
|
|
48434
|
+
const config2 = await loadConfig(import_node_process29.default.cwd());
|
|
47966
48435
|
if (!config2) {
|
|
47967
48436
|
requireConfigMessage3();
|
|
47968
48437
|
}
|
|
@@ -48003,7 +48472,7 @@ function createProvidersCommand() {
|
|
|
48003
48472
|
(value, previous = []) => [...previous, value],
|
|
48004
48473
|
[]
|
|
48005
48474
|
).option("--module-path <path>", "Module path for a custom provider driver").action(async (options) => {
|
|
48006
|
-
const config2 = await loadConfig(
|
|
48475
|
+
const config2 = await loadConfig(import_node_process29.default.cwd());
|
|
48007
48476
|
if (!config2) {
|
|
48008
48477
|
requireConfigMessage3();
|
|
48009
48478
|
}
|
|
@@ -48037,16 +48506,16 @@ function createProvidersCommand() {
|
|
|
48037
48506
|
} : {}
|
|
48038
48507
|
});
|
|
48039
48508
|
const nextConfig = upsertProvider(config2, provider);
|
|
48040
|
-
const outputPath = await saveConfig(nextConfig,
|
|
48509
|
+
const outputPath = await saveConfig(nextConfig, import_node_process29.default.cwd());
|
|
48041
48510
|
console.log(`Updated ${outputPath}`);
|
|
48042
48511
|
console.log(`Provider ${provider.id} -> ${provider.driver}`);
|
|
48043
48512
|
});
|
|
48044
48513
|
command.command("check").description("Run health checks for the configured providers.").action(async () => {
|
|
48045
|
-
const config2 = await loadConfig(
|
|
48514
|
+
const config2 = await loadConfig(import_node_process29.default.cwd());
|
|
48046
48515
|
if (!config2) {
|
|
48047
48516
|
requireConfigMessage3();
|
|
48048
48517
|
}
|
|
48049
|
-
const registry2 = createDefaultBrainProviderRegistry(
|
|
48518
|
+
const registry2 = createDefaultBrainProviderRegistry(import_node_process29.default.cwd());
|
|
48050
48519
|
for (const provider of config2.providers) {
|
|
48051
48520
|
try {
|
|
48052
48521
|
const result = await registry2.healthCheck(provider);
|
|
@@ -48061,10 +48530,10 @@ function createProvidersCommand() {
|
|
|
48061
48530
|
}
|
|
48062
48531
|
|
|
48063
48532
|
// src/commands/review.ts
|
|
48064
|
-
var
|
|
48533
|
+
var import_node_process30 = __toESM(require("node:process"), 1);
|
|
48065
48534
|
function createReviewCommand() {
|
|
48066
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) => {
|
|
48067
|
-
const cwd =
|
|
48536
|
+
const cwd = import_node_process30.default.cwd();
|
|
48068
48537
|
const payload = await reviewWorkspace(cwd, {
|
|
48069
48538
|
patchPath: options.patch
|
|
48070
48539
|
});
|
|
@@ -48097,8 +48566,8 @@ function createReviewCommand() {
|
|
|
48097
48566
|
}
|
|
48098
48567
|
|
|
48099
48568
|
// src/commands/resume.ts
|
|
48100
|
-
var
|
|
48101
|
-
function
|
|
48569
|
+
var import_node_process31 = __toESM(require("node:process"), 1);
|
|
48570
|
+
function parseCount5(value) {
|
|
48102
48571
|
const parsed = Number(value);
|
|
48103
48572
|
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
48104
48573
|
throw new Error(`Expected a positive integer, received "${value}".`);
|
|
@@ -48106,8 +48575,8 @@ function parseCount4(value) {
|
|
|
48106
48575
|
return parsed;
|
|
48107
48576
|
}
|
|
48108
48577
|
function createResumeCommand() {
|
|
48109
|
-
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",
|
|
48110
|
-
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();
|
|
48111
48580
|
const effectiveSearch = options.pr?.trim() || options.search?.trim();
|
|
48112
48581
|
const firstSearchMatch = effectiveSearch ? (await searchSessions(effectiveSearch, cwd, 1)).at(0) ?? null : null;
|
|
48113
48582
|
if (options.list) {
|
|
@@ -48132,12 +48601,12 @@ function createResumeCommand() {
|
|
|
48132
48601
|
const session = effectiveSearch && !sessionId && !options.last ? firstSearchMatch ? await loadSessionById(firstSearchMatch.id, cwd) : null : options.last || !sessionId ? await loadLatestSession(cwd) : await loadSessionById(sessionId, cwd);
|
|
48133
48602
|
if (!session) {
|
|
48134
48603
|
console.error("No saved session found. Run `kimbho run` first.");
|
|
48135
|
-
|
|
48604
|
+
import_node_process31.default.exitCode = 1;
|
|
48136
48605
|
return;
|
|
48137
48606
|
}
|
|
48138
48607
|
if (options.approve && options.deny) {
|
|
48139
48608
|
console.error("Pass only one of --approve or --deny.");
|
|
48140
|
-
|
|
48609
|
+
import_node_process31.default.exitCode = 1;
|
|
48141
48610
|
return;
|
|
48142
48611
|
}
|
|
48143
48612
|
const snapshot = options.execute ? await new ExecutionOrchestrator().continueSession(session, {
|
|
@@ -48184,7 +48653,7 @@ function createResumeCommand() {
|
|
|
48184
48653
|
}
|
|
48185
48654
|
|
|
48186
48655
|
// src/commands/run.ts
|
|
48187
|
-
var
|
|
48656
|
+
var import_node_process32 = __toESM(require("node:process"), 1);
|
|
48188
48657
|
|
|
48189
48658
|
// src/pr-link.ts
|
|
48190
48659
|
function inferProvider(hostname2) {
|
|
@@ -48227,7 +48696,7 @@ function parsePrLinkFromUrl(value, overrides = {}) {
|
|
|
48227
48696
|
}
|
|
48228
48697
|
|
|
48229
48698
|
// src/commands/run.ts
|
|
48230
|
-
function
|
|
48699
|
+
function parseCount6(value) {
|
|
48231
48700
|
const parsed = Number(value);
|
|
48232
48701
|
if (!Number.isInteger(parsed) || parsed <= 0) {
|
|
48233
48702
|
throw new Error(`Expected a positive integer, received "${value}".`);
|
|
@@ -48240,8 +48709,8 @@ function createRunCommand() {
|
|
|
48240
48709
|
"Explicit execution constraint; can be provided multiple times",
|
|
48241
48710
|
(value, previous = []) => [...previous, value],
|
|
48242
48711
|
[]
|
|
48243
|
-
).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",
|
|
48244
|
-
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();
|
|
48245
48714
|
const orchestrator = new ExecutionOrchestrator();
|
|
48246
48715
|
const agentSelection = await resolveAgentSelection(cwd, {
|
|
48247
48716
|
agent: options.agent,
|
|
@@ -48253,7 +48722,7 @@ function createRunCommand() {
|
|
|
48253
48722
|
let planResult = null;
|
|
48254
48723
|
if (!plan && !goal) {
|
|
48255
48724
|
console.error("No saved plan found. Pass a goal or run `kimbho plan` first.");
|
|
48256
|
-
|
|
48725
|
+
import_node_process32.default.exitCode = 1;
|
|
48257
48726
|
return;
|
|
48258
48727
|
}
|
|
48259
48728
|
if (goal) {
|
|
@@ -48358,7 +48827,7 @@ function createRunCommand() {
|
|
|
48358
48827
|
}
|
|
48359
48828
|
|
|
48360
48829
|
// src/commands/skills.ts
|
|
48361
|
-
var
|
|
48830
|
+
var import_node_process33 = __toESM(require("node:process"), 1);
|
|
48362
48831
|
function renderMetadataBlock(metadata) {
|
|
48363
48832
|
return [
|
|
48364
48833
|
` userInvocable: ${String(metadata.userInvocable)}`,
|
|
@@ -48376,7 +48845,7 @@ function renderOriginLabel(definition) {
|
|
|
48376
48845
|
function createSkillsCommand() {
|
|
48377
48846
|
const command = new Command("skills").description("Inspect Kimbho-native skill packs and command packs, with .claude fallback compatibility.");
|
|
48378
48847
|
command.action(async () => {
|
|
48379
|
-
const skills = await listClaudeSkills(
|
|
48848
|
+
const skills = await listClaudeSkills(import_node_process33.default.cwd());
|
|
48380
48849
|
if (skills.length === 0) {
|
|
48381
48850
|
console.log("No skill packs discovered.");
|
|
48382
48851
|
return;
|
|
@@ -48387,7 +48856,7 @@ function createSkillsCommand() {
|
|
|
48387
48856
|
}
|
|
48388
48857
|
});
|
|
48389
48858
|
command.command("list").description("List discovered skill packs from .kimbho/skills and .claude/skills.").action(async () => {
|
|
48390
|
-
const skills = await listClaudeSkills(
|
|
48859
|
+
const skills = await listClaudeSkills(import_node_process33.default.cwd());
|
|
48391
48860
|
if (skills.length === 0) {
|
|
48392
48861
|
console.log("No skill packs discovered.");
|
|
48393
48862
|
return;
|
|
@@ -48398,7 +48867,7 @@ function createSkillsCommand() {
|
|
|
48398
48867
|
}
|
|
48399
48868
|
});
|
|
48400
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) => {
|
|
48401
|
-
const commands = await listClaudeCommands(
|
|
48870
|
+
const commands = await listClaudeCommands(import_node_process33.default.cwd(), {
|
|
48402
48871
|
includeHidden: Boolean(options.all)
|
|
48403
48872
|
});
|
|
48404
48873
|
if (commands.length === 0) {
|
|
@@ -48411,7 +48880,7 @@ function createSkillsCommand() {
|
|
|
48411
48880
|
}
|
|
48412
48881
|
});
|
|
48413
48882
|
command.command("inspect").description("Inspect one skill pack entry.").argument("<id>", "Skill id").action(async (id) => {
|
|
48414
|
-
const skill = await loadClaudeSkillById(
|
|
48883
|
+
const skill = await loadClaudeSkillById(import_node_process33.default.cwd(), id);
|
|
48415
48884
|
if (!skill) {
|
|
48416
48885
|
throw new Error(`Unknown skill "${id}".`);
|
|
48417
48886
|
}
|
|
@@ -48424,7 +48893,7 @@ function createSkillsCommand() {
|
|
|
48424
48893
|
}
|
|
48425
48894
|
});
|
|
48426
48895
|
command.command("inspect-command").description("Inspect one command pack entry.").argument("<name>", "Command name").action(async (name) => {
|
|
48427
|
-
const definition = await loadClaudeCommandByName(
|
|
48896
|
+
const definition = await loadClaudeCommandByName(import_node_process33.default.cwd(), name, {
|
|
48428
48897
|
includeHidden: true
|
|
48429
48898
|
});
|
|
48430
48899
|
if (!definition) {
|
|
@@ -48439,7 +48908,7 @@ function createSkillsCommand() {
|
|
|
48439
48908
|
}
|
|
48440
48909
|
});
|
|
48441
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 = []) => {
|
|
48442
|
-
const invocation = await resolveClaudeCommandInvocation(
|
|
48911
|
+
const invocation = await resolveClaudeCommandInvocation(import_node_process33.default.cwd(), [
|
|
48443
48912
|
name,
|
|
48444
48913
|
...args
|
|
48445
48914
|
]);
|
|
@@ -48453,8 +48922,8 @@ function createSkillsCommand() {
|
|
|
48453
48922
|
|
|
48454
48923
|
// src/commands/worktree.ts
|
|
48455
48924
|
var import_promises26 = require("node:fs/promises");
|
|
48456
|
-
var
|
|
48457
|
-
var
|
|
48925
|
+
var import_node_path32 = __toESM(require("node:path"), 1);
|
|
48926
|
+
var import_node_process34 = __toESM(require("node:process"), 1);
|
|
48458
48927
|
var import_node_child_process12 = require("node:child_process");
|
|
48459
48928
|
function sanitizeName3(value) {
|
|
48460
48929
|
return value.replace(/[^a-zA-Z0-9._-]+/g, "-").slice(0, 80);
|
|
@@ -48463,10 +48932,10 @@ function storedWorktreeName(name) {
|
|
|
48463
48932
|
return sanitizeName3(`manual-${name}`);
|
|
48464
48933
|
}
|
|
48465
48934
|
function resolveStoredWorktreePath(cwd, name) {
|
|
48466
|
-
return
|
|
48935
|
+
return import_node_path32.default.join(resolveKimbhoDir(cwd), "worktrees", storedWorktreeName(name));
|
|
48467
48936
|
}
|
|
48468
48937
|
function resolveStoredPatchPath(cwd, name) {
|
|
48469
|
-
return
|
|
48938
|
+
return import_node_path32.default.join(resolveKimbhoDir(cwd), "logs", `${storedWorktreeName(name)}.patch`);
|
|
48470
48939
|
}
|
|
48471
48940
|
async function resolveStoredWorktree(cwd, name) {
|
|
48472
48941
|
const worktreePath = resolveStoredWorktreePath(cwd, name);
|
|
@@ -48492,14 +48961,14 @@ function gitRun(cwd, args) {
|
|
|
48492
48961
|
function createWorktreeCommand() {
|
|
48493
48962
|
const command = new Command("worktree").description("Manage user-visible isolated worktrees and apply their diffs back.");
|
|
48494
48963
|
command.command("list").description("List Kimbho-managed worktrees.").option("--json", "Print the worktree payload as JSON", false).action(async (options) => {
|
|
48495
|
-
const dir =
|
|
48964
|
+
const dir = import_node_path32.default.join(resolveKimbhoDir(import_node_process34.default.cwd()), "worktrees");
|
|
48496
48965
|
const entries = await (0, import_promises26.readdir)(dir, {
|
|
48497
48966
|
withFileTypes: true
|
|
48498
48967
|
}).catch(() => []);
|
|
48499
48968
|
const worktrees = entries.filter((entry) => entry.isDirectory()).map((entry) => ({
|
|
48500
48969
|
id: entry.name.replace(/^manual-/, ""),
|
|
48501
|
-
worktreePath:
|
|
48502
|
-
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`)
|
|
48503
48972
|
}));
|
|
48504
48973
|
if (options.json) {
|
|
48505
48974
|
console.log(JSON.stringify(worktrees, null, 2));
|
|
@@ -48516,7 +48985,7 @@ function createWorktreeCommand() {
|
|
|
48516
48985
|
}
|
|
48517
48986
|
});
|
|
48518
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) => {
|
|
48519
|
-
const worktree = await createIsolatedWorktree(
|
|
48988
|
+
const worktree = await createIsolatedWorktree(import_node_process34.default.cwd(), "manual", name);
|
|
48520
48989
|
if (!worktree) {
|
|
48521
48990
|
throw new Error("This workspace is not a git repo with a valid HEAD. Worktrees require git history.");
|
|
48522
48991
|
}
|
|
@@ -48528,19 +48997,19 @@ function createWorktreeCommand() {
|
|
|
48528
48997
|
console.log(`Patch artifact: ${worktree.patchArtifactPath}`);
|
|
48529
48998
|
});
|
|
48530
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) => {
|
|
48531
|
-
const worktree = await resolveStoredWorktree(
|
|
49000
|
+
const worktree = await resolveStoredWorktree(import_node_process34.default.cwd(), name);
|
|
48532
49001
|
const args = options.stat ? ["diff", "--stat", "HEAD"] : ["diff", "--binary", "--full-index", "--no-ext-diff", "--stat", "--patch", "HEAD"];
|
|
48533
49002
|
const result = gitRun(worktree.worktreePath, args);
|
|
48534
49003
|
if (!result.ok) {
|
|
48535
49004
|
console.error(result.detail);
|
|
48536
|
-
|
|
49005
|
+
import_node_process34.default.exitCode = 1;
|
|
48537
49006
|
return;
|
|
48538
49007
|
}
|
|
48539
49008
|
console.log(result.stdout.trim() || "No diff.");
|
|
48540
49009
|
});
|
|
48541
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) => {
|
|
48542
|
-
const worktree = await resolveStoredWorktree(
|
|
48543
|
-
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, [], []);
|
|
48544
49013
|
if (options.json) {
|
|
48545
49014
|
console.log(JSON.stringify(result, null, 2));
|
|
48546
49015
|
return;
|
|
@@ -48552,11 +49021,11 @@ function createWorktreeCommand() {
|
|
|
48552
49021
|
console.log(`artifact: ${artifact}`);
|
|
48553
49022
|
}
|
|
48554
49023
|
if (result.integrationFailed) {
|
|
48555
|
-
|
|
49024
|
+
import_node_process34.default.exitCode = 1;
|
|
48556
49025
|
}
|
|
48557
49026
|
});
|
|
48558
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) => {
|
|
48559
|
-
const cwd =
|
|
49028
|
+
const cwd = import_node_process34.default.cwd();
|
|
48560
49029
|
const worktreePath = resolveStoredWorktreePath(cwd, name);
|
|
48561
49030
|
const removal = gitRun(cwd, [
|
|
48562
49031
|
"worktree",
|
|
@@ -48586,20 +49055,6 @@ function createWorktreeCommand() {
|
|
|
48586
49055
|
return command;
|
|
48587
49056
|
}
|
|
48588
49057
|
|
|
48589
|
-
// src/commands/placeholders.ts
|
|
48590
|
-
function createPlaceholder(name, description, milestone) {
|
|
48591
|
-
return new Command(name).description(description).action(() => {
|
|
48592
|
-
console.log(`${name} is planned for ${milestone}.`);
|
|
48593
|
-
});
|
|
48594
|
-
}
|
|
48595
|
-
function createFixCommand() {
|
|
48596
|
-
return createPlaceholder(
|
|
48597
|
-
"fix",
|
|
48598
|
-
"Diagnose and repair a failing repository state.",
|
|
48599
|
-
"Milestone 4: Executor Loop"
|
|
48600
|
-
);
|
|
48601
|
-
}
|
|
48602
|
-
|
|
48603
49058
|
// src/program.ts
|
|
48604
49059
|
var MODELS_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
48605
49060
|
"help",
|
|
@@ -48726,10 +49181,10 @@ function createProgram(onOpenShell) {
|
|
|
48726
49181
|
}
|
|
48727
49182
|
|
|
48728
49183
|
// src/runtime-flags.ts
|
|
48729
|
-
var
|
|
48730
|
-
var
|
|
49184
|
+
var import_node_path33 = __toESM(require("node:path"), 1);
|
|
49185
|
+
var import_node_process35 = __toESM(require("node:process"), 1);
|
|
48731
49186
|
function parseJsonEnv2(name, fallback) {
|
|
48732
|
-
const raw =
|
|
49187
|
+
const raw = import_node_process35.default.env[name];
|
|
48733
49188
|
if (!raw || raw.trim().length === 0) {
|
|
48734
49189
|
return fallback;
|
|
48735
49190
|
}
|
|
@@ -48813,7 +49268,7 @@ function readOptionValue(tokens, index, label) {
|
|
|
48813
49268
|
return value;
|
|
48814
49269
|
}
|
|
48815
49270
|
function applyRuntimeFlags(tokens) {
|
|
48816
|
-
const initialCwd =
|
|
49271
|
+
const initialCwd = import_node_process35.default.cwd();
|
|
48817
49272
|
const remaining = [];
|
|
48818
49273
|
const overrides = parseJsonEnv2(
|
|
48819
49274
|
KIMBHO_RUNTIME_OVERRIDES_ENV,
|
|
@@ -48824,7 +49279,7 @@ function applyRuntimeFlags(tokens) {
|
|
|
48824
49279
|
[]
|
|
48825
49280
|
);
|
|
48826
49281
|
let nextCwd = null;
|
|
48827
|
-
let selectedProfile =
|
|
49282
|
+
let selectedProfile = import_node_process35.default.env[KIMBHO_RUNTIME_PROFILE_ENV] ?? null;
|
|
48828
49283
|
let forceExec = false;
|
|
48829
49284
|
let index = 0;
|
|
48830
49285
|
while (index < tokens.length) {
|
|
@@ -48922,14 +49377,14 @@ function applyRuntimeFlags(tokens) {
|
|
|
48922
49377
|
break;
|
|
48923
49378
|
}
|
|
48924
49379
|
if (nextCwd) {
|
|
48925
|
-
|
|
49380
|
+
import_node_process35.default.chdir(import_node_path33.default.resolve(initialCwd, nextCwd));
|
|
48926
49381
|
}
|
|
48927
49382
|
if (selectedProfile) {
|
|
48928
|
-
|
|
49383
|
+
import_node_process35.default.env[KIMBHO_RUNTIME_PROFILE_ENV] = selectedProfile;
|
|
48929
49384
|
}
|
|
48930
|
-
|
|
48931
|
-
|
|
48932
|
-
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))
|
|
48933
49388
|
);
|
|
48934
49389
|
return {
|
|
48935
49390
|
tokens: remaining,
|
|
@@ -48941,8 +49396,8 @@ function applyRuntimeFlags(tokens) {
|
|
|
48941
49396
|
var import_node_child_process13 = require("node:child_process");
|
|
48942
49397
|
var import_node_readline2 = require("node:readline");
|
|
48943
49398
|
var import_promises27 = require("node:readline/promises");
|
|
48944
|
-
var
|
|
48945
|
-
var
|
|
49399
|
+
var import_node_path34 = __toESM(require("node:path"), 1);
|
|
49400
|
+
var import_node_process36 = __toESM(require("node:process"), 1);
|
|
48946
49401
|
|
|
48947
49402
|
// src/agent-management.ts
|
|
48948
49403
|
async function renderCustomAgents(cwd) {
|
|
@@ -49116,7 +49571,7 @@ function renderShimmeringLabel(label, frameIndex) {
|
|
|
49116
49571
|
}).join("");
|
|
49117
49572
|
}
|
|
49118
49573
|
function readRuntimeOverrideEntries() {
|
|
49119
|
-
const raw =
|
|
49574
|
+
const raw = import_node_process36.default.env[KIMBHO_RUNTIME_OVERRIDES_ENV];
|
|
49120
49575
|
if (!raw || raw.trim().length === 0) {
|
|
49121
49576
|
return [];
|
|
49122
49577
|
}
|
|
@@ -49134,7 +49589,7 @@ function readRuntimeOverrideEntries() {
|
|
|
49134
49589
|
}
|
|
49135
49590
|
}
|
|
49136
49591
|
function readAdditionalDirectories2() {
|
|
49137
|
-
const raw =
|
|
49592
|
+
const raw = import_node_process36.default.env[KIMBHO_RUNTIME_ADDITIONAL_DIRS_ENV];
|
|
49138
49593
|
if (!raw || raw.trim().length === 0) {
|
|
49139
49594
|
return [];
|
|
49140
49595
|
}
|
|
@@ -49170,17 +49625,17 @@ function syncShellRuntimeOverrides(runtime) {
|
|
|
49170
49625
|
] : []
|
|
49171
49626
|
];
|
|
49172
49627
|
if (merged.length === 0) {
|
|
49173
|
-
delete
|
|
49628
|
+
delete import_node_process36.default.env[KIMBHO_RUNTIME_OVERRIDES_ENV];
|
|
49174
49629
|
return;
|
|
49175
49630
|
}
|
|
49176
|
-
|
|
49631
|
+
import_node_process36.default.env[KIMBHO_RUNTIME_OVERRIDES_ENV] = JSON.stringify(merged);
|
|
49177
49632
|
}
|
|
49178
49633
|
function syncShellAdditionalDirectories(runtime) {
|
|
49179
49634
|
if (runtime.additionalDirectories.length === 0) {
|
|
49180
|
-
delete
|
|
49635
|
+
delete import_node_process36.default.env[KIMBHO_RUNTIME_ADDITIONAL_DIRS_ENV];
|
|
49181
49636
|
return;
|
|
49182
49637
|
}
|
|
49183
|
-
|
|
49638
|
+
import_node_process36.default.env[KIMBHO_RUNTIME_ADDITIONAL_DIRS_ENV] = JSON.stringify(runtime.additionalDirectories);
|
|
49184
49639
|
}
|
|
49185
49640
|
function resolveRuntimeOverrideApprovalMode(runtime) {
|
|
49186
49641
|
if (runtime.sessionApprovalModeOverride) {
|
|
@@ -49362,7 +49817,7 @@ var ShellActivityIndicator = class {
|
|
|
49362
49817
|
this.label = label;
|
|
49363
49818
|
}
|
|
49364
49819
|
start() {
|
|
49365
|
-
if (!
|
|
49820
|
+
if (!import_node_process36.default.stdout.isTTY || this.interval) {
|
|
49366
49821
|
return;
|
|
49367
49822
|
}
|
|
49368
49823
|
this.activeLine = true;
|
|
@@ -49383,13 +49838,13 @@ var ShellActivityIndicator = class {
|
|
|
49383
49838
|
}
|
|
49384
49839
|
}
|
|
49385
49840
|
suspend() {
|
|
49386
|
-
if (!
|
|
49841
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49387
49842
|
return;
|
|
49388
49843
|
}
|
|
49389
49844
|
this.clear();
|
|
49390
49845
|
}
|
|
49391
49846
|
resume() {
|
|
49392
|
-
if (!
|
|
49847
|
+
if (!import_node_process36.default.stdout.isTTY || !this.interval) {
|
|
49393
49848
|
return;
|
|
49394
49849
|
}
|
|
49395
49850
|
this.render();
|
|
@@ -49403,7 +49858,7 @@ var ShellActivityIndicator = class {
|
|
|
49403
49858
|
this.activeLine = false;
|
|
49404
49859
|
}
|
|
49405
49860
|
render() {
|
|
49406
|
-
if (!
|
|
49861
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49407
49862
|
return;
|
|
49408
49863
|
}
|
|
49409
49864
|
const frame = color(AMBER, SPINNER_FRAMES[this.animationTick % SPINNER_FRAMES.length]);
|
|
@@ -49411,15 +49866,15 @@ var ShellActivityIndicator = class {
|
|
|
49411
49866
|
const dots = color(DIM, ELLIPSIS_FRAMES[this.animationTick % ELLIPSIS_FRAMES.length]);
|
|
49412
49867
|
const raw = `${frame} ${status}${dots}`;
|
|
49413
49868
|
this.clear();
|
|
49414
|
-
(0, import_node_readline2.cursorTo)(
|
|
49415
|
-
|
|
49869
|
+
(0, import_node_readline2.cursorTo)(import_node_process36.default.stdout, 0);
|
|
49870
|
+
import_node_process36.default.stdout.write(raw);
|
|
49416
49871
|
}
|
|
49417
49872
|
clear() {
|
|
49418
|
-
if (!
|
|
49873
|
+
if (!import_node_process36.default.stdout.isTTY || !this.activeLine) {
|
|
49419
49874
|
return;
|
|
49420
49875
|
}
|
|
49421
|
-
(0, import_node_readline2.cursorTo)(
|
|
49422
|
-
(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);
|
|
49423
49878
|
}
|
|
49424
49879
|
};
|
|
49425
49880
|
var ShellExecutionTui = class {
|
|
@@ -49438,12 +49893,12 @@ var ShellExecutionTui = class {
|
|
|
49438
49893
|
this.render();
|
|
49439
49894
|
};
|
|
49440
49895
|
start() {
|
|
49441
|
-
if (!
|
|
49896
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49442
49897
|
return;
|
|
49443
49898
|
}
|
|
49444
49899
|
if (this.ownsScreen) {
|
|
49445
|
-
|
|
49446
|
-
|
|
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);
|
|
49447
49902
|
}
|
|
49448
49903
|
this.render();
|
|
49449
49904
|
this.interval = setInterval(() => {
|
|
@@ -49457,12 +49912,12 @@ var ShellExecutionTui = class {
|
|
|
49457
49912
|
clearInterval(this.interval);
|
|
49458
49913
|
this.interval = null;
|
|
49459
49914
|
}
|
|
49460
|
-
if (!
|
|
49915
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49461
49916
|
return;
|
|
49462
49917
|
}
|
|
49463
49918
|
if (this.ownsScreen) {
|
|
49464
|
-
|
|
49465
|
-
|
|
49919
|
+
import_node_process36.default.stdout.off("resize", this.handleResize);
|
|
49920
|
+
import_node_process36.default.stdout.write(`${SHOW_CURSOR}${ALT_SCREEN_EXIT}`);
|
|
49466
49921
|
}
|
|
49467
49922
|
}
|
|
49468
49923
|
updateActivity(label) {
|
|
@@ -49483,11 +49938,11 @@ var ShellExecutionTui = class {
|
|
|
49483
49938
|
this.render();
|
|
49484
49939
|
}
|
|
49485
49940
|
render() {
|
|
49486
|
-
if (!
|
|
49941
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49487
49942
|
return;
|
|
49488
49943
|
}
|
|
49489
|
-
const columns = Math.max(
|
|
49490
|
-
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);
|
|
49491
49946
|
const headerLines = [
|
|
49492
49947
|
color(BOLD, "Kimbho Execution"),
|
|
49493
49948
|
color(DIM, `session ${shortenMiddle(this.board.sessionId, Math.max(20, columns - 12))}`),
|
|
@@ -49498,6 +49953,10 @@ var ShellExecutionTui = class {
|
|
|
49498
49953
|
const footerLines = [
|
|
49499
49954
|
"",
|
|
49500
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
|
+
] : [],
|
|
49501
49960
|
color(DIM, "Ctrl+C pauses the run and returns to the shell. A concise summary prints after the run exits.")
|
|
49502
49961
|
];
|
|
49503
49962
|
const chromeLines = headerLines.length + boardLines.length + footerLines.length + 1;
|
|
@@ -49515,7 +49974,7 @@ var ShellExecutionTui = class {
|
|
|
49515
49974
|
while (paddedLines.length < rows) {
|
|
49516
49975
|
paddedLines.push("");
|
|
49517
49976
|
}
|
|
49518
|
-
|
|
49977
|
+
import_node_process36.default.stdout.write(`${CLEAR_SCREEN}${HOME_CURSOR}${paddedLines.join("\n")}`);
|
|
49519
49978
|
}
|
|
49520
49979
|
};
|
|
49521
49980
|
function renderExecutionTelemetry(telemetry, startedAt) {
|
|
@@ -49652,6 +50111,8 @@ function renderBanner() {
|
|
|
49652
50111
|
}
|
|
49653
50112
|
async function getShellSessionState(cwd, focusRole, runtime) {
|
|
49654
50113
|
const config2 = await loadConfig(cwd);
|
|
50114
|
+
const latestSession = await loadLatestSession(cwd).catch(() => null);
|
|
50115
|
+
const pendingApprovals = latestSession?.pendingApprovals ?? [];
|
|
49655
50116
|
if (!config2) {
|
|
49656
50117
|
return {
|
|
49657
50118
|
focusRole,
|
|
@@ -49663,7 +50124,8 @@ async function getShellSessionState(cwd, focusRole, runtime) {
|
|
|
49663
50124
|
approvalMode: "manual",
|
|
49664
50125
|
sandboxMode: "workspace-write",
|
|
49665
50126
|
stackPreset: "next-prisma-postgres",
|
|
49666
|
-
configured: false
|
|
50127
|
+
configured: false,
|
|
50128
|
+
pendingApprovals
|
|
49667
50129
|
};
|
|
49668
50130
|
}
|
|
49669
50131
|
const focusSettings = config2.brains[focusRole];
|
|
@@ -49678,7 +50140,8 @@ async function getShellSessionState(cwd, focusRole, runtime) {
|
|
|
49678
50140
|
approvalMode: runtime?.sessionApprovalModeOverride ? `${runtime.sessionApprovalModeOverride} (session override)` : config2.approvalMode,
|
|
49679
50141
|
sandboxMode: runtime?.sessionSandboxModeOverride ? `${runtime.sessionSandboxModeOverride} (session override)` : config2.sandboxMode,
|
|
49680
50142
|
stackPreset: config2.stackPresets[0] ?? "none",
|
|
49681
|
-
configured: true
|
|
50143
|
+
configured: true,
|
|
50144
|
+
pendingApprovals
|
|
49682
50145
|
};
|
|
49683
50146
|
}
|
|
49684
50147
|
function renderCardLine(label, value) {
|
|
@@ -49767,8 +50230,8 @@ function renderHelp() {
|
|
|
49767
50230
|
"/permissions sandbox <mode> Set read-only, workspace-write, or full.",
|
|
49768
50231
|
"/permissions trust <path> Add a trusted directory.",
|
|
49769
50232
|
"/permissions untrust <path> Remove a trusted directory.",
|
|
49770
|
-
"/approve [id] Approve a pending risky action and continue.",
|
|
49771
|
-
"/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.",
|
|
49772
50235
|
"/deny [id] Deny a pending risky action.",
|
|
49773
50236
|
"",
|
|
49774
50237
|
`${color(BOLD, "Memory")}`,
|
|
@@ -49830,6 +50293,10 @@ function renderStartupCard(cwd, state) {
|
|
|
49830
50293
|
renderCardLine("approval", state.approvalMode),
|
|
49831
50294
|
renderCardLine("sandbox", state.sandboxMode),
|
|
49832
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
|
+
] : [],
|
|
49833
50300
|
renderCardLine("shortcuts", "/ask /run /model /permissions /memory /mcp /quit")
|
|
49834
50301
|
];
|
|
49835
50302
|
if (!state.configured) {
|
|
@@ -49871,9 +50338,83 @@ function renderShellRuntimeOverview(runtime) {
|
|
|
49871
50338
|
return lines;
|
|
49872
50339
|
}
|
|
49873
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
|
+
}
|
|
49874
50344
|
const model = state.focusModel === "not set" ? "unconfigured" : shortenMiddle(state.focusModel, 18);
|
|
49875
50345
|
return `${color(AMBER, "kimbho")} ${color(DIM, `[${state.focusRole}:${model}]`)} > `;
|
|
49876
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
|
+
}
|
|
49877
50418
|
function printHeader(cwd, state) {
|
|
49878
50419
|
console.log(renderBanner());
|
|
49879
50420
|
console.log(color(DIM, "Terminal-native coding agent"));
|
|
@@ -49897,8 +50438,8 @@ function appendShellLog(runtime, value) {
|
|
|
49897
50438
|
}
|
|
49898
50439
|
}
|
|
49899
50440
|
function renderShellDashboard(cwd, state, runtime) {
|
|
49900
|
-
const columns = Math.max(
|
|
49901
|
-
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);
|
|
49902
50443
|
const lines = [
|
|
49903
50444
|
`${color(BOLD, "Kimbho CLI")} ${color(DIM, `(v${KIMBHO_VERSION})`)}`,
|
|
49904
50445
|
color(DIM, `focus ${state.focusRole} | model ${shortenMiddle(state.focusModel, 28)} | provider ${state.providerId}`),
|
|
@@ -49921,6 +50462,16 @@ function renderShellDashboard(cwd, state, runtime) {
|
|
|
49921
50462
|
lines.push(`\u2022 ${shortenMiddle(runtime.pendingHookElicitation.question, Math.max(24, columns - 10))}`);
|
|
49922
50463
|
lines.push(color(DIM, "next: /answer <text> or /skip"));
|
|
49923
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
|
+
}
|
|
49924
50475
|
if (runtime.activeExecution) {
|
|
49925
50476
|
lines.push("");
|
|
49926
50477
|
lines.push(color(BOLD, "Active Execution"));
|
|
@@ -49942,9 +50493,10 @@ function renderShellDashboard(cwd, state, runtime) {
|
|
|
49942
50493
|
}
|
|
49943
50494
|
lines.push("");
|
|
49944
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";
|
|
49945
50497
|
const footerLines = [
|
|
49946
50498
|
"",
|
|
49947
|
-
color(DIM,
|
|
50499
|
+
color(DIM, footerActionLabel)
|
|
49948
50500
|
];
|
|
49949
50501
|
const activityBudget = Math.max(6, rows - lines.length - footerLines.length - 2);
|
|
49950
50502
|
const activity = runtime.shellLog.slice(-activityBudget);
|
|
@@ -49963,23 +50515,54 @@ function renderShellDashboard(cwd, state, runtime) {
|
|
|
49963
50515
|
return `${CLEAR_SCREEN}${HOME_CURSOR}${frame.join("\n")}
|
|
49964
50516
|
`;
|
|
49965
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
|
+
}
|
|
49966
50549
|
var ShellDashboardTui = class {
|
|
49967
50550
|
constructor(runtime) {
|
|
49968
50551
|
this.runtime = runtime;
|
|
49969
50552
|
}
|
|
49970
|
-
cwd =
|
|
50553
|
+
cwd = import_node_process36.default.cwd();
|
|
49971
50554
|
state = null;
|
|
49972
50555
|
handleResize = () => {
|
|
49973
50556
|
this.render();
|
|
49974
50557
|
};
|
|
49975
50558
|
start(cwd, state) {
|
|
49976
|
-
if (!
|
|
50559
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49977
50560
|
return;
|
|
49978
50561
|
}
|
|
49979
50562
|
this.cwd = cwd;
|
|
49980
50563
|
this.state = state;
|
|
49981
|
-
|
|
49982
|
-
|
|
50564
|
+
import_node_process36.default.stdout.write(`${ALT_SCREEN_ENTER}${HIDE_CURSOR}`);
|
|
50565
|
+
import_node_process36.default.stdout.on("resize", this.handleResize);
|
|
49983
50566
|
this.render();
|
|
49984
50567
|
}
|
|
49985
50568
|
update(cwd, state) {
|
|
@@ -49988,17 +50571,17 @@ var ShellDashboardTui = class {
|
|
|
49988
50571
|
this.render();
|
|
49989
50572
|
}
|
|
49990
50573
|
render() {
|
|
49991
|
-
if (!
|
|
50574
|
+
if (!import_node_process36.default.stdout.isTTY || !this.state || this.runtime.activeExecution) {
|
|
49992
50575
|
return;
|
|
49993
50576
|
}
|
|
49994
|
-
|
|
50577
|
+
import_node_process36.default.stdout.write(renderShellDashboard(this.cwd, this.state, this.runtime));
|
|
49995
50578
|
}
|
|
49996
50579
|
stop() {
|
|
49997
|
-
if (!
|
|
50580
|
+
if (!import_node_process36.default.stdout.isTTY) {
|
|
49998
50581
|
return;
|
|
49999
50582
|
}
|
|
50000
|
-
|
|
50001
|
-
|
|
50583
|
+
import_node_process36.default.stdout.off("resize", this.handleResize);
|
|
50584
|
+
import_node_process36.default.stdout.write(`${SHOW_CURSOR}${ALT_SCREEN_EXIT}`);
|
|
50002
50585
|
}
|
|
50003
50586
|
};
|
|
50004
50587
|
function renderInlineMarkdown(value) {
|
|
@@ -50311,138 +50894,6 @@ function renderPendingRunProposal(proposal, options = {}) {
|
|
|
50311
50894
|
}
|
|
50312
50895
|
return lines;
|
|
50313
50896
|
}
|
|
50314
|
-
function buildWorkspaceAnalysisPlan(request, prompt) {
|
|
50315
|
-
const generatedAt = (/* @__PURE__ */ new Date()).toISOString();
|
|
50316
|
-
return {
|
|
50317
|
-
goal: request.goal,
|
|
50318
|
-
generatedAt,
|
|
50319
|
-
summary: "Read-only multi-agent analysis of the current repository to answer the operator's question with concrete workspace evidence.",
|
|
50320
|
-
repoStrategy: {
|
|
50321
|
-
mode: "existing-repo",
|
|
50322
|
-
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."
|
|
50323
|
-
},
|
|
50324
|
-
assumptions: [
|
|
50325
|
-
"The user wants a grounded explanation of the current repository, not code changes.",
|
|
50326
|
-
"The analysis should stay read-only and avoid modifying product files."
|
|
50327
|
-
],
|
|
50328
|
-
openQuestions: [],
|
|
50329
|
-
milestones: [
|
|
50330
|
-
{
|
|
50331
|
-
id: "m1-repo-survey",
|
|
50332
|
-
title: "Repository Survey",
|
|
50333
|
-
objective: "Inspect the current workspace structure, entrypoints, tooling, and conventions.",
|
|
50334
|
-
tasks: [
|
|
50335
|
-
{
|
|
50336
|
-
id: "t1-repo-analysis",
|
|
50337
|
-
title: "Analyze the current workspace and conventions",
|
|
50338
|
-
description: "Map the repository shape, commands, entrypoints, and constraints before answering the user's question.",
|
|
50339
|
-
type: "analysis",
|
|
50340
|
-
status: "pending",
|
|
50341
|
-
agentRole: "repo-analyst",
|
|
50342
|
-
dependsOn: [],
|
|
50343
|
-
acceptanceCriteria: [
|
|
50344
|
-
"Repository shape and commands are captured.",
|
|
50345
|
-
"Likely entrypoints and major packages are identified."
|
|
50346
|
-
],
|
|
50347
|
-
outputs: [
|
|
50348
|
-
"Repo analysis summary"
|
|
50349
|
-
],
|
|
50350
|
-
filesLikelyTouched: [
|
|
50351
|
-
".",
|
|
50352
|
-
".kimbho/"
|
|
50353
|
-
],
|
|
50354
|
-
riskLevel: "low",
|
|
50355
|
-
sandboxModeOverride: "read-only"
|
|
50356
|
-
},
|
|
50357
|
-
{
|
|
50358
|
-
id: "t2-architecture",
|
|
50359
|
-
title: "Synthesize the architecture and package boundaries",
|
|
50360
|
-
description: "Turn the repository findings into a clear explanation of the system structure and responsibilities.",
|
|
50361
|
-
type: "documentation",
|
|
50362
|
-
status: "pending",
|
|
50363
|
-
agentRole: "planner",
|
|
50364
|
-
dependsOn: [
|
|
50365
|
-
"t1-repo-analysis"
|
|
50366
|
-
],
|
|
50367
|
-
acceptanceCriteria: [
|
|
50368
|
-
"Architecture summary is grounded in repo analysis findings.",
|
|
50369
|
-
"The main packages and responsibilities are explicit."
|
|
50370
|
-
],
|
|
50371
|
-
outputs: [
|
|
50372
|
-
"Architecture brief"
|
|
50373
|
-
],
|
|
50374
|
-
filesLikelyTouched: [
|
|
50375
|
-
".kimbho/"
|
|
50376
|
-
],
|
|
50377
|
-
riskLevel: "low",
|
|
50378
|
-
sandboxModeOverride: "read-only"
|
|
50379
|
-
}
|
|
50380
|
-
]
|
|
50381
|
-
},
|
|
50382
|
-
{
|
|
50383
|
-
id: "m2-answer",
|
|
50384
|
-
title: "Answer",
|
|
50385
|
-
objective: "Review the gathered analysis artifacts and produce the final project explanation.",
|
|
50386
|
-
tasks: [
|
|
50387
|
-
{
|
|
50388
|
-
id: "t3-project-brief",
|
|
50389
|
-
title: "Review the analysis artifacts and prepare the project explanation",
|
|
50390
|
-
description: "Inspect the repo-analysis and architecture artifacts, then summarize the current project in terms that answer the user's question.",
|
|
50391
|
-
type: "documentation",
|
|
50392
|
-
status: "pending",
|
|
50393
|
-
agentRole: "reviewer",
|
|
50394
|
-
dependsOn: [
|
|
50395
|
-
"t1-repo-analysis",
|
|
50396
|
-
"t2-architecture"
|
|
50397
|
-
],
|
|
50398
|
-
acceptanceCriteria: [
|
|
50399
|
-
"The answer addresses the user's question directly.",
|
|
50400
|
-
"The summary is grounded in repository evidence instead of generic assistant chatter."
|
|
50401
|
-
],
|
|
50402
|
-
outputs: [
|
|
50403
|
-
"Project explanation summary"
|
|
50404
|
-
],
|
|
50405
|
-
filesLikelyTouched: [
|
|
50406
|
-
".kimbho/logs/",
|
|
50407
|
-
"kimbho_init.md"
|
|
50408
|
-
],
|
|
50409
|
-
riskLevel: "low",
|
|
50410
|
-
sandboxModeOverride: "read-only",
|
|
50411
|
-
allowedTools: [
|
|
50412
|
-
"file.read",
|
|
50413
|
-
"file.search",
|
|
50414
|
-
"file.list",
|
|
50415
|
-
"repo.index",
|
|
50416
|
-
"repo.query",
|
|
50417
|
-
"git.diff"
|
|
50418
|
-
],
|
|
50419
|
-
deniedTools: [
|
|
50420
|
-
"file.write",
|
|
50421
|
-
"file.patch",
|
|
50422
|
-
"shell.exec"
|
|
50423
|
-
],
|
|
50424
|
-
agentPromptPreamble: [
|
|
50425
|
-
"This is a read-only repository explanation task.",
|
|
50426
|
-
"Do not modify product files, install packages, or run development servers.",
|
|
50427
|
-
`Answer the operator's question: ${prompt}`,
|
|
50428
|
-
"Use the repo-analysis and architecture artifacts plus direct file inspection if needed.",
|
|
50429
|
-
"Finish with a concise but concrete summary of the project, stack, entrypoints, commands, and notable risks or gaps."
|
|
50430
|
-
].join("\n")
|
|
50431
|
-
}
|
|
50432
|
-
]
|
|
50433
|
-
}
|
|
50434
|
-
],
|
|
50435
|
-
verificationChecklist: [
|
|
50436
|
-
"Repo analysis artifacts were captured.",
|
|
50437
|
-
"The architecture summary is grounded in the workspace.",
|
|
50438
|
-
"The final explanation answers the user's question without changing source files."
|
|
50439
|
-
],
|
|
50440
|
-
executionNotes: [
|
|
50441
|
-
"Read-only analysis run triggered directly from a workspace question.",
|
|
50442
|
-
"Prefer repo/file tools and existing memory artifacts over generic assistant responses."
|
|
50443
|
-
]
|
|
50444
|
-
};
|
|
50445
|
-
}
|
|
50446
50897
|
function hasRenderableDiff(toolId, output) {
|
|
50447
50898
|
if (!output || output.trim().length === 0) {
|
|
50448
50899
|
return false;
|
|
@@ -50567,7 +51018,7 @@ function renderShellSessionSummary(snapshot, planPath, sessionPath) {
|
|
|
50567
51018
|
snapshot.events.flatMap((event) => [
|
|
50568
51019
|
...event.artifacts,
|
|
50569
51020
|
...event.toolResults.flatMap((toolResult) => toolResult.artifacts)
|
|
50570
|
-
]).filter((artifact) => !artifact.includes(`${
|
|
51021
|
+
]).filter((artifact) => !artifact.includes(`${import_node_path34.default.sep}.kimbho${import_node_path34.default.sep}`))
|
|
50571
51022
|
));
|
|
50572
51023
|
const visibleNotes = snapshot.notes.filter(
|
|
50573
51024
|
(note) => /limit reached|approval|blocked|failed|error|conflict|denied/i.test(note)
|
|
@@ -50594,9 +51045,7 @@ function renderShellSessionSummary(snapshot, planPath, sessionPath) {
|
|
|
50594
51045
|
if (snapshot.pendingApprovals.length > 0) {
|
|
50595
51046
|
lines.push("");
|
|
50596
51047
|
lines.push(color(BOLD, "Waiting For Approval"));
|
|
50597
|
-
|
|
50598
|
-
lines.push(`\u2022 ${approval.reason}`);
|
|
50599
|
-
}
|
|
51048
|
+
lines.push(...renderPendingApprovalLines(snapshot.pendingApprovals.slice(0, 4)));
|
|
50600
51049
|
}
|
|
50601
51050
|
if (visibleNotes.length > 0) {
|
|
50602
51051
|
lines.push("");
|
|
@@ -50611,7 +51060,8 @@ function renderShellSessionSummary(snapshot, planPath, sessionPath) {
|
|
|
50611
51060
|
}
|
|
50612
51061
|
lines.push(color(DIM, `saved session: ${sessionPath}`));
|
|
50613
51062
|
if (snapshot.pendingApprovals.length > 0) {
|
|
50614
|
-
lines.push(
|
|
51063
|
+
lines.push(renderApprovalCommandHint());
|
|
51064
|
+
lines.push(color(DIM, renderApprovalShortcutHint(snapshot.pendingApprovals.length)));
|
|
50615
51065
|
} else if (snapshot.status === "paused" || snapshot.status === "running" || snapshot.status === "ready") {
|
|
50616
51066
|
lines.push("next: /resume to continue a paused run or start another request");
|
|
50617
51067
|
} else if (snapshot.status === "blocked") {
|
|
@@ -50723,7 +51173,8 @@ function renderLiveExecutionEvent(event, board, startedAt, options = {}) {
|
|
|
50723
51173
|
case "approval-requested":
|
|
50724
51174
|
return [
|
|
50725
51175
|
`${color(AMBER, "Approval Needed")} ${event.approval.reason}`,
|
|
50726
|
-
color(DIM,
|
|
51176
|
+
color(DIM, renderApprovalCommandHint()),
|
|
51177
|
+
color(DIM, renderApprovalShortcutHint(board.approvals)),
|
|
50727
51178
|
...progressLines
|
|
50728
51179
|
];
|
|
50729
51180
|
case "approval-resolved":
|
|
@@ -50910,12 +51361,12 @@ function rewindConversation(runtime, role, turns) {
|
|
|
50910
51361
|
return removed;
|
|
50911
51362
|
}
|
|
50912
51363
|
async function writeTextToClipboard(value) {
|
|
50913
|
-
const candidates =
|
|
51364
|
+
const candidates = import_node_process36.default.platform === "darwin" ? [
|
|
50914
51365
|
{
|
|
50915
51366
|
command: "pbcopy",
|
|
50916
51367
|
args: []
|
|
50917
51368
|
}
|
|
50918
|
-
] :
|
|
51369
|
+
] : import_node_process36.default.platform === "win32" ? [
|
|
50919
51370
|
{
|
|
50920
51371
|
command: "clip",
|
|
50921
51372
|
args: []
|
|
@@ -50963,7 +51414,7 @@ async function writeTextToClipboard(value) {
|
|
|
50963
51414
|
}
|
|
50964
51415
|
function createShellExportPath(cwd, role, kind) {
|
|
50965
51416
|
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
|
|
50966
|
-
return
|
|
51417
|
+
return import_node_path34.default.join(cwd, ".kimbho", "exports", `${kind}-${role}-${stamp}.md`);
|
|
50967
51418
|
}
|
|
50968
51419
|
function clearConversation(runtime, role) {
|
|
50969
51420
|
runtime.conversations[role] = [];
|
|
@@ -51069,7 +51520,7 @@ async function handleChatPrompt(cwd, prompt, runtime) {
|
|
|
51069
51520
|
const workspaceInfoPrompt = looksLikeWorkspaceInfoPrompt(hydrated.prompt);
|
|
51070
51521
|
let workspaceOverview = null;
|
|
51071
51522
|
if (workspaceInfoPrompt) {
|
|
51072
|
-
const existingOverview = await readMarkdownIfExists(
|
|
51523
|
+
const existingOverview = await readMarkdownIfExists(import_node_path34.default.join(cwd, "kimbho_init.md"));
|
|
51073
51524
|
if (existingOverview) {
|
|
51074
51525
|
workspaceOverview = existingOverview.slice(0, 6e3);
|
|
51075
51526
|
} else {
|
|
@@ -51255,7 +51706,7 @@ async function executePendingRunProposal(runtime) {
|
|
|
51255
51706
|
resolveShellMaxAgentSteps(runtime),
|
|
51256
51707
|
DEFAULT_MAX_REPAIR_ATTEMPTS2
|
|
51257
51708
|
);
|
|
51258
|
-
const tui =
|
|
51709
|
+
const tui = import_node_process36.default.stdout.isTTY ? new ShellExecutionTui(liveBoard, telemetry, startedAt, "starting", !runtime.dashboard) : null;
|
|
51259
51710
|
const activity = tui ? null : new ShellActivityIndicator("starting");
|
|
51260
51711
|
if (tui) {
|
|
51261
51712
|
tui.start();
|
|
@@ -51323,59 +51774,6 @@ async function executePendingRunProposal(runtime) {
|
|
|
51323
51774
|
void drainQueuedWork(runtime);
|
|
51324
51775
|
return request.cwd;
|
|
51325
51776
|
}
|
|
51326
|
-
async function synthesizeWorkspaceAnalysisAnswer(cwd, prompt, runtime, snapshot) {
|
|
51327
|
-
const config2 = await loadConfig(cwd);
|
|
51328
|
-
const projectInit = await readMarkdownIfExists(import_node_path33.default.join(cwd, "kimbho_init.md"));
|
|
51329
|
-
const artifactPaths = Array.from(new Set(
|
|
51330
|
-
snapshot.events.flatMap((event) => [
|
|
51331
|
-
...event.artifacts,
|
|
51332
|
-
...event.toolResults.flatMap((toolResult) => toolResult.artifacts)
|
|
51333
|
-
])
|
|
51334
|
-
));
|
|
51335
|
-
const prioritizedArtifacts = artifactPaths.filter((artifactPath) => /repo-analysis|architecture-brief|project-brief|transcript/i.test(import_node_path33.default.basename(artifactPath))).slice(0, 4);
|
|
51336
|
-
const artifactSections = (await Promise.all(
|
|
51337
|
-
prioritizedArtifacts.map(async (artifactPath) => {
|
|
51338
|
-
const content = await readMarkdownIfExists(artifactPath);
|
|
51339
|
-
if (!content) {
|
|
51340
|
-
return null;
|
|
51341
|
-
}
|
|
51342
|
-
return `Artifact: ${artifactPath}
|
|
51343
|
-
${content.slice(0, 4e3)}`;
|
|
51344
|
-
})
|
|
51345
|
-
)).filter((section) => Boolean(section));
|
|
51346
|
-
if (!config2) {
|
|
51347
|
-
return [
|
|
51348
|
-
"Repository analysis completed.",
|
|
51349
|
-
projectInit ? `Current workspace summary:
|
|
51350
|
-
${projectInit.slice(0, 4e3)}` : "Project summary is available in the session artifacts, but no configured model was available to synthesize a narrative answer."
|
|
51351
|
-
].join("\n\n");
|
|
51352
|
-
}
|
|
51353
|
-
const resolver = new BrainResolver(config2, createDefaultBrainProviderRegistry(cwd));
|
|
51354
|
-
const brain = await resolver.resolve(runtime.focusRole);
|
|
51355
|
-
const result = await brain.client.generateText({
|
|
51356
|
-
model: brain.model,
|
|
51357
|
-
systemPrompt: [
|
|
51358
|
-
brain.settings.promptPreamble,
|
|
51359
|
-
"You are summarizing the current repository after a read-only multi-agent analysis session.",
|
|
51360
|
-
"Answer the user's question directly and concretely from the provided workspace evidence.",
|
|
51361
|
-
"Do not greet, do not speak generically about your own capabilities, and do not invent repository details.",
|
|
51362
|
-
"Prefer a crisp project overview with stack, structure, key entrypoints, commands, and notable risks or gaps."
|
|
51363
|
-
].filter(Boolean).join("\n\n"),
|
|
51364
|
-
userPrompt: [
|
|
51365
|
-
`User question: ${prompt}`,
|
|
51366
|
-
projectInit ? `Workspace overview:
|
|
51367
|
-
${projectInit.slice(0, 6e3)}` : null,
|
|
51368
|
-
artifactSections.length > 0 ? artifactSections.join("\n\n") : "No detailed analysis artifacts were available; answer from the workspace overview only."
|
|
51369
|
-
].filter((value) => Boolean(value)).join("\n\n"),
|
|
51370
|
-
...typeof brain.settings.temperature === "number" ? {
|
|
51371
|
-
temperature: brain.settings.temperature
|
|
51372
|
-
} : {},
|
|
51373
|
-
...typeof brain.settings.maxTokens === "number" ? {
|
|
51374
|
-
maxTokens: brain.settings.maxTokens
|
|
51375
|
-
} : {}
|
|
51376
|
-
});
|
|
51377
|
-
return result.text;
|
|
51378
|
-
}
|
|
51379
51777
|
async function handleWorkspaceAnalysisPrompt(cwd, prompt, runtime) {
|
|
51380
51778
|
const hydrated = await hydratePromptWithMcpResources(cwd, prompt);
|
|
51381
51779
|
await recordAdaptiveTextObservation(cwd, hydrated.prompt, "chat");
|
|
@@ -51413,7 +51811,7 @@ async function handleWorkspaceAnalysisPrompt(cwd, prompt, runtime) {
|
|
|
51413
51811
|
resolveShellMaxAgentSteps(runtime),
|
|
51414
51812
|
DEFAULT_MAX_REPAIR_ATTEMPTS2
|
|
51415
51813
|
);
|
|
51416
|
-
const tui =
|
|
51814
|
+
const tui = import_node_process36.default.stdout.isTTY ? new ShellExecutionTui(liveBoard, telemetry, startedAt, "analyzing", !runtime.dashboard) : null;
|
|
51417
51815
|
const activity = tui ? null : new ShellActivityIndicator("analyzing");
|
|
51418
51816
|
if (tui) {
|
|
51419
51817
|
tui.start();
|
|
@@ -51469,7 +51867,12 @@ async function handleWorkspaceAnalysisPrompt(cwd, prompt, runtime) {
|
|
|
51469
51867
|
const sessionPath = await saveSession(snapshot, request.cwd);
|
|
51470
51868
|
await recordAdaptiveSessionOutcome(request.cwd, snapshot);
|
|
51471
51869
|
runtime.currentCwd = request.cwd;
|
|
51472
|
-
const answer = await synthesizeWorkspaceAnalysisAnswer(
|
|
51870
|
+
const answer = await synthesizeWorkspaceAnalysisAnswer(
|
|
51871
|
+
request.cwd,
|
|
51872
|
+
hydrated.prompt,
|
|
51873
|
+
runtime.focusRole,
|
|
51874
|
+
snapshot
|
|
51875
|
+
);
|
|
51473
51876
|
const conversation = trimConversation([
|
|
51474
51877
|
...getConversation(runtime, runtime.focusRole),
|
|
51475
51878
|
{
|
|
@@ -51513,7 +51916,7 @@ async function resumeGoalExecution(cwd, runtime) {
|
|
|
51513
51916
|
controller,
|
|
51514
51917
|
label: session.id
|
|
51515
51918
|
};
|
|
51516
|
-
const tui =
|
|
51919
|
+
const tui = import_node_process36.default.stdout.isTTY ? new ShellExecutionTui(liveBoard, telemetry, startedAt, "resuming", !runtime.dashboard) : null;
|
|
51517
51920
|
const activity = tui ? null : new ShellActivityIndicator("resuming");
|
|
51518
51921
|
if (tui) {
|
|
51519
51922
|
tui.start();
|
|
@@ -51629,7 +52032,7 @@ async function resolvePendingApproval(cwd, runtime, decision, approvalId, option
|
|
|
51629
52032
|
controller,
|
|
51630
52033
|
label: approvals.length === 1 ? `${session.id}:${approvals[0].id}` : `${session.id}:batch-approval`
|
|
51631
52034
|
};
|
|
51632
|
-
const tui =
|
|
52035
|
+
const tui = import_node_process36.default.stdout.isTTY ? new ShellExecutionTui(liveBoard, telemetry, startedAt, decision === "approve" ? "approving" : "denying", !runtime.dashboard) : null;
|
|
51633
52036
|
const activity = tui ? null : new ShellActivityIndicator(decision === "approve" ? "approving" : "denying");
|
|
51634
52037
|
if (tui) {
|
|
51635
52038
|
tui.start();
|
|
@@ -51693,16 +52096,74 @@ async function resolvePendingApproval(cwd, runtime, decision, approvalId, option
|
|
|
51693
52096
|
void drainQueuedWork(runtime);
|
|
51694
52097
|
}
|
|
51695
52098
|
async function applyApproveAllPreset(cwd, runtime, rawPreset) {
|
|
51696
|
-
|
|
51697
|
-
|
|
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;
|
|
51698
52115
|
}
|
|
51699
|
-
const preset = resolvePermissionPreset(rawPreset);
|
|
52116
|
+
const preset = resolvePermissionPreset(rawPreset ?? "auto");
|
|
51700
52117
|
setShellSessionPermissions(runtime, preset);
|
|
51701
52118
|
console.log(`Shell permission override: ${preset.label}`);
|
|
51702
52119
|
await recordAdaptiveTextObservation(cwd, `User approval preference: ${preset.label}`, "approval");
|
|
51703
52120
|
const session = await loadLatestSession(cwd);
|
|
51704
52121
|
return Boolean(session && session.pendingApprovals.length > 0);
|
|
51705
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
|
+
}
|
|
51706
52167
|
async function printLatestPlanSummary(cwd) {
|
|
51707
52168
|
const plan = await loadLatestPlan(cwd);
|
|
51708
52169
|
if (!plan) {
|
|
@@ -51849,7 +52310,7 @@ async function handlePermissionsCommand(cwd, tokens, runtime) {
|
|
|
51849
52310
|
if (!target) {
|
|
51850
52311
|
throw new Error(`Usage: /permissions ${subcommand} <path>`);
|
|
51851
52312
|
}
|
|
51852
|
-
const normalizedTarget =
|
|
52313
|
+
const normalizedTarget = import_node_path34.default.resolve(cwd, target);
|
|
51853
52314
|
const trustedDirectories = subcommand === "trust" ? Array.from(/* @__PURE__ */ new Set([
|
|
51854
52315
|
...effective.trustedDirectories,
|
|
51855
52316
|
normalizedTarget
|
|
@@ -51965,7 +52426,7 @@ async function handleExportCommand(cwd, tokens, runtime) {
|
|
|
51965
52426
|
);
|
|
51966
52427
|
const destinationToken = knownKind ? tokens[2] : tokens[1];
|
|
51967
52428
|
const outputPath = await writeMarkdownFile(
|
|
51968
|
-
destinationToken ?
|
|
52429
|
+
destinationToken ? import_node_path34.default.resolve(cwd, destinationToken) : createShellExportPath(cwd, runtime.focusRole, knownKind ? kindToken : "context"),
|
|
51969
52430
|
payload.content
|
|
51970
52431
|
);
|
|
51971
52432
|
console.log(`Exported ${payload.label} -> ${outputPath}`);
|
|
@@ -51975,7 +52436,7 @@ async function handleAddDirCommand(cwd, tokens, runtime) {
|
|
|
51975
52436
|
if (!target) {
|
|
51976
52437
|
throw new Error("Usage: /add-dir <path>");
|
|
51977
52438
|
}
|
|
51978
|
-
const resolved =
|
|
52439
|
+
const resolved = import_node_path34.default.resolve(cwd, target);
|
|
51979
52440
|
if (!runtime.additionalDirectories.includes(resolved)) {
|
|
51980
52441
|
runtime.additionalDirectories.push(resolved);
|
|
51981
52442
|
runtime.additionalDirectories.sort((left, right) => left.localeCompare(right));
|
|
@@ -52052,7 +52513,7 @@ async function handleHooksCommand(cwd, tokens) {
|
|
|
52052
52513
|
console.log(lines.join("\n"));
|
|
52053
52514
|
}
|
|
52054
52515
|
function shellHookSessionId(runtime, cwd) {
|
|
52055
|
-
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"}`;
|
|
52056
52517
|
}
|
|
52057
52518
|
async function createShellHookRunner(cwd, config2) {
|
|
52058
52519
|
const resolvedConfig = config2 ?? await loadConfig(cwd).catch(() => null);
|
|
@@ -52236,7 +52697,7 @@ async function handleMemoryCommand(cwd, tokens) {
|
|
|
52236
52697
|
}
|
|
52237
52698
|
let filePath;
|
|
52238
52699
|
if (scope === "init") {
|
|
52239
|
-
filePath =
|
|
52700
|
+
filePath = import_node_path34.default.join(cwd, "kimbho_init.md");
|
|
52240
52701
|
} else if (scope === "project") {
|
|
52241
52702
|
filePath = resolveProjectMemoryPath(cwd);
|
|
52242
52703
|
} else if (scope === "user") {
|
|
@@ -52246,7 +52707,7 @@ async function handleMemoryCommand(cwd, tokens) {
|
|
|
52246
52707
|
if (!agentId) {
|
|
52247
52708
|
throw new Error("Usage: /memory show agent <agent-id>");
|
|
52248
52709
|
}
|
|
52249
|
-
filePath =
|
|
52710
|
+
filePath = import_node_path34.default.join(resolveAgentMemoryDir(cwd), `${agentId}.md`);
|
|
52250
52711
|
} else {
|
|
52251
52712
|
throw new Error("Usage: /memory show <init|project|user|agent> [id]");
|
|
52252
52713
|
}
|
|
@@ -52855,7 +53316,7 @@ async function printProviderList(cwd, focusRole) {
|
|
|
52855
53316
|
const activeProviderId = config2.brains[focusRole].providerId;
|
|
52856
53317
|
for (const provider of config2.providers) {
|
|
52857
53318
|
const marker = provider.id === activeProviderId ? "*" : " ";
|
|
52858
|
-
const envState = provider.apiKeyEnv ?
|
|
53319
|
+
const envState = provider.apiKeyEnv ? import_node_process36.default.env[provider.apiKeyEnv] ? "present" : `missing ${provider.apiKeyEnv}` : "no key required";
|
|
52859
53320
|
console.log(`${marker} ${provider.id}`);
|
|
52860
53321
|
console.log(` label: ${provider.label ?? "-"}`);
|
|
52861
53322
|
console.log(` driver: ${provider.driver}`);
|
|
@@ -53310,6 +53771,9 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
53310
53771
|
await resolvePendingHookElicitation(cwd, runtime, "answer", trimmed);
|
|
53311
53772
|
return cwd;
|
|
53312
53773
|
}
|
|
53774
|
+
if (!isSlashCommand && !runtime.pendingRunProposal && await tryResolveApprovalShortcut(cwd, runtime, trimmed)) {
|
|
53775
|
+
return cwd;
|
|
53776
|
+
}
|
|
53313
53777
|
if (head.startsWith("mcp__")) {
|
|
53314
53778
|
const parts = head.split("__").filter((part) => part.length > 0);
|
|
53315
53779
|
if (parts.length < 3) {
|
|
@@ -53613,7 +54077,7 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
53613
54077
|
await createPlanOnly(cwd, goal);
|
|
53614
54078
|
return cwd;
|
|
53615
54079
|
}
|
|
53616
|
-
if (head === "resume") {
|
|
54080
|
+
if (head === "resume" || head === "continue") {
|
|
53617
54081
|
queueResumeRequest(cwd, runtime);
|
|
53618
54082
|
return cwd;
|
|
53619
54083
|
}
|
|
@@ -53626,16 +54090,16 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
53626
54090
|
}
|
|
53627
54091
|
if (head === "approve-all") {
|
|
53628
54092
|
const shouldResolvePending = await applyApproveAllPreset(cwd, runtime, tokens[1]?.trim());
|
|
53629
|
-
if (
|
|
54093
|
+
if (!shouldResolvePending) {
|
|
53630
54094
|
if (runtime.pendingRunProposal) {
|
|
53631
54095
|
void startPendingRunExecution(cwd, runtime);
|
|
53632
54096
|
return cwd;
|
|
53633
54097
|
}
|
|
53634
|
-
|
|
53635
|
-
|
|
53636
|
-
|
|
53637
|
-
|
|
53638
|
-
|
|
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
|
+
}
|
|
53639
54103
|
return cwd;
|
|
53640
54104
|
}
|
|
53641
54105
|
await resolvePendingApproval(
|
|
@@ -53651,6 +54115,27 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
53651
54115
|
}
|
|
53652
54116
|
if (head === "approve" || head === "deny") {
|
|
53653
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
|
+
}
|
|
53654
54139
|
if (!approvalId && runtime.pendingRunProposal) {
|
|
53655
54140
|
if (head === "approve") {
|
|
53656
54141
|
void startPendingRunExecution(cwd, runtime);
|
|
@@ -53681,9 +54166,9 @@ async function handleShellCommand(cwd, input, state, runtime, execute) {
|
|
|
53681
54166
|
}
|
|
53682
54167
|
async function runInteractiveShell(options) {
|
|
53683
54168
|
const readline = (0, import_promises27.createInterface)({
|
|
53684
|
-
input:
|
|
53685
|
-
output:
|
|
53686
|
-
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)
|
|
53687
54172
|
});
|
|
53688
54173
|
const runtime = {
|
|
53689
54174
|
focusRole: "coder",
|
|
@@ -53715,7 +54200,7 @@ async function runInteractiveShell(options) {
|
|
|
53715
54200
|
};
|
|
53716
54201
|
let currentCwd = options.cwd;
|
|
53717
54202
|
let closed = false;
|
|
53718
|
-
const useDashboard = Boolean(
|
|
54203
|
+
const useDashboard = Boolean(import_node_process36.default.stdin.isTTY && import_node_process36.default.stdout.isTTY);
|
|
53719
54204
|
const originalLog = console.log;
|
|
53720
54205
|
const originalError = console.error;
|
|
53721
54206
|
if (useDashboard) {
|
|
@@ -53731,7 +54216,7 @@ async function runInteractiveShell(options) {
|
|
|
53731
54216
|
readline.on("SIGINT", () => {
|
|
53732
54217
|
if (runtime.activeExecution) {
|
|
53733
54218
|
runtime.activeExecution.controller.abort();
|
|
53734
|
-
|
|
54219
|
+
import_node_process36.default.stdout.write("\n");
|
|
53735
54220
|
console.log(color(DIM, `Interrupt requested. Pausing ${runtime.activeExecution.label} after the current step...`));
|
|
53736
54221
|
return;
|
|
53737
54222
|
}
|
|
@@ -53752,10 +54237,14 @@ async function runInteractiveShell(options) {
|
|
|
53752
54237
|
try {
|
|
53753
54238
|
state = await getShellSessionState(currentCwd, runtime.focusRole, runtime);
|
|
53754
54239
|
runtime.dashboard?.update(currentCwd, state);
|
|
53755
|
-
line = await readline
|
|
54240
|
+
line = await readShellInput(readline, state);
|
|
53756
54241
|
} catch {
|
|
53757
54242
|
break;
|
|
53758
54243
|
}
|
|
54244
|
+
if (line === "__kimbho_sigint__") {
|
|
54245
|
+
closed = true;
|
|
54246
|
+
break;
|
|
54247
|
+
}
|
|
53759
54248
|
try {
|
|
53760
54249
|
currentCwd = await handleShellCommand(currentCwd, line, state, runtime, options.execute);
|
|
53761
54250
|
runtime.currentCwd = currentCwd;
|
|
@@ -53767,7 +54256,7 @@ async function runInteractiveShell(options) {
|
|
|
53767
54256
|
}
|
|
53768
54257
|
console.error(message);
|
|
53769
54258
|
} finally {
|
|
53770
|
-
|
|
54259
|
+
import_node_process36.default.exitCode = 0;
|
|
53771
54260
|
}
|
|
53772
54261
|
if (!closed && !useDashboard) {
|
|
53773
54262
|
console.log("");
|
|
@@ -53778,7 +54267,7 @@ async function runInteractiveShell(options) {
|
|
|
53778
54267
|
if (runtime.activeExecution) {
|
|
53779
54268
|
runtime.activeExecution.controller.abort();
|
|
53780
54269
|
}
|
|
53781
|
-
|
|
54270
|
+
import_node_process36.default.exitCode = 0;
|
|
53782
54271
|
if (useDashboard) {
|
|
53783
54272
|
runtime.dashboard?.stop();
|
|
53784
54273
|
console.log = originalLog;
|