@kimbho/kimbho-cli 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -28,12 +28,26 @@ npm install -g ./kimbho-kimbho-cli-0.1.0.tgz
28
28
  ## Usage
29
29
 
30
30
  ```bash
31
+ kimbho
32
+ kimbho shell
31
33
  kimbho --help
32
34
  kimbho init
33
35
  kimbho plan "build a coding agent"
34
36
  kimbho /models openrouter --search claude --limit 10
35
37
  ```
36
38
 
39
+ Bare `kimbho` opens the interactive shell. Within that shell, plain-English input is treated as `run <goal>`, and slash commands like `/plan`, `/run`, `/models`, and `/brains` are supported.
40
+
41
+ Useful shell commands:
42
+
43
+ ```bash
44
+ /status
45
+ /model
46
+ /plan build a coding agent
47
+ /run scaffold a SaaS starter
48
+ /quit
49
+ ```
50
+
37
51
  ## Notes
38
52
 
39
53
  - The published CLI bundles the internal Kimbho packages so installation does not depend on the monorepo layout.
package/dist/index.cjs CHANGED
@@ -1149,7 +1149,7 @@ var require_command = __commonJS({
1149
1149
  var childProcess = require("node:child_process");
1150
1150
  var path4 = require("node:path");
1151
1151
  var fs = require("node:fs");
1152
- var process10 = require("node:process");
1152
+ var process11 = 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) => process10.stdout.write(str),
1200
- writeErr: (str) => process10.stderr.write(str),
1199
+ writeOut: (str) => process11.stdout.write(str),
1200
+ writeErr: (str) => process11.stderr.write(str),
1201
1201
  outputError: (str, write) => write(str),
1202
- getOutHelpWidth: () => process10.stdout.isTTY ? process10.stdout.columns : void 0,
1203
- getErrHelpWidth: () => process10.stderr.isTTY ? process10.stderr.columns : void 0,
1204
- getOutHasColors: () => useColor() ?? (process10.stdout.isTTY && process10.stdout.hasColors?.()),
1205
- getErrHasColors: () => useColor() ?? (process10.stderr.isTTY && process10.stderr.hasColors?.()),
1202
+ getOutHelpWidth: () => process11.stdout.isTTY ? process11.stdout.columns : void 0,
1203
+ getErrHelpWidth: () => process11.stderr.isTTY ? process11.stderr.columns : void 0,
1204
+ getOutHasColors: () => useColor() ?? (process11.stdout.isTTY && process11.stdout.hasColors?.()),
1205
+ getErrHasColors: () => useColor() ?? (process11.stderr.isTTY && process11.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
- process10.exit(exitCode);
1588
+ process11.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 (process10.versions?.electron) {
1986
+ if (process11.versions?.electron) {
1987
1987
  parseOptions.from = "electron";
1988
1988
  }
1989
- const execArgv = process10.execArgv ?? [];
1989
+ const execArgv = process11.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 = process10.argv;
1995
+ argv = process11.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 (process10.defaultApp) {
2006
+ if (process11.defaultApp) {
2007
2007
  this._scriptPath = argv[1];
2008
2008
  userArgs = argv.slice(2);
2009
2009
  } else {
@@ -2190,11 +2190,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
2190
2190
  }
2191
2191
  launchWithNode = sourceExt.includes(path4.extname(executableFile));
2192
2192
  let proc;
2193
- if (process10.platform !== "win32") {
2193
+ if (process11.platform !== "win32") {
2194
2194
  if (launchWithNode) {
2195
2195
  args.unshift(executableFile);
2196
- args = incrementNodeInspectorPort(process10.execArgv).concat(args);
2197
- proc = childProcess.spawn(process10.argv[0], args, { stdio: "inherit" });
2196
+ args = incrementNodeInspectorPort(process11.execArgv).concat(args);
2197
+ proc = childProcess.spawn(process11.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(process10.execArgv).concat(args);
2209
- proc = childProcess.spawn(process10.execPath, args, { stdio: "inherit" });
2208
+ args = incrementNodeInspectorPort(process11.execArgv).concat(args);
2209
+ proc = childProcess.spawn(process11.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
- process10.on(signal, () => {
2214
+ process11.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
- process10.exit(code);
2225
+ process11.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
- process10.exit(1);
2247
+ process11.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 process10.env) {
2742
+ if (option.envVar && option.envVar in process11.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()}`, process10.env[option.envVar]);
2748
+ this.emit(`optionEnv:${option.name()}`, process11.env[option.envVar]);
2749
2749
  } else {
2750
2750
  this.emit(`optionEnv:${option.name()}`);
2751
2751
  }
@@ -3200,7 +3200,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
3200
3200
  */
3201
3201
  help(contextOptions) {
3202
3202
  this.outputHelp(contextOptions);
3203
- let exitCode = Number(process10.exitCode ?? 0);
3203
+ let exitCode = Number(process11.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 (process10.env.NO_COLOR || process10.env.FORCE_COLOR === "0" || process10.env.FORCE_COLOR === "false")
3293
+ if (process11.env.NO_COLOR || process11.env.FORCE_COLOR === "0" || process11.env.FORCE_COLOR === "false")
3294
3294
  return false;
3295
- if (process10.env.FORCE_COLOR || process10.env.CLICOLOR_FORCE !== void 0)
3295
+ if (process11.env.FORCE_COLOR || process11.env.CLICOLOR_FORCE !== void 0)
3296
3296
  return true;
3297
3297
  return void 0;
3298
3298
  }
@@ -3340,6 +3340,55 @@ var {
3340
3340
  Help
3341
3341
  } = import_index.default;
3342
3342
 
3343
+ // package.json
3344
+ var package_default = {
3345
+ name: "@kimbho/kimbho-cli",
3346
+ version: "0.1.1",
3347
+ description: "Kimbho CLI is a terminal-native coding agent for planning, execution, and verification.",
3348
+ type: "module",
3349
+ engines: {
3350
+ node: ">=20.0.0"
3351
+ },
3352
+ preferGlobal: true,
3353
+ bin: {
3354
+ kimbho: "dist/index.cjs"
3355
+ },
3356
+ main: "dist/index.cjs",
3357
+ exports: {
3358
+ ".": {
3359
+ default: "./dist/index.cjs"
3360
+ }
3361
+ },
3362
+ files: [
3363
+ "dist",
3364
+ "README.md"
3365
+ ],
3366
+ publishConfig: {
3367
+ access: "public"
3368
+ },
3369
+ scripts: {
3370
+ build: "npm run clean && npm run build:bundle && npm run chmod:bin",
3371
+ "build:bundle": "esbuild src/index.ts --bundle --platform=node --format=cjs --sourcemap --outfile=dist/index.cjs --banner:js='#!/usr/bin/env node'",
3372
+ "chmod:bin": `node -e "require('node:fs').chmodSync('dist/index.cjs', 0o755)"`,
3373
+ clean: `node -e "require('node:fs').rmSync('dist', { recursive: true, force: true })"`,
3374
+ prepack: "npm run build"
3375
+ },
3376
+ dependencies: {
3377
+ commander: "^13.1.0"
3378
+ },
3379
+ devDependencies: {
3380
+ "@kimbho/agent-runtime": "file:../agent-runtime",
3381
+ "@kimbho/brains": "file:../brains",
3382
+ "@kimbho/core": "file:../core",
3383
+ "@kimbho/planner": "file:../planner",
3384
+ "@kimbho/tools": "file:../tools"
3385
+ }
3386
+ };
3387
+
3388
+ // src/metadata.ts
3389
+ var KIMBHO_VERSION = package_default.version;
3390
+ var KIMBHO_DESCRIPTION = "Kimbho CLI: a terminal-native coding agent for planning and execution.";
3391
+
3343
3392
  // ../agent-runtime/dist/agents/catalog.js
3344
3393
  var AGENT_CATALOG = {
3345
3394
  "session-orchestrator": {
@@ -9948,36 +9997,392 @@ function createReviewCommand() {
9948
9997
  );
9949
9998
  }
9950
9999
 
9951
- // src/index.ts
9952
- var program2 = new Command();
9953
- program2.name("kimbho").description("Kimbho CLI: a terminal-native coding agent for planning and execution.").version("0.1.0");
9954
- program2.addCommand(createInitCommand());
9955
- program2.addCommand(createPlanCommand());
9956
- program2.addCommand(createDoctorCommand());
9957
- program2.addCommand(createAgentsCommand());
9958
- program2.addCommand(createProvidersCommand());
9959
- program2.addCommand(createModelsCommand());
9960
- program2.addCommand(createBrainsCommand());
9961
- program2.addCommand(createRunCommand());
9962
- program2.addCommand(createResumeCommand());
9963
- program2.addCommand(createFixCommand());
9964
- program2.addCommand(createReviewCommand());
9965
- var normalizedArgv = process.argv.map(
9966
- (value, index) => index === 2 && value.startsWith("/") ? value.slice(1) : value
9967
- );
9968
- var modelsSubcommands = /* @__PURE__ */ new Set([
10000
+ // src/program.ts
10001
+ var MODELS_SUBCOMMANDS = /* @__PURE__ */ new Set([
9969
10002
  "help",
9970
10003
  "list",
9971
10004
  "sync",
9972
10005
  "use"
9973
10006
  ]);
9974
- if (normalizedArgv[2] === "models") {
9975
- const candidate = normalizedArgv[3];
9976
- if (!candidate || candidate.startsWith("-") || !modelsSubcommands.has(candidate)) {
9977
- normalizedArgv.splice(3, 0, "list");
10007
+ function normalizeCliTokens(tokens) {
10008
+ const normalized = [...tokens];
10009
+ if (normalized[0]?.startsWith("/")) {
10010
+ normalized[0] = normalized[0].slice(1);
10011
+ }
10012
+ if (normalized[0] === "models") {
10013
+ const candidate = normalized[1];
10014
+ if (!candidate || candidate.startsWith("-") || !MODELS_SUBCOMMANDS.has(candidate)) {
10015
+ normalized.splice(1, 0, "list");
10016
+ }
10017
+ }
10018
+ return normalized;
10019
+ }
10020
+ function createProgram(onOpenShell) {
10021
+ const program2 = new Command();
10022
+ program2.name("kimbho").description(KIMBHO_DESCRIPTION).version(KIMBHO_VERSION);
10023
+ program2.addCommand(createInitCommand());
10024
+ program2.addCommand(createPlanCommand());
10025
+ program2.addCommand(createDoctorCommand());
10026
+ program2.addCommand(createAgentsCommand());
10027
+ program2.addCommand(createProvidersCommand());
10028
+ program2.addCommand(createModelsCommand());
10029
+ program2.addCommand(createBrainsCommand());
10030
+ program2.addCommand(createRunCommand());
10031
+ program2.addCommand(createResumeCommand());
10032
+ program2.addCommand(createFixCommand());
10033
+ program2.addCommand(createReviewCommand());
10034
+ if (onOpenShell) {
10035
+ program2.command("shell").description("Open the interactive Kimbho shell.").action(async () => {
10036
+ await onOpenShell();
10037
+ });
10038
+ }
10039
+ return program2;
10040
+ }
10041
+
10042
+ // src/shell.ts
10043
+ var import_promises6 = require("node:readline/promises");
10044
+ var import_node_process9 = __toESM(require("node:process"), 1);
10045
+ var AMBER = "\x1B[38;5;214m";
10046
+ var BOLD = "\x1B[1m";
10047
+ var DIM = "\x1B[2m";
10048
+ var RESET = "\x1B[0m";
10049
+ var TOP_LEVEL_COMMANDS = /* @__PURE__ */ new Set([
10050
+ "agents",
10051
+ "brains",
10052
+ "doctor",
10053
+ "fix",
10054
+ "help",
10055
+ "init",
10056
+ "model",
10057
+ "models",
10058
+ "new",
10059
+ "plan",
10060
+ "providers",
10061
+ "quit",
10062
+ "resume",
10063
+ "review",
10064
+ "run",
10065
+ "scaffold",
10066
+ "shell",
10067
+ "status"
10068
+ ]);
10069
+ function color(code, value) {
10070
+ return `${code}${value}${RESET}`;
10071
+ }
10072
+ function renderBanner() {
10073
+ return [
10074
+ " _ ___ __ __ ____ ____ _ _ ___ ",
10075
+ "| |/ (_) \\/ | __ )| _ \\| | | |/ _ \\",
10076
+ "| ' /| | |\\/| | _ \\| | | | |_| | | | |",
10077
+ "| . \\| | | | | |_) | |_| | _ | |_| |",
10078
+ "|_|\\_\\_|_| |_|____/|____/|_| |_|\\___/ "
10079
+ ].map((line) => color(AMBER, line)).join("\n");
10080
+ }
10081
+ async function getShellSessionState(cwd) {
10082
+ const config = await loadConfig(cwd);
10083
+ if (!config) {
10084
+ return {
10085
+ providerLabel: "unconfigured",
10086
+ providerId: "-",
10087
+ coderModel: "not set",
10088
+ plannerModel: "not set",
10089
+ approvalMode: "manual",
10090
+ sandboxMode: "workspace-write",
10091
+ stackPreset: "next-prisma-postgres",
10092
+ configured: false
10093
+ };
10094
+ }
10095
+ const coderSettings = config.brains.coder;
10096
+ const provider = findProviderById(config, coderSettings.providerId);
10097
+ return {
10098
+ providerLabel: provider?.label ?? provider?.id ?? "unknown",
10099
+ providerId: provider?.id ?? coderSettings.providerId,
10100
+ coderModel: resolveBrainModel(config, "coder") ?? "not set",
10101
+ plannerModel: resolveBrainModel(config, "planner") ?? "not set",
10102
+ approvalMode: config.approvalMode,
10103
+ sandboxMode: config.sandboxMode,
10104
+ stackPreset: config.stackPresets[0] ?? "none",
10105
+ configured: true
10106
+ };
10107
+ }
10108
+ function renderCardLine(label, value) {
10109
+ return `${label}: ${value}`;
10110
+ }
10111
+ function shortenMiddle(value, maxLength) {
10112
+ if (value.length <= maxLength) {
10113
+ return value;
10114
+ }
10115
+ const visible = maxLength - 3;
10116
+ const left = Math.ceil(visible / 2);
10117
+ const right = Math.floor(visible / 2);
10118
+ return `${value.slice(0, left)}...${value.slice(value.length - right)}`;
10119
+ }
10120
+ function renderBox(lines) {
10121
+ const width = lines.reduce((max, line) => Math.max(max, line.length), 0);
10122
+ const top = `+${"-".repeat(width + 2)}+`;
10123
+ return [
10124
+ top,
10125
+ ...lines.map((line) => `| ${line.padEnd(width, " ")} |`),
10126
+ top
10127
+ ].join("\n");
10128
+ }
10129
+ function renderHelp() {
10130
+ return [
10131
+ `${color(DIM, "Commands")}`,
10132
+ "/status Show the active model, provider, and workspace state.",
10133
+ "/plan <goal> Create a structured implementation plan.",
10134
+ "/run <goal> Start a Kimbho execution session for a goal.",
10135
+ "/new <goal> Alias for /run <goal>.",
10136
+ "/scaffold <goal> Alias for /run <goal> with scaffolding intent.",
10137
+ "/resume Show the latest saved session.",
10138
+ "/agents Inspect agent roles and the active session.",
10139
+ "/providers Manage model providers.",
10140
+ "/model Show the active planner/coder model selection.",
10141
+ "/models Discover and select provider models.",
10142
+ "/brains Inspect or assign planner/coder/reviewer brains.",
10143
+ "/doctor Check local environment and config.",
10144
+ "/clear Redraw the shell.",
10145
+ "/quit, /exit Leave the shell.",
10146
+ "",
10147
+ `${color(DIM, "Tip")}`,
10148
+ "Type a natural-language goal directly and Kimbho will treat it as /run <goal>."
10149
+ ].join("\n");
10150
+ }
10151
+ function renderStartupCard(cwd, state) {
10152
+ const cardLines = [
10153
+ `${color(BOLD, "Kimbho CLI")} (v${KIMBHO_VERSION})`,
10154
+ renderCardLine("coder", state.coderModel),
10155
+ renderCardLine("planner", state.plannerModel),
10156
+ renderCardLine("provider", `${state.providerLabel} [${state.providerId}]`),
10157
+ renderCardLine("directory", shortenMiddle(cwd, 78)),
10158
+ renderCardLine("approval", state.approvalMode),
10159
+ renderCardLine("sandbox", state.sandboxMode),
10160
+ renderCardLine("preset", state.stackPreset),
10161
+ renderCardLine("shortcuts", "/help /status /plan /run /models /brains /quit")
10162
+ ];
10163
+ if (!state.configured) {
10164
+ cardLines.push("setup: run /init to create .kimbho/config.json");
10165
+ }
10166
+ return renderBox(cardLines);
10167
+ }
10168
+ function formatPrompt(state) {
10169
+ const coderModel = state.coderModel === "not set" ? "unconfigured" : shortenMiddle(state.coderModel, 18);
10170
+ return `${color(AMBER, "kimbho")} ${color(DIM, `[${coderModel}]`)} > `;
10171
+ }
10172
+ function printHeader(cwd, state) {
10173
+ console.log(renderBanner());
10174
+ console.log(color(DIM, "Terminal-native coding agent"));
10175
+ console.log(renderStartupCard(cwd, state));
10176
+ console.log("");
10177
+ console.log(color(DIM, "Tip: describe the app or repo change you want, and Kimbho will route it into /run."));
10178
+ console.log(renderHelp());
10179
+ console.log("");
10180
+ }
10181
+ function tokenizeInput(input) {
10182
+ const tokens = [];
10183
+ let current = "";
10184
+ let quote = null;
10185
+ let escaping = false;
10186
+ for (const character of input) {
10187
+ if (escaping) {
10188
+ current += character;
10189
+ escaping = false;
10190
+ continue;
10191
+ }
10192
+ if (character === "\\") {
10193
+ escaping = true;
10194
+ continue;
10195
+ }
10196
+ if (quote) {
10197
+ if (character === quote) {
10198
+ quote = null;
10199
+ } else {
10200
+ current += character;
10201
+ }
10202
+ continue;
10203
+ }
10204
+ if (character === "'" || character === '"') {
10205
+ quote = character;
10206
+ continue;
10207
+ }
10208
+ if (/\s/.test(character)) {
10209
+ if (current) {
10210
+ tokens.push(current);
10211
+ current = "";
10212
+ }
10213
+ continue;
10214
+ }
10215
+ current += character;
10216
+ }
10217
+ if (quote) {
10218
+ throw new Error(`Unterminated ${quote === '"' ? "double" : "single"} quote.`);
10219
+ }
10220
+ if (escaping) {
10221
+ current += "\\";
9978
10222
  }
10223
+ if (current) {
10224
+ tokens.push(current);
10225
+ }
10226
+ return tokens;
10227
+ }
10228
+ function toCommandTokens(input) {
10229
+ const trimmed = input.trim();
10230
+ if (!trimmed) {
10231
+ return [];
10232
+ }
10233
+ const normalizedInput = trimmed.startsWith("kimbho ") ? trimmed.slice("kimbho ".length).trim() : trimmed;
10234
+ const tokens = tokenizeInput(normalizedInput);
10235
+ if (tokens.length === 0) {
10236
+ return [];
10237
+ }
10238
+ const firstToken = tokens[0];
10239
+ if (!firstToken) {
10240
+ return [];
10241
+ }
10242
+ const head = firstToken.startsWith("/") ? firstToken.slice(1) : firstToken;
10243
+ if (head === "new") {
10244
+ return [
10245
+ "run",
10246
+ normalizedInput.replace(/^\/?new\s+/, "")
10247
+ ];
10248
+ }
10249
+ if (head === "scaffold") {
10250
+ const goal = normalizedInput.replace(/^\/?scaffold\s+/, "");
10251
+ return [
10252
+ "run",
10253
+ `scaffold ${goal}`.trim()
10254
+ ];
10255
+ }
10256
+ if (head === "model") {
10257
+ return [
10258
+ "brains",
10259
+ "list"
10260
+ ];
10261
+ }
10262
+ if (!firstToken.startsWith("/") && !TOP_LEVEL_COMMANDS.has(head) && !head.startsWith("-")) {
10263
+ return [
10264
+ "run",
10265
+ normalizedInput
10266
+ ];
10267
+ }
10268
+ tokens[0] = head;
10269
+ return tokens;
10270
+ }
10271
+ async function runInteractiveShell(options) {
10272
+ const readline = (0, import_promises6.createInterface)({
10273
+ input: import_node_process9.default.stdin,
10274
+ output: import_node_process9.default.stdout,
10275
+ terminal: Boolean(import_node_process9.default.stdin.isTTY && import_node_process9.default.stdout.isTTY)
10276
+ });
10277
+ let closed = false;
10278
+ readline.on("SIGINT", () => {
10279
+ closed = true;
10280
+ readline.close();
10281
+ });
10282
+ let state = await getShellSessionState(options.cwd);
10283
+ printHeader(options.cwd, state);
10284
+ while (!closed) {
10285
+ let line;
10286
+ try {
10287
+ state = await getShellSessionState(options.cwd);
10288
+ line = await readline.question(formatPrompt(state));
10289
+ } catch {
10290
+ break;
10291
+ }
10292
+ const trimmed = line.trim();
10293
+ if (!trimmed) {
10294
+ continue;
10295
+ }
10296
+ if (trimmed === "/exit" || trimmed === "exit" || trimmed === "quit" || trimmed === "/quit") {
10297
+ closed = true;
10298
+ break;
10299
+ }
10300
+ if (trimmed === "/help" || trimmed === "help" || trimmed === "?") {
10301
+ console.log(renderHelp());
10302
+ console.log("");
10303
+ continue;
10304
+ }
10305
+ if (trimmed === "/status" || trimmed === "status") {
10306
+ state = await getShellSessionState(options.cwd);
10307
+ console.log(renderStartupCard(options.cwd, state));
10308
+ console.log("");
10309
+ continue;
10310
+ }
10311
+ if (trimmed === "/clear" || trimmed === "clear") {
10312
+ if (import_node_process9.default.stdout.isTTY) {
10313
+ import_node_process9.default.stdout.write("\x1Bc");
10314
+ }
10315
+ state = await getShellSessionState(options.cwd);
10316
+ printHeader(options.cwd, state);
10317
+ continue;
10318
+ }
10319
+ try {
10320
+ const tokens = toCommandTokens(trimmed);
10321
+ if (tokens.length === 0) {
10322
+ continue;
10323
+ }
10324
+ await options.execute(tokens);
10325
+ } catch (error) {
10326
+ const message = error instanceof Error ? error.message : String(error);
10327
+ console.error(message);
10328
+ } finally {
10329
+ import_node_process9.default.exitCode = 0;
10330
+ }
10331
+ if (!closed) {
10332
+ console.log("");
10333
+ }
10334
+ }
10335
+ readline.close();
10336
+ import_node_process9.default.exitCode = 0;
10337
+ console.log(color(DIM, "Leaving Kimbho."));
10338
+ }
10339
+
10340
+ // src/index.ts
10341
+ async function dispatchCliTokens(tokens) {
10342
+ const program2 = createProgram();
10343
+ program2.exitOverride();
10344
+ try {
10345
+ await program2.parseAsync([
10346
+ "node",
10347
+ "kimbho",
10348
+ ...normalizeCliTokens(tokens)
10349
+ ]);
10350
+ } catch (error) {
10351
+ if (error instanceof CommanderError) {
10352
+ return;
10353
+ }
10354
+ throw error;
10355
+ }
10356
+ }
10357
+ async function openShell() {
10358
+ await runInteractiveShell({
10359
+ cwd: process.cwd(),
10360
+ execute: dispatchCliTokens
10361
+ });
10362
+ }
10363
+ async function main() {
10364
+ const tokens = normalizeCliTokens(process.argv.slice(2));
10365
+ if (tokens.length === 0) {
10366
+ if (process.stdin.isTTY && process.stdout.isTTY) {
10367
+ await openShell();
10368
+ return;
10369
+ }
10370
+ const helpProgram = createProgram(openShell);
10371
+ await helpProgram.parseAsync([
10372
+ "node",
10373
+ "kimbho",
10374
+ "--help"
10375
+ ]);
10376
+ return;
10377
+ }
10378
+ const program2 = createProgram(openShell);
10379
+ await program2.parseAsync([
10380
+ "node",
10381
+ "kimbho",
10382
+ ...tokens
10383
+ ]);
9979
10384
  }
9980
- program2.parseAsync(normalizedArgv).catch((error) => {
10385
+ main().catch((error) => {
9981
10386
  const message = error instanceof Error ? error.message : String(error);
9982
10387
  console.error(message);
9983
10388
  process.exitCode = 1;