@kolisachint/hoocode-agent 0.5.56 → 0.5.57

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.
Files changed (76) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/core/keybindings.d.ts +2 -12
  3. package/dist/core/keybindings.d.ts.map +1 -1
  4. package/dist/core/keybindings.js +5 -16
  5. package/dist/core/keybindings.js.map +1 -1
  6. package/dist/core/settings-defaults.d.ts +1 -1
  7. package/dist/core/settings-defaults.d.ts.map +1 -1
  8. package/dist/core/settings-defaults.js +1 -1
  9. package/dist/core/settings-defaults.js.map +1 -1
  10. package/dist/core/settings-manager.d.ts +1 -1
  11. package/dist/core/settings-manager.d.ts.map +1 -1
  12. package/dist/core/settings-manager.js +1 -1
  13. package/dist/core/settings-manager.js.map +1 -1
  14. package/dist/core/settings-types.d.ts +1 -1
  15. package/dist/core/settings-types.d.ts.map +1 -1
  16. package/dist/core/settings-types.js.map +1 -1
  17. package/dist/core/tool-output-view.d.ts +28 -10
  18. package/dist/core/tool-output-view.d.ts.map +1 -1
  19. package/dist/core/tool-output-view.js +24 -9
  20. package/dist/core/tool-output-view.js.map +1 -1
  21. package/dist/core/tools/bash.d.ts.map +1 -1
  22. package/dist/core/tools/bash.js +2 -2
  23. package/dist/core/tools/bash.js.map +1 -1
  24. package/dist/core/tools/plugins.d.ts.map +1 -1
  25. package/dist/core/tools/plugins.js +2 -1
  26. package/dist/core/tools/plugins.js.map +1 -1
  27. package/dist/core/tools/read.d.ts.map +1 -1
  28. package/dist/core/tools/read.js +2 -1
  29. package/dist/core/tools/read.js.map +1 -1
  30. package/dist/core/tools/search.d.ts.map +1 -1
  31. package/dist/core/tools/search.js +2 -1
  32. package/dist/core/tools/search.js.map +1 -1
  33. package/dist/core/tools/webfetch.d.ts.map +1 -1
  34. package/dist/core/tools/webfetch.js +2 -1
  35. package/dist/core/tools/webfetch.js.map +1 -1
  36. package/dist/core/tools/websearch.d.ts.map +1 -1
  37. package/dist/core/tools/websearch.js +2 -1
  38. package/dist/core/tools/websearch.js.map +1 -1
  39. package/dist/core/tools/write.d.ts.map +1 -1
  40. package/dist/core/tools/write.js +2 -1
  41. package/dist/core/tools/write.js.map +1 -1
  42. package/dist/modes/interactive/command-executor.d.ts.map +1 -1
  43. package/dist/modes/interactive/command-executor.js +2 -5
  44. package/dist/modes/interactive/command-executor.js.map +1 -1
  45. package/dist/modes/interactive/components/footer.d.ts +1 -1
  46. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  47. package/dist/modes/interactive/components/footer.js +3 -2
  48. package/dist/modes/interactive/components/footer.js.map +1 -1
  49. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  50. package/dist/modes/interactive/components/settings-selector.js +1 -1
  51. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  52. package/dist/modes/interactive/components/tool-chain-summary.d.ts +2 -1
  53. package/dist/modes/interactive/components/tool-chain-summary.d.ts.map +1 -1
  54. package/dist/modes/interactive/components/tool-chain-summary.js +2 -1
  55. package/dist/modes/interactive/components/tool-chain-summary.js.map +1 -1
  56. package/dist/modes/interactive/components/tool-chain.d.ts +2 -9
  57. package/dist/modes/interactive/components/tool-chain.d.ts.map +1 -1
  58. package/dist/modes/interactive/components/tool-chain.js +3 -20
  59. package/dist/modes/interactive/components/tool-chain.js.map +1 -1
  60. package/dist/modes/interactive/components/tool-execution.d.ts +16 -20
  61. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  62. package/dist/modes/interactive/components/tool-execution.js +38 -37
  63. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  64. package/dist/modes/interactive/components/tool-signal.d.ts.map +1 -1
  65. package/dist/modes/interactive/components/tool-signal.js +1 -1
  66. package/dist/modes/interactive/components/tool-signal.js.map +1 -1
  67. package/dist/modes/interactive/interactive-mode.d.ts +28 -20
  68. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  69. package/dist/modes/interactive/interactive-mode.js +57 -68
  70. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  71. package/docs/keybindings.md +3 -1
  72. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  73. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  74. package/examples/extensions/sandbox/package.json +1 -1
  75. package/examples/extensions/with-deps/package.json +1 -1
  76. package/package.json +4 -4
@@ -31,7 +31,7 @@ import { SessionManager } from "../../core/session-manager.js";
31
31
  import { BUILTIN_SLASH_COMMANDS } from "../../core/slash-commands.js";
32
32
  import { startupProgress } from "../../core/startup-progress.js";
33
33
  import { taskStore } from "../../core/task-store.js";
34
- import { cycleToolOutputView } from "../../core/tool-output-view.js";
34
+ import { cycleToolOutputView, DEFAULT_TOOL_OUTPUT_VIEW, MAX_TOOL_OUTPUT_VIEW, } from "../../core/tool-output-view.js";
35
35
  import { settleDanglingMainTasks } from "../../core/tools/todo.js";
36
36
  import { buildCompactWordmark } from "../../core/wordmark.js";
37
37
  import { extensionForImageMimeType, readClipboardImage } from "../../utils/clipboard-image.js";
@@ -202,10 +202,21 @@ export class InteractiveMode {
202
202
  });
203
203
  // Tool execution tracking: toolCallId -> component
204
204
  pendingTools = new Map();
205
- // Tool output expansion state
206
- toolOutputExpanded = false;
207
- // Persisted view dial (radar / glance / full). See core/tool-output-view.ts.
208
- toolOutputView = "glance";
205
+ // Persisted view dial (radar / peek / full). See core/tool-output-view.ts.
206
+ toolOutputView = DEFAULT_TOOL_OUTPUT_VIEW;
207
+ // Where `app.tools.expand` came from, so the same key goes back there. Kept
208
+ // in memory only: the jump is the momentary look, the dial is the decision.
209
+ viewBeforeJump;
210
+ /**
211
+ * Whether everything foldable is currently open.
212
+ *
213
+ * Not a state of its own any more — it is the top of the view dial. The
214
+ * header, compaction and branch summaries and skill blocks follow the dial
215
+ * for the same reason tool bodies do: `full` means nothing is held back.
216
+ */
217
+ get toolOutputExpanded() {
218
+ return this.toolOutputView === MAX_TOOL_OUTPUT_VIEW;
219
+ }
209
220
  // The chain currently collecting tool calls, if the agent is mid-run.
210
221
  openChain;
211
222
  /** The newest tool block in the transcript; radar marks it. */
@@ -708,9 +719,8 @@ export class InteractiveMode {
708
719
  hint("app.thinking.cycle", "to cycle thinking level"),
709
720
  rawKeyHint(`${keyText("app.model.cycleForward")}/${keyText("app.model.cycleBackward")}`, "to cycle models"),
710
721
  hint("app.model.select", "to select model"),
711
- hint("app.tools.expand", "to expand all tool output"),
712
- hint("app.tools.unfoldOne", "to open one chain or block (repeat to peel back)"),
713
- hint("app.view.cycleForward", "to cycle tool output (radar/glance/full)"),
722
+ hint("app.tools.expand", "to jump to full output and back"),
723
+ hint("app.view.cycleForward", "to cycle tool output (radar/peek/full)"),
714
724
  hint("app.thinking.toggle", "to expand thinking"),
715
725
  hint("app.tasks.cycleView", "to cycle task panel view"),
716
726
  ...(this.teamFocus.connected ? [hint("app.team.focus", "to focus team roster")] : []),
@@ -1506,11 +1516,9 @@ export class InteractiveMode {
1506
1516
  // Global debug handler on TUI (works regardless of focus)
1507
1517
  this.ui.onDebug = () => this.commandExecutor.handleDebug();
1508
1518
  this.defaultEditor.onAction("app.model.select", () => this.modelController.showModelSelector());
1509
- this.defaultEditor.onAction("app.tools.expand", () => this.toggleToolOutputExpansion());
1519
+ this.defaultEditor.onAction("app.tools.expand", () => this.jumpToFullView());
1510
1520
  this.defaultEditor.onAction("app.view.cycleForward", () => this.cycleToolOutputView("forward"));
1511
1521
  this.defaultEditor.onAction("app.view.cycleBackward", () => this.cycleToolOutputView("backward"));
1512
- this.defaultEditor.onAction("app.tools.unfoldOne", () => this.stepToolOutput("unfold"));
1513
- this.defaultEditor.onAction("app.tools.foldOne", () => this.stepToolOutput("fold"));
1514
1522
  this.defaultEditor.onAction("app.thinking.toggle", () => this.toggleThinkingBlockVisibility());
1515
1523
  this.defaultEditor.onAction("app.tasks.cycleView", () => {
1516
1524
  this.taskPanel.cycleView();
@@ -2022,7 +2030,6 @@ export class InteractiveMode {
2022
2030
  imageWidthCells: this.settingsManager.getImageWidthCells(),
2023
2031
  view: this.toolOutputView,
2024
2032
  }, this.getRegisteredToolDefinition(content.name), this.ui, this.sessionManager.getCwd());
2025
- component.setExpanded(this.toolOutputExpanded);
2026
2033
  this.attachToolBlock(component);
2027
2034
  this.pendingTools.set(content.id, component);
2028
2035
  }
@@ -2089,7 +2096,6 @@ export class InteractiveMode {
2089
2096
  imageWidthCells: this.settingsManager.getImageWidthCells(),
2090
2097
  view: this.toolOutputView,
2091
2098
  }, this.getRegisteredToolDefinition(event.toolName), this.ui, this.sessionManager.getCwd());
2092
- component.setExpanded(this.toolOutputExpanded);
2093
2099
  this.attachToolBlock(component);
2094
2100
  this.pendingTools.set(event.toolCallId, component);
2095
2101
  }
@@ -2388,7 +2394,6 @@ export class InteractiveMode {
2388
2394
  imageWidthCells: this.settingsManager.getImageWidthCells(),
2389
2395
  view: this.toolOutputView,
2390
2396
  }, this.getRegisteredToolDefinition(content.name), this.ui, this.sessionManager.getCwd());
2391
- component.setExpanded(this.toolOutputExpanded);
2392
2397
  this.attachToolBlock(component);
2393
2398
  if (message.stopReason === "aborted" || message.stopReason === "error") {
2394
2399
  let errorMessage;
@@ -2714,66 +2719,35 @@ export class InteractiveMode {
2714
2719
  }
2715
2720
  return blocks;
2716
2721
  }
2717
- /** Every chain in the transcript, in order. */
2718
- transcriptChains() {
2719
- return this.chatContainer.children.filter((child) => child instanceof ToolChainComponent);
2720
- }
2721
- toggleToolOutputExpansion() {
2722
- this.setToolsExpanded(!this.toolOutputExpanded);
2723
- }
2724
2722
  /**
2725
- * Open or close one tool block instead of all of them.
2723
+ * Jump to the full view, or back to where the jump started.
2726
2724
  *
2727
- * `ctrl+o` is all-or-nothing, which left the caret on every glance and
2728
- * radar row advertising something no key could do. This is the missing half:
2729
- * unfold walks back from the newest block to the first one still folded,
2730
- * fold walks back to the most recently opened one.
2725
+ * The dial's top stop is the whole result with nothing trimmed, which is what
2726
+ * "expand" always meant so expand is not a second state layered over the
2727
+ * dial any more, it is a jump along it. From any stop the first press lands
2728
+ * on `full`; the next press returns to the stop you came from (`peek` if the
2729
+ * jump started there, so the key is never a no-op).
2731
2730
  *
2732
- * Working from the tail is not a shortcut, it is the only thing this view can
2733
- * honestly offer. The transcript is bottom-anchored and has no app-level
2734
- * scrolling — anything far enough up is in the terminal's own scrollback,
2735
- * where this process cannot put a cursor or scroll to a selection. So the
2736
- * key peels backwards through what is actually on screen, and each block it
2737
- * opens is its own marker for where you have got to.
2731
+ * Only `app.view.cycleForward` writes the setting. This key deliberately does
2732
+ * not: the dial is the decision you keep, the jump is the look you take.
2738
2733
  */
2739
- stepToolOutput(direction) {
2740
- const wantOpen = direction === "unfold";
2741
- // Radar's unit is the chain: one press turns the newest summary line back
2742
- // into the calls it stands for. Its per-call bodies are a glance/full
2743
- // question, so the step stops there rather than cascading.
2744
- if (this.toolOutputView === "radar") {
2745
- const chains = this.transcriptChains();
2746
- for (let i = chains.length - 1; i >= 0; i--) {
2747
- if (chains[i].isEmpty || chains[i].isOpened === wantOpen)
2748
- continue;
2749
- // A chain of one is never summarised, so there is nothing for unfold to
2750
- // reveal; skipping it keeps the press moving to a chain that will change.
2751
- if (wantOpen && !chains[i].isSummarised)
2752
- continue;
2753
- chains[i].setOpened(wantOpen);
2754
- this.ui.requestRender();
2755
- return;
2756
- }
2757
- this.showStatus(wantOpen ? "No collapsed chains below this point" : "No open chains below this point");
2758
- return;
2759
- }
2760
- const blocks = this.transcriptToolBlocks();
2761
- for (let i = blocks.length - 1; i >= 0; i--) {
2762
- const block = blocks[i];
2763
- if (block.isRevealed() === wantOpen)
2764
- continue;
2765
- block.setExpanded(wantOpen);
2766
- this.ui.requestRender();
2734
+ jumpToFullView() {
2735
+ if (this.toolOutputView === MAX_TOOL_OUTPUT_VIEW) {
2736
+ const back = this.viewBeforeJump ?? DEFAULT_TOOL_OUTPUT_VIEW;
2737
+ this.viewBeforeJump = undefined;
2738
+ this.applyToolOutputView(back, { persist: false });
2767
2739
  return;
2768
2740
  }
2769
- this.showStatus(wantOpen ? "No folded tool output below this point" : "No unfolded tool output below this point");
2741
+ this.viewBeforeJump = this.toolOutputView;
2742
+ this.applyToolOutputView(MAX_TOOL_OUTPUT_VIEW, { persist: false });
2770
2743
  }
2771
2744
  /**
2772
- * Move the view dial one stop and report where it landed.
2745
+ * Move the view dial one stop; the footer shows where it landed.
2773
2746
  *
2774
- * The dial is the persistent decision ("how much do I ever want to see"),
2775
- * which is why it saves; `app.tools.expand` stays the momentary one ("open
2776
- * what is in front of me"), which is why it does not.
2747
+ * This is the persistent decision ("how much do I ever want to see"), which
2748
+ * is why it saves. `app.tools.expand` jumps along the same dial without
2749
+ * saving, which is what keeps "the look I am taking now" from overwriting
2750
+ * "the view I live in".
2777
2751
  */
2778
2752
  cycleToolOutputView(direction) {
2779
2753
  const next = cycleToolOutputView(this.toolOutputView, direction);
@@ -2802,10 +2776,17 @@ export class InteractiveMode {
2802
2776
  return "omit";
2803
2777
  return this.hideThinkingBlock ? "label" : "full";
2804
2778
  }
2805
- applyToolOutputView(view) {
2779
+ applyToolOutputView(view, options = {}) {
2806
2780
  const previousThinking = this.thinkingDisplayForView();
2781
+ const wasExpanded = this.toolOutputExpanded;
2807
2782
  this.toolOutputView = view;
2808
- this.settingsManager.setToolOutputView(view);
2783
+ if (options.persist !== false) {
2784
+ this.settingsManager.setToolOutputView(view);
2785
+ // Anything that moves the dial deliberately — the cycle key, the
2786
+ // settings pane — is a new home stop, so the jump has nowhere stale to
2787
+ // return to.
2788
+ this.viewBeforeJump = undefined;
2789
+ }
2809
2790
  this.footer.setToolOutputView(view);
2810
2791
  const thinking = this.thinkingDisplayForView();
2811
2792
  for (const child of this.chatContainer.children) {
@@ -2820,10 +2801,18 @@ export class InteractiveMode {
2820
2801
  if (this.streamingComponent && thinking !== previousThinking) {
2821
2802
  this.streamingComponent.setThinkingDisplay(thinking);
2822
2803
  }
2804
+ // The header and the summary blocks are not tool output, but "full" means
2805
+ // nothing is held back, so they open and close with the dial's top stop.
2806
+ if (this.toolOutputExpanded !== wasExpanded)
2807
+ this.setToolsExpanded(this.toolOutputExpanded);
2823
2808
  this.ui.requestRender();
2824
2809
  }
2810
+ /**
2811
+ * Open or close everything that folds but is not a tool call — the header,
2812
+ * compaction and branch summaries, skill blocks. Tool blocks and chains are
2813
+ * not in this sweep: they take the view dial directly.
2814
+ */
2825
2815
  setToolsExpanded(expanded) {
2826
- this.toolOutputExpanded = expanded;
2827
2816
  const activeHeader = this.chrome.customHeader ?? this.builtInHeader;
2828
2817
  if (isExpandable(activeHeader)) {
2829
2818
  activeHeader.setExpanded(expanded);