@kimbho/kimbho-cli 0.1.23 → 0.1.25

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 CHANGED
@@ -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.23",
12721
+ version: "0.1.25",
12722
12722
  description: "Kimbho CLI is a terminal-native coding agent for planning, execution, and verification.",
12723
12723
  type: "module",
12724
12724
  engines: {
@@ -24540,7 +24540,8 @@ async function runShellCommand(toolId, command, cwd, timeoutMs, signal) {
24540
24540
  command
24541
24541
  ], cwd, timeoutMs, signal);
24542
24542
  const success2 = !result.timedOut && result.code === 0;
24543
- const summary = result.timedOut ? `Command timed out after ${timeoutMs}ms.` : success2 ? `Command completed successfully.` : `Command exited with code ${result.code ?? "unknown"}.`;
24543
+ const interactiveSetupSummary = !success2 ? detectInteractiveShellPrompt(command, result.stdout, result.stderr) : null;
24544
+ const summary = result.timedOut ? `Command timed out after ${timeoutMs}ms.` : interactiveSetupSummary ? interactiveSetupSummary : success2 ? `Command completed successfully.` : `Command exited with code ${result.code ?? "unknown"}.`;
24544
24545
  return ToolResultSchema.parse({
24545
24546
  toolId,
24546
24547
  success: success2,
@@ -24549,6 +24550,18 @@ async function runShellCommand(toolId, command, cwd, timeoutMs, signal) {
24549
24550
  stderr: truncateOutput(result.stderr)
24550
24551
  });
24551
24552
  }
24553
+ function detectInteractiveShellPrompt(command, stdout, stderr) {
24554
+ const combined = `${stdout}
24555
+ ${stderr}`;
24556
+ const normalizedCommand = command.trim().toLowerCase();
24557
+ if (/how would you like to configure eslint\?/i.test(combined) || normalizedCommand.includes("next lint") && /eslint/i.test(combined) && /(strict \(recommended\)|base|cancel)/i.test(combined)) {
24558
+ return "Interactive ESLint setup required before next lint can run.";
24559
+ }
24560
+ if (/\?\s+[^\n]+\n(?:\s*❯|\s*>|\s*\*)/i.test(combined) || /(would you like to|choose one of the following|select an option|enter a value)/i.test(combined)) {
24561
+ return "Command requires interactive input before it can continue.";
24562
+ }
24563
+ return null;
24564
+ }
24552
24565
  async function executeFileRead(input, context) {
24553
24566
  if (context.signal?.aborted) {
24554
24567
  const error2 = new Error("Tool execution aborted.");
@@ -33108,6 +33121,24 @@ function isVerificationAction(action) {
33108
33121
  const command = typeof action.input.command === "string" ? action.input.command : "";
33109
33122
  return command.length > 0 && isVerificationCommand(command);
33110
33123
  }
33124
+ function extractShellCommand(action) {
33125
+ if (action.type !== "tool" || action.tool !== "shell.exec") {
33126
+ return "";
33127
+ }
33128
+ return typeof action.input.command === "string" ? action.input.command.trim() : "";
33129
+ }
33130
+ function isInteractiveVerificationSetupFailure(action, result) {
33131
+ if (!isVerificationAction(action) || result.success) {
33132
+ return false;
33133
+ }
33134
+ const command = extractShellCommand(action).toLowerCase();
33135
+ const combined = [
33136
+ result.summary,
33137
+ result.stdout ?? "",
33138
+ result.stderr ?? ""
33139
+ ].join("\n").toLowerCase();
33140
+ return combined.includes("interactive eslint setup required") || combined.includes("command requires interactive input before it can continue") || command.includes("lint") && combined.includes("how would you like to configure eslint");
33141
+ }
33111
33142
  function buildSystemPrompt(agent, task, request, allowedTools, plan, extraInstructions) {
33112
33143
  const toolShape = allowedTools.join("|");
33113
33144
  const dependencyTasks = plan ? flattenPlanTasks(plan).filter((candidate) => task.dependsOn.includes(candidate.id)) : [];
@@ -33150,6 +33181,7 @@ function buildSystemPrompt(agent, task, request, allowedTools, plan, extraInstru
33150
33181
  `- Keep paths relative to the workspace.`,
33151
33182
  `- In an existing repo, inspect and change the likely source files before running build or test verification. Do not front-load verification unless you are confirming an already-completed change or diagnosing a failure.`,
33152
33183
  `- After changing code, run verification with tests.run or shell.exec when appropriate.`,
33184
+ `- If a verification command asks for interactive setup or operator input, do not rerun it unchanged. Choose a different non-interactive verifier, or configure that verifier only if the task explicitly requires it.`,
33153
33185
  `- Do not claim success unless the task acceptance criteria are satisfied.`,
33154
33186
  `- If the task is underspecified, make a pragmatic implementation choice and continue.`,
33155
33187
  ...task.subagentInstructions ? [
@@ -33820,6 +33852,7 @@ ${truncateForModel(customAgentMemory)}`);
33820
33852
  const applyToolResult = async (parsedAction, result, step, transcriptEntry) => {
33821
33853
  const mutatingAction = isMutatingAction(parsedAction);
33822
33854
  const verificationAction = isVerificationAction(parsedAction);
33855
+ const interactiveVerificationSetupFailure = verificationAction && !result.success && isInteractiveVerificationSetupFailure(parsedAction, result);
33823
33856
  if (mutatingAction && result.success) {
33824
33857
  changedWorkspace = true;
33825
33858
  verifiedAfterLatestChange = false;
@@ -33834,6 +33867,10 @@ ${truncateForModel(customAgentMemory)}`);
33834
33867
  repairRequiredBeforeVerification = false;
33835
33868
  repairAppliedSinceFailure = false;
33836
33869
  lastVerificationFailure = null;
33870
+ } else if (interactiveVerificationSetupFailure) {
33871
+ repairRequiredBeforeVerification = false;
33872
+ repairAppliedSinceFailure = false;
33873
+ lastVerificationFailure = result;
33837
33874
  } else {
33838
33875
  verificationFailures += 1;
33839
33876
  repairRequiredBeforeVerification = true;
@@ -33853,9 +33890,25 @@ ${truncateForModel(customAgentMemory)}`);
33853
33890
  if (mutatingAction && result.success) {
33854
33891
  followUp.push("Code or workspace state changed. Inspect the diff if needed and run verification before finishing.");
33855
33892
  }
33856
- if (verificationAction && !result.success) {
33893
+ if (verificationAction && interactiveVerificationSetupFailure) {
33894
+ const failureSummary = `${result.toolId}: ${result.summary}`;
33895
+ transcriptEntry.runtimeNote = [
33896
+ `Verification could not run non-interactively. Latest failure: ${failureSummary}`,
33897
+ "Executor should choose a different non-interactive verifier or configure the verifier explicitly."
33898
+ ].join(" ");
33899
+ await emitProgress({
33900
+ type: "task-note",
33901
+ sessionId,
33902
+ taskId: task.id,
33903
+ agentRole: task.agentRole,
33904
+ step,
33905
+ message: `Verification needs setup via ${failureSummary}. Choosing a different non-interactive verifier or configuration path.`
33906
+ });
33907
+ followUp.push(`The attempted verification was not a code failure. It requires interactive setup or input (${failureSummary}). Do not rerun the same verifier unchanged. Choose a different non-interactive verification command, or configure the verifier explicitly if the task requires it.`);
33908
+ } else if (verificationAction && !result.success) {
33909
+ const failureSummary = `${result.toolId}: ${result.summary}`;
33857
33910
  transcriptEntry.runtimeNote = [
33858
- `Verification failed (${verificationFailures}/${maxRepairAttempts} repair attempts used).`,
33911
+ `Verification failed (${verificationFailures}/${maxRepairAttempts} repair attempts used). Latest failure: ${failureSummary}`,
33859
33912
  "Executor requires a repair action before the next verification run."
33860
33913
  ].join(" ");
33861
33914
  await emitProgress({
@@ -33864,9 +33917,9 @@ ${truncateForModel(customAgentMemory)}`);
33864
33917
  taskId: task.id,
33865
33918
  agentRole: task.agentRole,
33866
33919
  step,
33867
- message: `Verification failed. Repair attempts used: ${verificationFailures}/${maxRepairAttempts}.`
33920
+ message: `Verification failed via ${failureSummary}. Repair attempts used: ${verificationFailures}/${maxRepairAttempts}.`
33868
33921
  });
33869
- followUp.push(`Verification failed. Inspect the failure output, repair the issue, and run verification again before finishing. Repair attempts used: ${verificationFailures}/${maxRepairAttempts}.`);
33922
+ followUp.push(`Verification failed via ${failureSummary}. Inspect the failure output, repair the issue, and run verification again before finishing. Repair attempts used: ${verificationFailures}/${maxRepairAttempts}.`);
33870
33923
  if (verificationFailures >= maxRepairAttempts) {
33871
33924
  transcriptEntry.runtimeNote = [
33872
33925
  transcriptEntry.runtimeNote,
@@ -43930,6 +43983,14 @@ var SPINNER_FRAMES = [
43930
43983
  "|",
43931
43984
  "/"
43932
43985
  ];
43986
+ var ELLIPSIS_FRAMES = [
43987
+ ". ",
43988
+ ".. ",
43989
+ "...",
43990
+ " ..",
43991
+ " .",
43992
+ " "
43993
+ ];
43933
43994
  var IDLE_STATUS_LABELS = [
43934
43995
  "thinking",
43935
43996
  "musing",
@@ -44170,7 +44231,7 @@ function createExecutionTelemetry() {
44170
44231
  }
44171
44232
  var ShellActivityIndicator = class {
44172
44233
  interval = null;
44173
- frameIndex = 0;
44234
+ animationTick = 0;
44174
44235
  label;
44175
44236
  activeLine = false;
44176
44237
  constructor(label) {
@@ -44183,14 +44244,14 @@ var ShellActivityIndicator = class {
44183
44244
  this.activeLine = true;
44184
44245
  this.render();
44185
44246
  this.interval = setInterval(() => {
44186
- this.frameIndex = (this.frameIndex + 1) % SPINNER_FRAMES.length;
44247
+ this.animationTick += 1;
44187
44248
  this.render();
44188
- }, 120);
44249
+ }, 140);
44189
44250
  this.interval.unref?.();
44190
44251
  }
44191
44252
  update(label) {
44192
44253
  if (label !== this.label) {
44193
- this.frameIndex = 0;
44254
+ this.animationTick = 0;
44194
44255
  }
44195
44256
  this.label = label;
44196
44257
  if (this.interval) {
@@ -44221,9 +44282,10 @@ var ShellActivityIndicator = class {
44221
44282
  if (!import_node_process26.default.stdout.isTTY) {
44222
44283
  return;
44223
44284
  }
44224
- const frame = color(AMBER, SPINNER_FRAMES[this.frameIndex]);
44225
- const status = renderShimmeringLabel(this.label, this.frameIndex);
44226
- const raw = `${frame} ${status}${color(DIM, "...")}`;
44285
+ const frame = color(AMBER, SPINNER_FRAMES[this.animationTick % SPINNER_FRAMES.length]);
44286
+ const status = renderShimmeringLabel(this.label, this.animationTick);
44287
+ const dots = color(DIM, ELLIPSIS_FRAMES[this.animationTick % ELLIPSIS_FRAMES.length]);
44288
+ const raw = `${frame} ${status}${dots}`;
44227
44289
  this.clear();
44228
44290
  (0, import_node_readline2.cursorTo)(import_node_process26.default.stdout, 0);
44229
44291
  import_node_process26.default.stdout.write(raw);
@@ -44532,6 +44594,27 @@ function hashString(value) {
44532
44594
  function pickStatusLabel(message) {
44533
44595
  const lower = message.toLowerCase();
44534
44596
  const choose = (labels) => labels[hashString(message) % labels.length];
44597
+ if (lower.includes("verification needs setup") || lower.includes("different non-interactive verifier")) {
44598
+ return choose([
44599
+ "adapting",
44600
+ "rerouting",
44601
+ "recovering"
44602
+ ]);
44603
+ }
44604
+ if (lower.includes("verification failed") || lower.includes("repair attempts used")) {
44605
+ return choose([
44606
+ "repairing",
44607
+ "debugging",
44608
+ "recovering"
44609
+ ]);
44610
+ }
44611
+ if (lower.includes("repair budget exhausted") || lower.includes("debugger escalation")) {
44612
+ return choose([
44613
+ "escalating",
44614
+ "stopping",
44615
+ "blocking"
44616
+ ]);
44617
+ }
44535
44618
  if (lower.includes("synthesizing") || lower.includes("architecture brief")) {
44536
44619
  return choose([
44537
44620
  "planning",
@@ -44581,6 +44664,13 @@ function pickStatusLabel(message) {
44581
44664
  "untangling"
44582
44665
  ]);
44583
44666
  }
44667
+ if (lower.includes("verify") || lower.includes("verification")) {
44668
+ return choose([
44669
+ "verifying",
44670
+ "checking",
44671
+ "confirming"
44672
+ ]);
44673
+ }
44584
44674
  return choose([
44585
44675
  "thinking",
44586
44676
  "musing",