@kolisachint/hoocode-agent 0.4.107 → 0.4.109

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 (77) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/core/agent-session-compaction.d.ts +79 -0
  3. package/dist/core/agent-session-compaction.d.ts.map +1 -0
  4. package/dist/core/agent-session-compaction.js +346 -0
  5. package/dist/core/agent-session-compaction.js.map +1 -0
  6. package/dist/core/agent-session-retry.d.ts +76 -0
  7. package/dist/core/agent-session-retry.d.ts.map +1 -0
  8. package/dist/core/agent-session-retry.js +192 -0
  9. package/dist/core/agent-session-retry.js.map +1 -0
  10. package/dist/core/agent-session-skills.d.ts +34 -0
  11. package/dist/core/agent-session-skills.d.ts.map +1 -0
  12. package/dist/core/agent-session-skills.js +52 -0
  13. package/dist/core/agent-session-skills.js.map +1 -0
  14. package/dist/core/agent-session-stats.d.ts +74 -0
  15. package/dist/core/agent-session-stats.d.ts.map +1 -0
  16. package/dist/core/agent-session-stats.js +187 -0
  17. package/dist/core/agent-session-stats.js.map +1 -0
  18. package/dist/core/agent-session-tree-navigation.d.ts +69 -0
  19. package/dist/core/agent-session-tree-navigation.d.ts.map +1 -0
  20. package/dist/core/agent-session-tree-navigation.js +198 -0
  21. package/dist/core/agent-session-tree-navigation.js.map +1 -0
  22. package/dist/core/agent-session.d.ts +10 -66
  23. package/dist/core/agent-session.d.ts.map +1 -1
  24. package/dist/core/agent-session.js +96 -806
  25. package/dist/core/agent-session.js.map +1 -1
  26. package/dist/core/context-files.d.ts +25 -0
  27. package/dist/core/context-files.d.ts.map +1 -0
  28. package/dist/core/context-files.js +97 -0
  29. package/dist/core/context-files.js.map +1 -0
  30. package/dist/core/package-manager.d.ts.map +1 -1
  31. package/dist/core/package-manager.js +3 -519
  32. package/dist/core/package-manager.js.map +1 -1
  33. package/dist/core/package-resource-discovery.d.ts +62 -0
  34. package/dist/core/package-resource-discovery.d.ts.map +1 -0
  35. package/dist/core/package-resource-discovery.js +530 -0
  36. package/dist/core/package-resource-discovery.js.map +1 -0
  37. package/dist/core/resource-loader.d.ts +1 -10
  38. package/dist/core/resource-loader.d.ts.map +1 -1
  39. package/dist/core/resource-loader.js +4 -83
  40. package/dist/core/resource-loader.js.map +1 -1
  41. package/dist/core/settings-manager.d.ts +5 -140
  42. package/dist/core/settings-manager.d.ts.map +1 -1
  43. package/dist/core/settings-manager.js +4 -81
  44. package/dist/core/settings-manager.js.map +1 -1
  45. package/dist/core/settings-storage.d.ts +29 -0
  46. package/dist/core/settings-storage.d.ts.map +1 -0
  47. package/dist/core/settings-storage.js +90 -0
  48. package/dist/core/settings-storage.js.map +1 -0
  49. package/dist/core/settings-types.d.ts +128 -0
  50. package/dist/core/settings-types.d.ts.map +1 -0
  51. package/dist/core/settings-types.js +9 -0
  52. package/dist/core/settings-types.js.map +1 -0
  53. package/dist/modes/interactive/bash-execution-controller.d.ts +34 -0
  54. package/dist/modes/interactive/bash-execution-controller.d.ts.map +1 -0
  55. package/dist/modes/interactive/bash-execution-controller.js +98 -0
  56. package/dist/modes/interactive/bash-execution-controller.js.map +1 -0
  57. package/dist/modes/interactive/interactive-mode.d.ts +5 -45
  58. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  59. package/dist/modes/interactive/interactive-mode.js +91 -779
  60. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  61. package/dist/modes/interactive/login-controller.d.ts +50 -0
  62. package/dist/modes/interactive/login-controller.d.ts.map +1 -0
  63. package/dist/modes/interactive/login-controller.js +352 -0
  64. package/dist/modes/interactive/login-controller.js.map +1 -0
  65. package/dist/modes/interactive/message-queue-controller.d.ts +49 -0
  66. package/dist/modes/interactive/message-queue-controller.d.ts.map +1 -0
  67. package/dist/modes/interactive/message-queue-controller.js +184 -0
  68. package/dist/modes/interactive/message-queue-controller.js.map +1 -0
  69. package/dist/modes/interactive/model-controller.d.ts +43 -0
  70. package/dist/modes/interactive/model-controller.d.ts.map +1 -0
  71. package/dist/modes/interactive/model-controller.js +184 -0
  72. package/dist/modes/interactive/model-controller.js.map +1 -0
  73. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  74. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  75. package/examples/extensions/sandbox/package.json +1 -1
  76. package/examples/extensions/with-deps/package.json +1 -1
  77. package/package.json +4 -4
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-types.d.ts","sourceRoot":"","sources":["../../src/core/settings-types.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Settings schema shared across the app.\n *\n * The `Settings` interface and its nested option groups describe the on-disk\n * global/project settings.json shape. Extracted from settings-manager.ts so the\n * schema can be imported without pulling in the manager implementation.\n */\n\nimport type { Transport } from \"@kolisachint/hoocode-ai\";\n\nexport interface CompactionSettings {\n\tenabled?: boolean; // default: true\n\treserveTokens?: number; // default: 16384\n\tkeepRecentTokens?: number; // default: 20000\n}\n\nexport interface BranchSummarySettings {\n\treserveTokens?: number; // default: 16384 (tokens reserved for prompt + LLM response)\n\tskipPrompt?: boolean; // default: false - when true, skips \"Summarize branch?\" prompt and defaults to no summary\n}\n\nexport interface ProviderRetrySettings {\n\ttimeoutMs?: number; // SDK/provider request timeout in milliseconds\n\tmaxRetries?: number; // SDK/provider retry attempts\n\tmaxRetryDelayMs?: number; // default: 60000 (max server-requested delay before failing)\n}\n\nexport interface RetrySettings {\n\tenabled?: boolean; // default: true\n\tmaxRetries?: number; // default: 3\n\tbaseDelayMs?: number; // default: 2000 (exponential backoff: 2s, 4s, 8s)\n\tprovider?: ProviderRetrySettings;\n}\n\nexport interface TerminalSettings {\n\tshowImages?: boolean; // default: true (only relevant if terminal supports images)\n\timageWidthCells?: number; // default: 60 (preferred inline image width in terminal cells)\n\tclearOnShrink?: boolean; // default: false (clear empty rows when content shrinks)\n\tshowTerminalProgress?: boolean; // default: false (OSC 9;4 terminal progress indicators)\n}\n\nexport interface ImageSettings {\n\tautoResize?: boolean; // default: true (resize images to 2000x2000 max for better model compatibility)\n\tblockImages?: boolean; // default: false - when true, prevents all images from being sent to LLM providers\n}\n\nexport interface ThinkingBudgetsSettings {\n\tminimal?: number;\n\tlow?: number;\n\tmedium?: number;\n\thigh?: number;\n}\n\nexport interface MarkdownSettings {\n\tcodeBlockIndent?: string; // default: \" \"\n}\n\nexport interface WarningSettings {\n\tanthropicExtraUsage?: boolean; // default: true\n}\n\n/**\n * Model categories for subagent model selection.\n * Categories map to explicit model IDs (e.g., \"<provider>/<model-id>\").\n * When a category is not configured, no override is applied and the agent's or\n * parent's default model is used.\n */\nexport interface ModelCategories {\n\t/** Quick, cheap models for read-only exploration (grep, find, file discovery) */\n\tfast?: string;\n\t/** Balanced models for general work (planning, moderate complexity) */\n\tstandard?: string;\n\t/** Most capable models for complex reasoning (multi-file refactors) */\n\tcapable?: string;\n}\n\nexport type TransportSetting = Transport;\n\n/**\n * Package source for npm/git packages.\n * - String form: load all resources from the package\n * - Object form: filter which resources to load\n */\nexport type PackageSource =\n\t| string\n\t| {\n\t\t\tsource: string;\n\t\t\textensions?: string[];\n\t\t\tskills?: string[];\n\t\t\tprompts?: string[];\n\t\t\tthemes?: string[];\n\t };\n\nexport interface Settings {\n\tlastChangelogVersion?: string;\n\tdefaultProvider?: string;\n\tdefaultModel?: string;\n\tdefaultThinkingLevel?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\tmodelCategories?: ModelCategories; // Model categories for subagent model selection (fast, standard, capable)\n\ttransport?: TransportSetting; // default: \"auto\"\n\tsteeringMode?: \"all\" | \"one-at-a-time\";\n\tfollowUpMode?: \"all\" | \"one-at-a-time\";\n\ttheme?: string;\n\tcompaction?: CompactionSettings;\n\tbranchSummary?: BranchSummarySettings;\n\tretry?: RetrySettings;\n\thideThinkingBlock?: boolean;\n\tshellPath?: string; // Custom shell path (e.g., for Cygwin users on Windows)\n\tquietStartup?: boolean;\n\tshellCommandPrefix?: string; // Prefix prepended to every bash command (e.g., \"shopt -s expand_aliases\" for alias support)\n\tnpmCommand?: string[]; // Command used for npm package lookup/install operations, argv-style (e.g., [\"mise\", \"exec\", \"node@20\", \"--\", \"npm\"])\n\tcollapseChangelog?: boolean; // Show condensed changelog after update (use /changelog for full)\n\tenableInstallTelemetry?: boolean; // default: true - anonymous version/update ping after changelog-detected updates\n\tpackages?: PackageSource[]; // Array of npm/git package sources (string or object with filtering)\n\textensions?: string[]; // Array of local extension file paths or directories\n\tskills?: string[]; // Array of local skill file paths or directories\n\tprompts?: string[]; // Array of local prompt template paths or directories\n\tslashCommands?: string[]; // Array of local slash-command paths or directories\n\tthemes?: string[]; // Array of local theme file paths or directories\n\tenableSkillCommands?: boolean; // default: true - register skills as /skill:name commands\n\tenableSubagent?: boolean; // default: false - enable the subagent tool (delegate tasks to isolated agent loops)\n\twarmSubagents?: boolean; // default: false - dispatch eligible subagents on reused warm RPC workers (experimental)\n\tmaxSubagentDepth?: number; // default: 1 - tree-wide subagent nesting cap (1 = subagents cannot spawn subagents)\n\tnestedSubagentConcurrency?: number; // default: 2 - max concurrent subagents per pool at nesting depth >= 1\n\tenableTodoWrite?: boolean; // default: true - enable the TodoWrite tool (maintain a live todo list in the task panel)\n\tenableWebTools?: boolean; // default: false - enable the webfetch + websearch tools (network access)\n\tenableBrowserTools?: boolean; // default: false - enable the browser_run + browser_continue tools (browsertools engine)\n\tenableBrowserLivePreview?: boolean; // default: false - default the live viewer on for browser_run runs and auto-open it\n\tenableFileTools?: boolean; // default: false - enable the document tools: DocRead/DocEdit/DocWrite + DocScan/DocGrep/DocPeek (filetools binary)\n\tterminal?: TerminalSettings;\n\timages?: ImageSettings;\n\tenabledModels?: string[]; // Model patterns for cycling (same format as --models CLI flag)\n\tdoubleEscapeAction?: \"fork\" | \"tree\" | \"none\"; // Action for double-escape with empty editor (default: \"tree\")\n\ttreeFilterMode?: \"default\" | \"no-tools\" | \"user-only\" | \"labeled-only\" | \"all\"; // Default filter when opening /tree\n\tthinkingBudgets?: ThinkingBudgetsSettings; // Custom token budgets for thinking levels\n\tthinkingDisplay?: \"summarized\" | \"omitted\"; // How adaptive-thinking models return thinking content. Opus 4.8 defaults to \"omitted\" (faster tool use); set \"summarized\" to surface thinking text.\n\teditorPaddingX?: number; // Horizontal padding for input editor (default: 0)\n\tautocompleteMaxVisible?: number; // Max visible items in autocomplete dropdown (default: 5)\n\tshowHardwareCursor?: boolean; // Show terminal cursor while still positioning it for IME\n\tmarkdown?: MarkdownSettings;\n\twarnings?: WarningSettings;\n\tsessionDir?: string; // Custom session storage directory (same format as --session-dir CLI flag)\n}\n"]}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Settings schema shared across the app.
3
+ *
4
+ * The `Settings` interface and its nested option groups describe the on-disk
5
+ * global/project settings.json shape. Extracted from settings-manager.ts so the
6
+ * schema can be imported without pulling in the manager implementation.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=settings-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settings-types.js","sourceRoot":"","sources":["../../src/core/settings-types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG","sourcesContent":["/**\n * Settings schema shared across the app.\n *\n * The `Settings` interface and its nested option groups describe the on-disk\n * global/project settings.json shape. Extracted from settings-manager.ts so the\n * schema can be imported without pulling in the manager implementation.\n */\n\nimport type { Transport } from \"@kolisachint/hoocode-ai\";\n\nexport interface CompactionSettings {\n\tenabled?: boolean; // default: true\n\treserveTokens?: number; // default: 16384\n\tkeepRecentTokens?: number; // default: 20000\n}\n\nexport interface BranchSummarySettings {\n\treserveTokens?: number; // default: 16384 (tokens reserved for prompt + LLM response)\n\tskipPrompt?: boolean; // default: false - when true, skips \"Summarize branch?\" prompt and defaults to no summary\n}\n\nexport interface ProviderRetrySettings {\n\ttimeoutMs?: number; // SDK/provider request timeout in milliseconds\n\tmaxRetries?: number; // SDK/provider retry attempts\n\tmaxRetryDelayMs?: number; // default: 60000 (max server-requested delay before failing)\n}\n\nexport interface RetrySettings {\n\tenabled?: boolean; // default: true\n\tmaxRetries?: number; // default: 3\n\tbaseDelayMs?: number; // default: 2000 (exponential backoff: 2s, 4s, 8s)\n\tprovider?: ProviderRetrySettings;\n}\n\nexport interface TerminalSettings {\n\tshowImages?: boolean; // default: true (only relevant if terminal supports images)\n\timageWidthCells?: number; // default: 60 (preferred inline image width in terminal cells)\n\tclearOnShrink?: boolean; // default: false (clear empty rows when content shrinks)\n\tshowTerminalProgress?: boolean; // default: false (OSC 9;4 terminal progress indicators)\n}\n\nexport interface ImageSettings {\n\tautoResize?: boolean; // default: true (resize images to 2000x2000 max for better model compatibility)\n\tblockImages?: boolean; // default: false - when true, prevents all images from being sent to LLM providers\n}\n\nexport interface ThinkingBudgetsSettings {\n\tminimal?: number;\n\tlow?: number;\n\tmedium?: number;\n\thigh?: number;\n}\n\nexport interface MarkdownSettings {\n\tcodeBlockIndent?: string; // default: \" \"\n}\n\nexport interface WarningSettings {\n\tanthropicExtraUsage?: boolean; // default: true\n}\n\n/**\n * Model categories for subagent model selection.\n * Categories map to explicit model IDs (e.g., \"<provider>/<model-id>\").\n * When a category is not configured, no override is applied and the agent's or\n * parent's default model is used.\n */\nexport interface ModelCategories {\n\t/** Quick, cheap models for read-only exploration (grep, find, file discovery) */\n\tfast?: string;\n\t/** Balanced models for general work (planning, moderate complexity) */\n\tstandard?: string;\n\t/** Most capable models for complex reasoning (multi-file refactors) */\n\tcapable?: string;\n}\n\nexport type TransportSetting = Transport;\n\n/**\n * Package source for npm/git packages.\n * - String form: load all resources from the package\n * - Object form: filter which resources to load\n */\nexport type PackageSource =\n\t| string\n\t| {\n\t\t\tsource: string;\n\t\t\textensions?: string[];\n\t\t\tskills?: string[];\n\t\t\tprompts?: string[];\n\t\t\tthemes?: string[];\n\t };\n\nexport interface Settings {\n\tlastChangelogVersion?: string;\n\tdefaultProvider?: string;\n\tdefaultModel?: string;\n\tdefaultThinkingLevel?: \"off\" | \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\tmodelCategories?: ModelCategories; // Model categories for subagent model selection (fast, standard, capable)\n\ttransport?: TransportSetting; // default: \"auto\"\n\tsteeringMode?: \"all\" | \"one-at-a-time\";\n\tfollowUpMode?: \"all\" | \"one-at-a-time\";\n\ttheme?: string;\n\tcompaction?: CompactionSettings;\n\tbranchSummary?: BranchSummarySettings;\n\tretry?: RetrySettings;\n\thideThinkingBlock?: boolean;\n\tshellPath?: string; // Custom shell path (e.g., for Cygwin users on Windows)\n\tquietStartup?: boolean;\n\tshellCommandPrefix?: string; // Prefix prepended to every bash command (e.g., \"shopt -s expand_aliases\" for alias support)\n\tnpmCommand?: string[]; // Command used for npm package lookup/install operations, argv-style (e.g., [\"mise\", \"exec\", \"node@20\", \"--\", \"npm\"])\n\tcollapseChangelog?: boolean; // Show condensed changelog after update (use /changelog for full)\n\tenableInstallTelemetry?: boolean; // default: true - anonymous version/update ping after changelog-detected updates\n\tpackages?: PackageSource[]; // Array of npm/git package sources (string or object with filtering)\n\textensions?: string[]; // Array of local extension file paths or directories\n\tskills?: string[]; // Array of local skill file paths or directories\n\tprompts?: string[]; // Array of local prompt template paths or directories\n\tslashCommands?: string[]; // Array of local slash-command paths or directories\n\tthemes?: string[]; // Array of local theme file paths or directories\n\tenableSkillCommands?: boolean; // default: true - register skills as /skill:name commands\n\tenableSubagent?: boolean; // default: false - enable the subagent tool (delegate tasks to isolated agent loops)\n\twarmSubagents?: boolean; // default: false - dispatch eligible subagents on reused warm RPC workers (experimental)\n\tmaxSubagentDepth?: number; // default: 1 - tree-wide subagent nesting cap (1 = subagents cannot spawn subagents)\n\tnestedSubagentConcurrency?: number; // default: 2 - max concurrent subagents per pool at nesting depth >= 1\n\tenableTodoWrite?: boolean; // default: true - enable the TodoWrite tool (maintain a live todo list in the task panel)\n\tenableWebTools?: boolean; // default: false - enable the webfetch + websearch tools (network access)\n\tenableBrowserTools?: boolean; // default: false - enable the browser_run + browser_continue tools (browsertools engine)\n\tenableBrowserLivePreview?: boolean; // default: false - default the live viewer on for browser_run runs and auto-open it\n\tenableFileTools?: boolean; // default: false - enable the document tools: DocRead/DocEdit/DocWrite + DocScan/DocGrep/DocPeek (filetools binary)\n\tterminal?: TerminalSettings;\n\timages?: ImageSettings;\n\tenabledModels?: string[]; // Model patterns for cycling (same format as --models CLI flag)\n\tdoubleEscapeAction?: \"fork\" | \"tree\" | \"none\"; // Action for double-escape with empty editor (default: \"tree\")\n\ttreeFilterMode?: \"default\" | \"no-tools\" | \"user-only\" | \"labeled-only\" | \"all\"; // Default filter when opening /tree\n\tthinkingBudgets?: ThinkingBudgetsSettings; // Custom token budgets for thinking levels\n\tthinkingDisplay?: \"summarized\" | \"omitted\"; // How adaptive-thinking models return thinking content. Opus 4.8 defaults to \"omitted\" (faster tool use); set \"summarized\" to surface thinking text.\n\teditorPaddingX?: number; // Horizontal padding for input editor (default: 0)\n\tautocompleteMaxVisible?: number; // Max visible items in autocomplete dropdown (default: 5)\n\tshowHardwareCursor?: boolean; // Show terminal cursor while still positioning it for IME\n\tmarkdown?: MarkdownSettings;\n\twarnings?: WarningSettings;\n\tsessionDir?: string; // Custom session storage directory (same format as --session-dir CLI flag)\n}\n"]}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Bash command execution for the interactive mode (the `!cmd` prompt mode).
3
+ *
4
+ * Runs a bash command through the session (letting extensions intercept via
5
+ * the user_bash event), renders a BashExecutionComponent for it, and streams
6
+ * output into that component. Commands started while the agent is streaming are
7
+ * parked in the pending area and moved into the chat transcript once the turn
8
+ * finishes. Extracted from interactive-mode.ts behind a narrow
9
+ * BashExecutionControllerDeps interface.
10
+ */
11
+ import type { Container, TUI } from "@kolisachint/hoocode-tui";
12
+ import type { AgentSession } from "../../core/agent-session.js";
13
+ /** The slice of the interactive mode the bash execution needs. */
14
+ export interface BashExecutionControllerDeps {
15
+ /** The active session (read at call time; the session can be swapped). */
16
+ get session(): AgentSession;
17
+ ui: TUI;
18
+ /** Holds bash rows started while the agent is streaming. */
19
+ pendingMessagesContainer: Container;
20
+ /** The chat transcript. */
21
+ chatContainer: Container;
22
+ showError(errorMessage: string): void;
23
+ }
24
+ export declare class BashExecutionController {
25
+ private readonly deps;
26
+ private bashComponent;
27
+ private pendingBashComponents;
28
+ constructor(deps: BashExecutionControllerDeps);
29
+ private get session();
30
+ /** Move pending bash components from pending area to chat */
31
+ flushPendingBashComponents(): void;
32
+ handleBashCommand(command: string, excludeFromContext?: boolean): Promise<void>;
33
+ }
34
+ //# sourceMappingURL=bash-execution-controller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash-execution-controller.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/bash-execution-controller.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAIhE,kEAAkE;AAClE,MAAM,WAAW,2BAA2B;IAC3C,0EAA0E;IAC1E,IAAI,OAAO,IAAI,YAAY,CAAC;IAC5B,EAAE,EAAE,GAAG,CAAC;IACR,4DAA4D;IAC5D,wBAAwB,EAAE,SAAS,CAAC;IACpC,2BAA2B;IAC3B,aAAa,EAAE,SAAS,CAAC;IACzB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CACtC;AAED,qBAAa,uBAAuB;IAOvB,OAAO,CAAC,QAAQ,CAAC,IAAI;IALjC,OAAO,CAAC,aAAa,CAAiD;IAGtE,OAAO,CAAC,qBAAqB,CAAgC;IAE7D,YAA6B,IAAI,EAAE,2BAA2B,EAAI;IAElE,OAAO,KAAK,OAAO,GAElB;IAED,6DAA6D;IAC7D,0BAA0B,IAAI,IAAI,CAMjC;IAEK,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,kBAAkB,UAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAqFlF;CACD","sourcesContent":["/**\n * Bash command execution for the interactive mode (the `!cmd` prompt mode).\n *\n * Runs a bash command through the session (letting extensions intercept via\n * the user_bash event), renders a BashExecutionComponent for it, and streams\n * output into that component. Commands started while the agent is streaming are\n * parked in the pending area and moved into the chat transcript once the turn\n * finishes. Extracted from interactive-mode.ts behind a narrow\n * BashExecutionControllerDeps interface.\n */\n\nimport type { Container, TUI } from \"@kolisachint/hoocode-tui\";\nimport type { AgentSession } from \"../../core/agent-session.js\";\nimport type { TruncationResult } from \"../../core/tools/truncate.js\";\nimport { BashExecutionComponent } from \"./components/bash-execution.js\";\n\n/** The slice of the interactive mode the bash execution needs. */\nexport interface BashExecutionControllerDeps {\n\t/** The active session (read at call time; the session can be swapped). */\n\tget session(): AgentSession;\n\tui: TUI;\n\t/** Holds bash rows started while the agent is streaming. */\n\tpendingMessagesContainer: Container;\n\t/** The chat transcript. */\n\tchatContainer: Container;\n\tshowError(errorMessage: string): void;\n}\n\nexport class BashExecutionController {\n\t// Current bash execution component\n\tprivate bashComponent: BashExecutionComponent | undefined = undefined;\n\n\t// Pending bash components (shown in pending area, moved to chat on submit)\n\tprivate pendingBashComponents: BashExecutionComponent[] = [];\n\n\tconstructor(private readonly deps: BashExecutionControllerDeps) {}\n\n\tprivate get session(): AgentSession {\n\t\treturn this.deps.session;\n\t}\n\n\t/** Move pending bash components from pending area to chat */\n\tflushPendingBashComponents(): void {\n\t\tfor (const component of this.pendingBashComponents) {\n\t\t\tthis.deps.pendingMessagesContainer.removeChild(component);\n\t\t\tthis.deps.chatContainer.addChild(component);\n\t\t}\n\t\tthis.pendingBashComponents = [];\n\t}\n\n\tasync handleBashCommand(command: string, excludeFromContext = false): Promise<void> {\n\t\tconst extensionRunner = this.session.extensionRunner;\n\n\t\t// Emit user_bash event to let extensions intercept\n\t\tconst eventResult = await extensionRunner.emitUserBash({\n\t\t\ttype: \"user_bash\",\n\t\t\tcommand,\n\t\t\texcludeFromContext,\n\t\t\tcwd: this.session.sessionManager.getCwd(),\n\t\t});\n\n\t\t// If extension returned a full result, use it directly\n\t\tif (eventResult?.result) {\n\t\t\tconst result = eventResult.result;\n\n\t\t\t// Create UI component for display\n\t\t\tthis.bashComponent = new BashExecutionComponent(command, this.deps.ui, excludeFromContext);\n\t\t\tif (this.session.isStreaming) {\n\t\t\t\tthis.deps.pendingMessagesContainer.addChild(this.bashComponent);\n\t\t\t\tthis.pendingBashComponents.push(this.bashComponent);\n\t\t\t} else {\n\t\t\t\tthis.deps.chatContainer.addChild(this.bashComponent);\n\t\t\t}\n\n\t\t\t// Show output and complete\n\t\t\tif (result.output) {\n\t\t\t\tthis.bashComponent.appendOutput(result.output);\n\t\t\t}\n\t\t\tthis.bashComponent.setComplete(\n\t\t\t\tresult.exitCode,\n\t\t\t\tresult.cancelled,\n\t\t\t\tresult.truncated ? ({ truncated: true, content: result.output } as TruncationResult) : undefined,\n\t\t\t\tresult.fullOutputPath,\n\t\t\t);\n\n\t\t\t// Record the result in session\n\t\t\tthis.session.recordBashResult(command, result, { excludeFromContext });\n\t\t\tthis.bashComponent = undefined;\n\t\t\tthis.deps.ui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\t// Normal execution path (possibly with custom operations)\n\t\tconst isDeferred = this.session.isStreaming;\n\t\tthis.bashComponent = new BashExecutionComponent(command, this.deps.ui, excludeFromContext);\n\n\t\tif (isDeferred) {\n\t\t\t// Show in pending area when agent is streaming\n\t\t\tthis.deps.pendingMessagesContainer.addChild(this.bashComponent);\n\t\t\tthis.pendingBashComponents.push(this.bashComponent);\n\t\t} else {\n\t\t\t// Show in chat immediately when agent is idle\n\t\t\tthis.deps.chatContainer.addChild(this.bashComponent);\n\t\t}\n\t\tthis.deps.ui.requestRender();\n\n\t\ttry {\n\t\t\tconst result = await this.session.executeBash(\n\t\t\t\tcommand,\n\t\t\t\t(chunk) => {\n\t\t\t\t\tif (this.bashComponent) {\n\t\t\t\t\t\tthis.bashComponent.appendOutput(chunk);\n\t\t\t\t\t\tthis.deps.ui.requestRender();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ excludeFromContext, operations: eventResult?.operations },\n\t\t\t);\n\n\t\t\tif (this.bashComponent) {\n\t\t\t\tthis.bashComponent.setComplete(\n\t\t\t\t\tresult.exitCode,\n\t\t\t\t\tresult.cancelled,\n\t\t\t\t\tresult.truncated ? ({ truncated: true, content: result.output } as TruncationResult) : undefined,\n\t\t\t\t\tresult.fullOutputPath,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (this.bashComponent) {\n\t\t\t\tthis.bashComponent.setComplete(undefined, false);\n\t\t\t}\n\t\t\tthis.deps.showError(`Bash command failed: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t}\n\n\t\tthis.bashComponent = undefined;\n\t\tthis.deps.ui.requestRender();\n\t}\n}\n"]}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Bash command execution for the interactive mode (the `!cmd` prompt mode).
3
+ *
4
+ * Runs a bash command through the session (letting extensions intercept via
5
+ * the user_bash event), renders a BashExecutionComponent for it, and streams
6
+ * output into that component. Commands started while the agent is streaming are
7
+ * parked in the pending area and moved into the chat transcript once the turn
8
+ * finishes. Extracted from interactive-mode.ts behind a narrow
9
+ * BashExecutionControllerDeps interface.
10
+ */
11
+ import { BashExecutionComponent } from "./components/bash-execution.js";
12
+ export class BashExecutionController {
13
+ deps;
14
+ // Current bash execution component
15
+ bashComponent = undefined;
16
+ // Pending bash components (shown in pending area, moved to chat on submit)
17
+ pendingBashComponents = [];
18
+ constructor(deps) {
19
+ this.deps = deps;
20
+ }
21
+ get session() {
22
+ return this.deps.session;
23
+ }
24
+ /** Move pending bash components from pending area to chat */
25
+ flushPendingBashComponents() {
26
+ for (const component of this.pendingBashComponents) {
27
+ this.deps.pendingMessagesContainer.removeChild(component);
28
+ this.deps.chatContainer.addChild(component);
29
+ }
30
+ this.pendingBashComponents = [];
31
+ }
32
+ async handleBashCommand(command, excludeFromContext = false) {
33
+ const extensionRunner = this.session.extensionRunner;
34
+ // Emit user_bash event to let extensions intercept
35
+ const eventResult = await extensionRunner.emitUserBash({
36
+ type: "user_bash",
37
+ command,
38
+ excludeFromContext,
39
+ cwd: this.session.sessionManager.getCwd(),
40
+ });
41
+ // If extension returned a full result, use it directly
42
+ if (eventResult?.result) {
43
+ const result = eventResult.result;
44
+ // Create UI component for display
45
+ this.bashComponent = new BashExecutionComponent(command, this.deps.ui, excludeFromContext);
46
+ if (this.session.isStreaming) {
47
+ this.deps.pendingMessagesContainer.addChild(this.bashComponent);
48
+ this.pendingBashComponents.push(this.bashComponent);
49
+ }
50
+ else {
51
+ this.deps.chatContainer.addChild(this.bashComponent);
52
+ }
53
+ // Show output and complete
54
+ if (result.output) {
55
+ this.bashComponent.appendOutput(result.output);
56
+ }
57
+ this.bashComponent.setComplete(result.exitCode, result.cancelled, result.truncated ? { truncated: true, content: result.output } : undefined, result.fullOutputPath);
58
+ // Record the result in session
59
+ this.session.recordBashResult(command, result, { excludeFromContext });
60
+ this.bashComponent = undefined;
61
+ this.deps.ui.requestRender();
62
+ return;
63
+ }
64
+ // Normal execution path (possibly with custom operations)
65
+ const isDeferred = this.session.isStreaming;
66
+ this.bashComponent = new BashExecutionComponent(command, this.deps.ui, excludeFromContext);
67
+ if (isDeferred) {
68
+ // Show in pending area when agent is streaming
69
+ this.deps.pendingMessagesContainer.addChild(this.bashComponent);
70
+ this.pendingBashComponents.push(this.bashComponent);
71
+ }
72
+ else {
73
+ // Show in chat immediately when agent is idle
74
+ this.deps.chatContainer.addChild(this.bashComponent);
75
+ }
76
+ this.deps.ui.requestRender();
77
+ try {
78
+ const result = await this.session.executeBash(command, (chunk) => {
79
+ if (this.bashComponent) {
80
+ this.bashComponent.appendOutput(chunk);
81
+ this.deps.ui.requestRender();
82
+ }
83
+ }, { excludeFromContext, operations: eventResult?.operations });
84
+ if (this.bashComponent) {
85
+ this.bashComponent.setComplete(result.exitCode, result.cancelled, result.truncated ? { truncated: true, content: result.output } : undefined, result.fullOutputPath);
86
+ }
87
+ }
88
+ catch (error) {
89
+ if (this.bashComponent) {
90
+ this.bashComponent.setComplete(undefined, false);
91
+ }
92
+ this.deps.showError(`Bash command failed: ${error instanceof Error ? error.message : "Unknown error"}`);
93
+ }
94
+ this.bashComponent = undefined;
95
+ this.deps.ui.requestRender();
96
+ }
97
+ }
98
+ //# sourceMappingURL=bash-execution-controller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bash-execution-controller.js","sourceRoot":"","sources":["../../../src/modes/interactive/bash-execution-controller.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Bash command execution for the interactive mode (the `!cmd` prompt mode).\n *\n * Runs a bash command through the session (letting extensions intercept via\n * the user_bash event), renders a BashExecutionComponent for it, and streams\n * output into that component. Commands started while the agent is streaming are\n * parked in the pending area and moved into the chat transcript once the turn\n * finishes. Extracted from interactive-mode.ts behind a narrow\n * BashExecutionControllerDeps interface.\n */\n\nimport type { Container, TUI } from \"@kolisachint/hoocode-tui\";\nimport type { AgentSession } from \"../../core/agent-session.js\";\nimport type { TruncationResult } from \"../../core/tools/truncate.js\";\nimport { BashExecutionComponent } from \"./components/bash-execution.js\";\n\n/** The slice of the interactive mode the bash execution needs. */\nexport interface BashExecutionControllerDeps {\n\t/** The active session (read at call time; the session can be swapped). */\n\tget session(): AgentSession;\n\tui: TUI;\n\t/** Holds bash rows started while the agent is streaming. */\n\tpendingMessagesContainer: Container;\n\t/** The chat transcript. */\n\tchatContainer: Container;\n\tshowError(errorMessage: string): void;\n}\n\nexport class BashExecutionController {\n\t// Current bash execution component\n\tprivate bashComponent: BashExecutionComponent | undefined = undefined;\n\n\t// Pending bash components (shown in pending area, moved to chat on submit)\n\tprivate pendingBashComponents: BashExecutionComponent[] = [];\n\n\tconstructor(private readonly deps: BashExecutionControllerDeps) {}\n\n\tprivate get session(): AgentSession {\n\t\treturn this.deps.session;\n\t}\n\n\t/** Move pending bash components from pending area to chat */\n\tflushPendingBashComponents(): void {\n\t\tfor (const component of this.pendingBashComponents) {\n\t\t\tthis.deps.pendingMessagesContainer.removeChild(component);\n\t\t\tthis.deps.chatContainer.addChild(component);\n\t\t}\n\t\tthis.pendingBashComponents = [];\n\t}\n\n\tasync handleBashCommand(command: string, excludeFromContext = false): Promise<void> {\n\t\tconst extensionRunner = this.session.extensionRunner;\n\n\t\t// Emit user_bash event to let extensions intercept\n\t\tconst eventResult = await extensionRunner.emitUserBash({\n\t\t\ttype: \"user_bash\",\n\t\t\tcommand,\n\t\t\texcludeFromContext,\n\t\t\tcwd: this.session.sessionManager.getCwd(),\n\t\t});\n\n\t\t// If extension returned a full result, use it directly\n\t\tif (eventResult?.result) {\n\t\t\tconst result = eventResult.result;\n\n\t\t\t// Create UI component for display\n\t\t\tthis.bashComponent = new BashExecutionComponent(command, this.deps.ui, excludeFromContext);\n\t\t\tif (this.session.isStreaming) {\n\t\t\t\tthis.deps.pendingMessagesContainer.addChild(this.bashComponent);\n\t\t\t\tthis.pendingBashComponents.push(this.bashComponent);\n\t\t\t} else {\n\t\t\t\tthis.deps.chatContainer.addChild(this.bashComponent);\n\t\t\t}\n\n\t\t\t// Show output and complete\n\t\t\tif (result.output) {\n\t\t\t\tthis.bashComponent.appendOutput(result.output);\n\t\t\t}\n\t\t\tthis.bashComponent.setComplete(\n\t\t\t\tresult.exitCode,\n\t\t\t\tresult.cancelled,\n\t\t\t\tresult.truncated ? ({ truncated: true, content: result.output } as TruncationResult) : undefined,\n\t\t\t\tresult.fullOutputPath,\n\t\t\t);\n\n\t\t\t// Record the result in session\n\t\t\tthis.session.recordBashResult(command, result, { excludeFromContext });\n\t\t\tthis.bashComponent = undefined;\n\t\t\tthis.deps.ui.requestRender();\n\t\t\treturn;\n\t\t}\n\n\t\t// Normal execution path (possibly with custom operations)\n\t\tconst isDeferred = this.session.isStreaming;\n\t\tthis.bashComponent = new BashExecutionComponent(command, this.deps.ui, excludeFromContext);\n\n\t\tif (isDeferred) {\n\t\t\t// Show in pending area when agent is streaming\n\t\t\tthis.deps.pendingMessagesContainer.addChild(this.bashComponent);\n\t\t\tthis.pendingBashComponents.push(this.bashComponent);\n\t\t} else {\n\t\t\t// Show in chat immediately when agent is idle\n\t\t\tthis.deps.chatContainer.addChild(this.bashComponent);\n\t\t}\n\t\tthis.deps.ui.requestRender();\n\n\t\ttry {\n\t\t\tconst result = await this.session.executeBash(\n\t\t\t\tcommand,\n\t\t\t\t(chunk) => {\n\t\t\t\t\tif (this.bashComponent) {\n\t\t\t\t\t\tthis.bashComponent.appendOutput(chunk);\n\t\t\t\t\t\tthis.deps.ui.requestRender();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ excludeFromContext, operations: eventResult?.operations },\n\t\t\t);\n\n\t\t\tif (this.bashComponent) {\n\t\t\t\tthis.bashComponent.setComplete(\n\t\t\t\t\tresult.exitCode,\n\t\t\t\t\tresult.cancelled,\n\t\t\t\t\tresult.truncated ? ({ truncated: true, content: result.output } as TruncationResult) : undefined,\n\t\t\t\t\tresult.fullOutputPath,\n\t\t\t\t);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (this.bashComponent) {\n\t\t\t\tthis.bashComponent.setComplete(undefined, false);\n\t\t\t}\n\t\t\tthis.deps.showError(`Bash command failed: ${error instanceof Error ? error.message : \"Unknown error\"}`);\n\t\t}\n\n\t\tthis.bashComponent = undefined;\n\t\tthis.deps.ui.requestRender();\n\t}\n}\n"]}
@@ -2,10 +2,9 @@
2
2
  * Interactive mode for the coding agent.
3
3
  * Handles TUI rendering and user interaction, delegating business logic to AgentSession.
4
4
  */
5
- import { type ImageContent } from "@kolisachint/hoocode-ai";
5
+ import type { ImageContent } from "@kolisachint/hoocode-ai";
6
6
  import type { AgentSessionRuntime } from "../../core/agent-session-runtime.js";
7
7
  import type { TeamViewConnection } from "../../core/team-view.js";
8
- export declare function isApiKeyLoginProvider(providerId: string, oauthProviderIds: ReadonlySet<string>, builtInProviderIds?: ReadonlySet<string>): boolean;
9
8
  /**
10
9
  * Options for InteractiveMode initialization.
11
10
  */
@@ -55,7 +54,6 @@ export declare class InteractiveMode {
55
54
  private lastEscapeTime;
56
55
  private changelogMarkdown;
57
56
  private startupNoticesShown;
58
- private anthropicSubscriptionWarningShown;
59
57
  private lastStatusSpacer;
60
58
  private lastStatusText;
61
59
  private streamingComponent;
@@ -68,14 +66,11 @@ export declare class InteractiveMode {
68
66
  private taskStoreUnsubscribe?;
69
67
  private signalCleanupHandlers;
70
68
  private isBashMode;
71
- private bashComponent;
72
- private pendingBashComponents;
73
69
  private autoCompactionLoader;
74
70
  private autoCompactionEscapeHandler?;
75
71
  private retryLoader;
76
72
  private retryCountdown;
77
73
  private retryEscapeHandler?;
78
- private compactionQueuedMessages;
79
74
  private shutdownRequested;
80
75
  private dialogs;
81
76
  private extensionTerminalInputUnsubscribers;
@@ -84,6 +79,10 @@ export declare class InteractiveMode {
84
79
  private widgetContainerBelow;
85
80
  private taskPanel;
86
81
  private teamFocus;
82
+ private bashExecution;
83
+ private messageQueue;
84
+ private modelController;
85
+ private loginController;
87
86
  private headerContainer;
88
87
  private builtInHeader;
89
88
  private get session();
@@ -219,7 +218,6 @@ export declare class InteractiveMode {
219
218
  private updateEditorBorderColor;
220
219
  private updateEditorPromptPrefix;
221
220
  private cycleThinkingLevel;
222
- private cycleModel;
223
221
  private toggleToolOutputExpansion;
224
222
  private setToolsExpanded;
225
223
  private toggleThinkingBlockVisibility;
@@ -229,55 +227,17 @@ export declare class InteractiveMode {
229
227
  showWarning(warningMessage: string): void;
230
228
  showNewVersionNotification(newVersion: string): void;
231
229
  showPackageUpdateNotification(packages: string[]): void;
232
- /**
233
- * Get all queued messages (read-only).
234
- * Combines session queue and compaction queue.
235
- */
236
- private getAllQueuedMessages;
237
- /**
238
- * Clear all queued messages and return their contents.
239
- * Clears both session queue and compaction queue.
240
- */
241
- private clearAllQueues;
242
- private updatePendingMessagesDisplay;
243
- private restoreQueuedMessagesToEditor;
244
- private queueCompactionMessage;
245
- private isExtensionCommand;
246
- private flushCompactionQueue;
247
- /** Move pending bash components from pending area to chat */
248
- private flushPendingBashComponents;
249
230
  /**
250
231
  * Shows a selector component in place of the editor.
251
232
  * @param create Factory that receives a `done` callback and returns the component and focus target
252
233
  */
253
234
  private showSelector;
254
235
  private showSettingsSelector;
255
- private findExactModelMatch;
256
- private getModelCandidates;
257
- private updateAvailableProviderCount;
258
- private maybeWarnAboutAnthropicSubscriptionAuth;
259
- private showModelSelector;
260
- private showModelsSelector;
261
236
  private showUserMessageSelector;
262
237
  private showTreeSelector;
263
238
  private showSessionSelector;
264
239
  private handleResumeSession;
265
- private getLoginProviderOptions;
266
- private getLogoutProviderOptions;
267
- private showLoginAuthTypeSelector;
268
- private showLoginProviderSelector;
269
- private showOAuthSelector;
270
- private completeProviderAuthentication;
271
- private showBedrockSetupDialog;
272
- private showApiKeyLoginDialog;
273
- private showOAuthLoginSelect;
274
- private showLoginDialog;
275
240
  private handleReloadCommand;
276
- /**
277
- * Get capitalized display string for an app keybinding action.
278
- */
279
- private getAppKeyDisplay;
280
- private handleBashCommand;
281
241
  private handleCompactCommand;
282
242
  stop(): void;
283
243
  }