@kolisachint/hoocode-agent 0.4.106 → 0.4.108
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/CHANGELOG.md +4 -0
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +4 -4
- package/dist/cli/args.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +0 -1
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +2 -2
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session.d.ts +1 -3
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +2 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/bash-executor.d.ts.map +1 -1
- package/dist/core/bash-executor.js +1 -1
- package/dist/core/bash-executor.js.map +1 -1
- package/dist/core/extension-mcp-servers.d.ts +1 -1
- package/dist/core/extension-mcp-servers.d.ts.map +1 -1
- package/dist/core/extension-mcp-servers.js +1 -1
- package/dist/core/extension-mcp-servers.js.map +1 -1
- package/dist/core/extensions/plugins/index.d.ts.map +1 -1
- package/dist/core/extensions/plugins/index.js +1 -1
- package/dist/core/extensions/plugins/index.js.map +1 -1
- package/dist/core/extensions/types.d.ts +1 -3
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/mode-prompts.d.ts +1 -1
- package/dist/core/mode-prompts.d.ts.map +1 -1
- package/dist/core/mode-prompts.js +1 -1
- package/dist/core/mode-prompts.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +1 -1
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -2
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +2 -97
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +4 -65
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +2 -3
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/telemetry.d.ts.map +1 -1
- package/dist/core/telemetry.js +1 -1
- package/dist/core/telemetry.js.map +1 -1
- package/dist/core/timings.d.ts +1 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +2 -2
- package/dist/core/timings.js.map +1 -1
- package/dist/core/tools/{browser-continue.d.ts → browser/browser-continue.d.ts} +1 -1
- package/dist/core/tools/browser/browser-continue.d.ts.map +1 -0
- package/dist/core/tools/{browser-continue.js → browser/browser-continue.js} +2 -2
- package/dist/core/tools/browser/browser-continue.js.map +1 -0
- package/dist/core/tools/{browser-run.d.ts → browser/browser-run.d.ts} +2 -2
- package/dist/core/tools/browser/browser-run.d.ts.map +1 -0
- package/dist/core/tools/{browser-run.js → browser/browser-run.js} +2 -2
- package/dist/core/tools/browser/browser-run.js.map +1 -0
- package/dist/core/tools/browser/browsertools-shared.d.ts.map +1 -0
- package/dist/core/tools/{browsertools-shared.js → browser/browsertools-shared.js} +1 -1
- package/dist/core/tools/browser/browsertools-shared.js.map +1 -0
- package/dist/core/tools/browser/index.d.ts +8 -0
- package/dist/core/tools/browser/index.d.ts.map +1 -0
- package/dist/core/tools/browser/index.js +8 -0
- package/dist/core/tools/browser/index.js.map +1 -0
- package/dist/core/tools/{docedit.d.ts → doc/docedit.d.ts} +2 -2
- package/dist/core/tools/doc/docedit.d.ts.map +1 -0
- package/dist/core/tools/{docedit.js → doc/docedit.js} +7 -7
- package/dist/core/tools/doc/docedit.js.map +1 -0
- package/dist/core/tools/{docgrep.d.ts → doc/docgrep.d.ts} +2 -2
- package/dist/core/tools/doc/docgrep.d.ts.map +1 -0
- package/dist/core/tools/{docgrep.js → doc/docgrep.js} +6 -6
- package/dist/core/tools/doc/docgrep.js.map +1 -0
- package/dist/core/tools/{docpeek.d.ts → doc/docpeek.d.ts} +2 -2
- package/dist/core/tools/{docpeek.js.map → doc/docpeek.d.ts.map} +1 -1
- package/dist/core/tools/{docpeek.js → doc/docpeek.js} +6 -6
- package/dist/core/tools/doc/docpeek.js.map +1 -0
- package/dist/core/tools/{docread.d.ts → doc/docread.d.ts} +2 -2
- package/dist/core/tools/doc/docread.d.ts.map +1 -0
- package/dist/core/tools/{docread.js → doc/docread.js} +6 -6
- package/dist/core/tools/doc/docread.js.map +1 -0
- package/dist/core/tools/{docscan.d.ts → doc/docscan.d.ts} +2 -2
- package/dist/core/tools/doc/docscan.d.ts.map +1 -0
- package/dist/core/tools/{docscan.js → doc/docscan.js} +6 -6
- package/dist/core/tools/doc/docscan.js.map +1 -0
- package/dist/core/tools/{docwrite.d.ts → doc/docwrite.d.ts} +1 -1
- package/dist/core/tools/doc/docwrite.d.ts.map +1 -0
- package/dist/core/tools/{docwrite.js → doc/docwrite.js} +6 -6
- package/dist/core/tools/doc/docwrite.js.map +1 -0
- package/dist/core/tools/doc/index.d.ts +11 -0
- package/dist/core/tools/doc/index.d.ts.map +1 -0
- package/dist/core/tools/doc/index.js +11 -0
- package/dist/core/tools/doc/index.js.map +1 -0
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +1 -1
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +42 -28
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +61 -199
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/output-accumulator.d.ts.map +1 -1
- package/dist/core/tools/output-accumulator.js +1 -1
- package/dist/core/tools/output-accumulator.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +1 -1
- package/dist/core/tools/read.js.map +1 -1
- package/dist/extensions/core/ask-options.d.ts +10 -0
- package/dist/extensions/core/ask-options.d.ts.map +1 -0
- package/dist/extensions/core/ask-options.js +83 -0
- package/dist/extensions/core/ask-options.js.map +1 -0
- package/dist/extensions/core/config.d.ts +80 -0
- package/dist/extensions/core/config.d.ts.map +1 -0
- package/dist/extensions/core/config.js +110 -0
- package/dist/extensions/core/config.js.map +1 -0
- package/dist/extensions/core/cost.d.ts +11 -0
- package/dist/extensions/core/cost.d.ts.map +1 -0
- package/dist/extensions/core/cost.js +64 -0
- package/dist/extensions/core/cost.js.map +1 -0
- package/dist/extensions/core/hoo-core.d.ts +16 -179
- package/dist/extensions/core/hoo-core.d.ts.map +1 -1
- package/dist/extensions/core/hoo-core.js +27 -1663
- package/dist/extensions/core/hoo-core.js.map +1 -1
- package/dist/extensions/core/loop.d.ts +15 -0
- package/dist/extensions/core/loop.d.ts.map +1 -0
- package/dist/extensions/core/loop.js +235 -0
- package/dist/extensions/core/loop.js.map +1 -0
- package/dist/extensions/core/marketplace.d.ts +17 -0
- package/dist/extensions/core/marketplace.d.ts.map +1 -0
- package/dist/extensions/core/marketplace.js +167 -0
- package/dist/extensions/core/marketplace.js.map +1 -0
- package/dist/extensions/core/mcp-loader.d.ts +26 -0
- package/dist/extensions/core/mcp-loader.d.ts.map +1 -0
- package/dist/extensions/core/mcp-loader.js +391 -0
- package/dist/extensions/core/mcp-loader.js.map +1 -0
- package/dist/extensions/core/modes.d.ts +56 -0
- package/dist/extensions/core/modes.d.ts.map +1 -0
- package/dist/extensions/core/modes.js +268 -0
- package/dist/extensions/core/modes.js.map +1 -0
- package/dist/extensions/core/permission-gate.d.ts +10 -0
- package/dist/extensions/core/permission-gate.d.ts.map +1 -0
- package/dist/extensions/core/permission-gate.js +167 -0
- package/dist/extensions/core/permission-gate.js.map +1 -0
- package/dist/extensions/core/scaffold.d.ts +9 -0
- package/dist/extensions/core/scaffold.d.ts.map +1 -0
- package/dist/extensions/core/scaffold.js +146 -0
- package/dist/extensions/core/scaffold.js.map +1 -0
- package/dist/extensions/core/thinking-escalation.d.ts +18 -0
- package/dist/extensions/core/thinking-escalation.d.ts.map +1 -0
- package/dist/extensions/core/thinking-escalation.js +70 -0
- package/dist/extensions/core/thinking-escalation.js.map +1 -0
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +2 -2
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/bash-execution-controller.d.ts +34 -0
- package/dist/modes/interactive/bash-execution-controller.d.ts.map +1 -0
- package/dist/modes/interactive/bash-execution-controller.js +98 -0
- package/dist/modes/interactive/bash-execution-controller.js.map +1 -0
- package/dist/modes/interactive/command-executor.d.ts +0 -5
- package/dist/modes/interactive/command-executor.d.ts.map +1 -1
- package/dist/modes/interactive/command-executor.js +0 -7
- package/dist/modes/interactive/command-executor.js.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +0 -2
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +0 -2
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/extension-chrome.d.ts +56 -0
- package/dist/modes/interactive/extension-chrome.d.ts.map +1 -0
- package/dist/modes/interactive/extension-chrome.js +172 -0
- package/dist/modes/interactive/extension-chrome.js.map +1 -0
- package/dist/modes/interactive/extension-dialogs.d.ts +82 -0
- package/dist/modes/interactive/extension-dialogs.d.ts.map +1 -0
- package/dist/modes/interactive/extension-dialogs.js +259 -0
- package/dist/modes/interactive/extension-dialogs.js.map +1 -0
- package/dist/modes/interactive/interactive-mode.d.ts +16 -206
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +359 -2370
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/login-controller.d.ts +50 -0
- package/dist/modes/interactive/login-controller.d.ts.map +1 -0
- package/dist/modes/interactive/login-controller.js +352 -0
- package/dist/modes/interactive/login-controller.js.map +1 -0
- package/dist/modes/interactive/message-queue-controller.d.ts +49 -0
- package/dist/modes/interactive/message-queue-controller.d.ts.map +1 -0
- package/dist/modes/interactive/message-queue-controller.js +184 -0
- package/dist/modes/interactive/message-queue-controller.js.map +1 -0
- package/dist/modes/interactive/model-controller.d.ts +43 -0
- package/dist/modes/interactive/model-controller.d.ts.map +1 -0
- package/dist/modes/interactive/model-controller.js +184 -0
- package/dist/modes/interactive/model-controller.js.map +1 -0
- package/dist/modes/interactive/resource-display.d.ts +59 -0
- package/dist/modes/interactive/resource-display.d.ts.map +1 -0
- package/dist/modes/interactive/resource-display.js +499 -0
- package/dist/modes/interactive/resource-display.js.map +1 -0
- package/dist/modes/interactive/startup-checks.d.ts +17 -0
- package/dist/modes/interactive/startup-checks.d.ts.map +1 -0
- package/dist/modes/interactive/startup-checks.js +102 -0
- package/dist/modes/interactive/startup-checks.js.map +1 -0
- package/dist/modes/interactive/team-focus.d.ts +56 -0
- package/dist/modes/interactive/team-focus.d.ts.map +1 -0
- package/dist/modes/interactive/team-focus.js +167 -0
- package/dist/modes/interactive/team-focus.js.map +1 -0
- package/dist/modes/interactive/voice/voice-controller.d.ts +66 -0
- package/dist/modes/interactive/voice/voice-controller.d.ts.map +1 -0
- package/dist/modes/interactive/voice/voice-controller.js +312 -0
- package/dist/modes/interactive/voice/voice-controller.js.map +1 -0
- package/dist/modes/interactive/voice/voice-panel.d.ts.map +1 -0
- package/dist/modes/interactive/voice/voice-panel.js.map +1 -0
- package/dist/modes/interactive/voice/voice-transcribe.d.ts.map +1 -0
- package/dist/modes/interactive/voice/voice-transcribe.js.map +1 -0
- package/dist/modes/rpc/rpc-client.d.ts +1 -2
- package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-client.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +1 -2
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/resources-cli.d.ts.map +1 -1
- package/dist/resources-cli.js +1 -1
- package/dist/resources-cli.js.map +1 -1
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +1 -1
- package/dist/utils/tools-manager.js.map +1 -1
- package/dist/utils/version-check.d.ts.map +1 -1
- package/dist/utils/version-check.js +2 -2
- package/dist/utils/version-check.js.map +1 -1
- package/docs/project-local-resources.md +1 -1
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package.json +1 -1
- package/package.json +4 -4
- package/dist/core/compaction/branch-summarization.d.ts +0 -88
- package/dist/core/compaction/branch-summarization.d.ts.map +0 -1
- package/dist/core/compaction/branch-summarization.js +0 -243
- package/dist/core/compaction/branch-summarization.js.map +0 -1
- package/dist/core/compaction/compaction.d.ts +0 -123
- package/dist/core/compaction/compaction.d.ts.map +0 -1
- package/dist/core/compaction/compaction.js +0 -635
- package/dist/core/compaction/compaction.js.map +0 -1
- package/dist/core/compaction/index.d.ts +0 -7
- package/dist/core/compaction/index.d.ts.map +0 -1
- package/dist/core/compaction/index.js +0 -7
- package/dist/core/compaction/index.js.map +0 -1
- package/dist/core/compaction/utils.d.ts +0 -38
- package/dist/core/compaction/utils.d.ts.map +0 -1
- package/dist/core/compaction/utils.js +0 -156
- package/dist/core/compaction/utils.js.map +0 -1
- package/dist/core/messages.d.ts +0 -124
- package/dist/core/messages.d.ts.map +0 -1
- package/dist/core/messages.js +0 -221
- package/dist/core/messages.js.map +0 -1
- package/dist/core/tools/browser-continue.d.ts.map +0 -1
- package/dist/core/tools/browser-continue.js.map +0 -1
- package/dist/core/tools/browser-run.d.ts.map +0 -1
- package/dist/core/tools/browser-run.js.map +0 -1
- package/dist/core/tools/browsertools-shared.d.ts.map +0 -1
- package/dist/core/tools/browsertools-shared.js.map +0 -1
- package/dist/core/tools/docedit.d.ts.map +0 -1
- package/dist/core/tools/docedit.js.map +0 -1
- package/dist/core/tools/docgrep.d.ts.map +0 -1
- package/dist/core/tools/docgrep.js.map +0 -1
- package/dist/core/tools/docpeek.d.ts.map +0 -1
- package/dist/core/tools/docread.d.ts.map +0 -1
- package/dist/core/tools/docread.js.map +0 -1
- package/dist/core/tools/docscan.d.ts.map +0 -1
- package/dist/core/tools/docscan.js.map +0 -1
- package/dist/core/tools/docwrite.d.ts.map +0 -1
- package/dist/core/tools/docwrite.js.map +0 -1
- package/dist/core/tools/output-compression.d.ts +0 -53
- package/dist/core/tools/output-compression.d.ts.map +0 -1
- package/dist/core/tools/output-compression.js +0 -392
- package/dist/core/tools/output-compression.js.map +0 -1
- package/dist/modes/interactive/components/armin.d.ts +0 -34
- package/dist/modes/interactive/components/armin.d.ts.map +0 -1
- package/dist/modes/interactive/components/armin.js +0 -333
- package/dist/modes/interactive/components/armin.js.map +0 -1
- package/dist/modes/interactive/components/daxnuts.d.ts +0 -23
- package/dist/modes/interactive/components/daxnuts.d.ts.map +0 -1
- package/dist/modes/interactive/components/daxnuts.js +0 -140
- package/dist/modes/interactive/components/daxnuts.js.map +0 -1
- package/dist/modes/interactive/components/voice-panel.d.ts.map +0 -1
- package/dist/modes/interactive/components/voice-panel.js.map +0 -1
- package/dist/modes/interactive/voice-transcribe.d.ts.map +0 -1
- package/dist/modes/interactive/voice-transcribe.js.map +0 -1
- /package/dist/core/tools/{browsertools-shared.d.ts → browser/browsertools-shared.d.ts} +0 -0
- /package/dist/modes/interactive/{components → voice}/voice-panel.d.ts +0 -0
- /package/dist/modes/interactive/{components → voice}/voice-panel.js +0 -0
- /package/dist/modes/interactive/{voice-transcribe.d.ts → voice/voice-transcribe.d.ts} +0 -0
- /package/dist/modes/interactive/{voice-transcribe.js → voice/voice-transcribe.js} +0 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* hoo-config.json — types, I/O, and merge rules shared by the hoo-core extensions.
|
|
3
|
+
*
|
|
4
|
+
* Config merge order (lowest → highest priority):
|
|
5
|
+
* 1. ~/.hoocode/hoo-config.json (global defaults)
|
|
6
|
+
* 2. ./.hoocode/hoo-config.json (project overrides — scalars win; arrays union)
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { getHooCodeDir } from "../../config.js";
|
|
11
|
+
const HOOCODE_DIR = getHooCodeDir();
|
|
12
|
+
const GLOBAL_CONFIG_PATH = join(HOOCODE_DIR, "hoo-config.json");
|
|
13
|
+
export function readConfig() {
|
|
14
|
+
try {
|
|
15
|
+
return JSON.parse(readFileSync(GLOBAL_CONFIG_PATH, "utf8"));
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return {};
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export function writeConfig(config) {
|
|
22
|
+
if (!existsSync(HOOCODE_DIR))
|
|
23
|
+
mkdirSync(HOOCODE_DIR, { recursive: true });
|
|
24
|
+
writeFileSync(GLOBAL_CONFIG_PATH, `${JSON.stringify(config, null, 2)}\n`, "utf8");
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Deep-merges a project-local config on top of the global config.
|
|
28
|
+
*
|
|
29
|
+
* Merge rules:
|
|
30
|
+
* - active_mode: project wins if set
|
|
31
|
+
* - modes[x].auto_allow: union of global + project arrays
|
|
32
|
+
* - modes[x].allowed_write_paths: union of global + project arrays
|
|
33
|
+
* - modes[x].enabled_tools: project wins if set, else falls back to global
|
|
34
|
+
* - mode_paths: project list is prepended so project paths are searched first
|
|
35
|
+
* - thinking_escalation: project wins as a whole if set, else inherit global
|
|
36
|
+
*/
|
|
37
|
+
export function mergeConfigs(global, project) {
|
|
38
|
+
const merged = { ...global };
|
|
39
|
+
if (project.active_mode !== undefined)
|
|
40
|
+
merged.active_mode = project.active_mode;
|
|
41
|
+
// thinking_escalation: project wins as a whole if set, else inherit global.
|
|
42
|
+
if (project.thinking_escalation !== undefined)
|
|
43
|
+
merged.thinking_escalation = project.thinking_escalation;
|
|
44
|
+
if (project.modes) {
|
|
45
|
+
merged.modes = { ...(global.modes ?? {}) };
|
|
46
|
+
for (const [mode, projectCfg] of Object.entries(project.modes)) {
|
|
47
|
+
const globalCfg = global.modes?.[mode] ?? {};
|
|
48
|
+
merged.modes[mode] = {
|
|
49
|
+
...globalCfg,
|
|
50
|
+
...projectCfg,
|
|
51
|
+
// Union both auto_allow lists so project can extend, not just replace
|
|
52
|
+
auto_allow: Array.from(new Set([...(globalCfg.auto_allow ?? []), ...(projectCfg.auto_allow ?? [])])),
|
|
53
|
+
// Union allowed_write_paths so project can extend
|
|
54
|
+
allowed_write_paths: Array.from(new Set([...(globalCfg.allowed_write_paths ?? []), ...(projectCfg.allowed_write_paths ?? [])])),
|
|
55
|
+
// enabled_tools: project wins if set, else falls back to global
|
|
56
|
+
enabled_tools: projectCfg.enabled_tools ?? globalCfg.enabled_tools,
|
|
57
|
+
// denied_tools: union so project can add more denied tools on top of global
|
|
58
|
+
denied_tools: Array.from(new Set([...(globalCfg.denied_tools ?? []), ...(projectCfg.denied_tools ?? [])])),
|
|
59
|
+
// allowed_bash_commands: project wins if set, else falls back to global
|
|
60
|
+
allowed_bash_commands: projectCfg.allowed_bash_commands ?? globalCfg.allowed_bash_commands,
|
|
61
|
+
// denied_bash_commands: union so project can add more denied patterns on top of global
|
|
62
|
+
denied_bash_commands: Array.from(new Set([...(globalCfg.denied_bash_commands ?? []), ...(projectCfg.denied_bash_commands ?? [])])),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (project.mode_paths || global.mode_paths) {
|
|
67
|
+
// Project paths first so they're searched before global paths
|
|
68
|
+
merged.mode_paths = dedupePaths([...(project.mode_paths ?? []), ...(global.mode_paths ?? [])]);
|
|
69
|
+
}
|
|
70
|
+
return merged;
|
|
71
|
+
}
|
|
72
|
+
function dedupePaths(paths) {
|
|
73
|
+
const seen = new Set();
|
|
74
|
+
const out = [];
|
|
75
|
+
for (const p of paths) {
|
|
76
|
+
if (!seen.has(p)) {
|
|
77
|
+
seen.add(p);
|
|
78
|
+
out.push(p);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
export function mergeSearchPaths(...sources) {
|
|
84
|
+
const merged = [];
|
|
85
|
+
for (const source of sources) {
|
|
86
|
+
if (!source)
|
|
87
|
+
continue;
|
|
88
|
+
merged.push(...source);
|
|
89
|
+
}
|
|
90
|
+
return dedupePaths(merged);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Reads the global config and optionally overlays the project-local config at
|
|
94
|
+
* `./.hoocode/hoo-config.json`. Project values win on all scalar fields; arrays are
|
|
95
|
+
* unioned (see mergeConfigs for full rules).
|
|
96
|
+
*/
|
|
97
|
+
export function readMergedConfig(cwd) {
|
|
98
|
+
const global = readConfig();
|
|
99
|
+
const projectPath = join(cwd, ".hoocode", "hoo-config.json");
|
|
100
|
+
if (!existsSync(projectPath))
|
|
101
|
+
return global;
|
|
102
|
+
try {
|
|
103
|
+
const project = JSON.parse(readFileSync(projectPath, "utf8"));
|
|
104
|
+
return mergeConfigs(global, project);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return global;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../src/extensions/core/config.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * hoo-config.json — types, I/O, and merge rules shared by the hoo-core extensions.\n *\n * Config merge order (lowest → highest priority):\n * 1. ~/.hoocode/hoo-config.json (global defaults)\n * 2. ./.hoocode/hoo-config.json (project overrides — scalars win; arrays union)\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ThinkingLevel } from \"@kolisachint/hoocode-agent-core\";\nimport { getHooCodeDir } from \"../../config.js\";\n\nconst HOOCODE_DIR = getHooCodeDir();\nconst GLOBAL_CONFIG_PATH = join(HOOCODE_DIR, \"hoo-config.json\");\n\nexport interface ModeConfig {\n\t/** Tool names that bypass the permission gate in this mode */\n\tauto_allow?: string[];\n\t/** Tool names available in this mode (if set, only these tools are active) */\n\tenabled_tools?: string[];\n\t/** Tool names explicitly blocked in this mode regardless of enabled_tools */\n\tdenied_tools?: string[];\n\t/** Allowed write paths in this mode (glob patterns, only applies if write/edit is enabled) */\n\tallowed_write_paths?: string[];\n\t/** Regex patterns for allowed bash commands. If set, a command must match at least one to execute. */\n\tallowed_bash_commands?: string[];\n\t/** Regex patterns for denied bash commands. A command matching any pattern is blocked. */\n\tdenied_bash_commands?: string[];\n}\n\n/**\n * Tool-outcome-driven thinking escalation (on by default).\n *\n * The default (fast) path keeps thinking low so mechanical tool turns — reads,\n * greps, successful edits — don't pay the extended-thinking prefill tax. When a\n * tool *fails*, the next turn(s) escalate to a higher thinking level so the model\n * reasons through the failure, then the level is restored. This buys low latency\n * on the happy path while preserving deep reasoning exactly when something breaks.\n *\n * Enabled by default; set `thinking_escalation.enabled` to `false` to turn it off.\n *\n * Note: escalation uses the same setter as manual thinking control, so the\n * escalated level is briefly written to settings and restored when the window\n * ends. If a run is interrupted mid-window, the escalated level may persist until\n * the next change.\n */\nexport interface ThinkingEscalationConfig {\n\t/** Master switch. Default: true (set to false to disable). */\n\tenabled?: boolean;\n\t/** Level to escalate to after a tool error. Default: \"high\". */\n\ton_error?: ThinkingLevel;\n\t/** Restrict escalation to errors from these tool names. Default: any tool. */\n\ttools?: string[];\n\t/** Number of subsequent turns to stay escalated after an error. Default: 1. */\n\tcooldown_turns?: number;\n}\n\nexport interface HooConfig {\n\t/** Manually-pinned active mode (overrides default \"build\") */\n\tactive_mode?: string;\n\t/** Per-mode configuration keyed by mode name */\n\tmodes?: Record<string, ModeConfig>;\n\t/** Extra directories to search for `{name}/system.md` mode files (after project + user). */\n\tmode_paths?: string[];\n\t/** Raise thinking after tool failures, restore on success. On by default; set `enabled: false` to disable. */\n\tthinking_escalation?: ThinkingEscalationConfig;\n}\n\nexport function readConfig(): HooConfig {\n\ttry {\n\t\treturn JSON.parse(readFileSync(GLOBAL_CONFIG_PATH, \"utf8\")) as HooConfig;\n\t} catch {\n\t\treturn {};\n\t}\n}\n\nexport function writeConfig(config: HooConfig): void {\n\tif (!existsSync(HOOCODE_DIR)) mkdirSync(HOOCODE_DIR, { recursive: true });\n\twriteFileSync(GLOBAL_CONFIG_PATH, `${JSON.stringify(config, null, 2)}\\n`, \"utf8\");\n}\n\n/**\n * Deep-merges a project-local config on top of the global config.\n *\n * Merge rules:\n * - active_mode: project wins if set\n * - modes[x].auto_allow: union of global + project arrays\n * - modes[x].allowed_write_paths: union of global + project arrays\n * - modes[x].enabled_tools: project wins if set, else falls back to global\n * - mode_paths: project list is prepended so project paths are searched first\n * - thinking_escalation: project wins as a whole if set, else inherit global\n */\nexport function mergeConfigs(global: HooConfig, project: HooConfig): HooConfig {\n\tconst merged: HooConfig = { ...global };\n\n\tif (project.active_mode !== undefined) merged.active_mode = project.active_mode;\n\n\t// thinking_escalation: project wins as a whole if set, else inherit global.\n\tif (project.thinking_escalation !== undefined) merged.thinking_escalation = project.thinking_escalation;\n\n\tif (project.modes) {\n\t\tmerged.modes = { ...(global.modes ?? {}) };\n\t\tfor (const [mode, projectCfg] of Object.entries(project.modes)) {\n\t\t\tconst globalCfg = global.modes?.[mode] ?? {};\n\t\t\tmerged.modes[mode] = {\n\t\t\t\t...globalCfg,\n\t\t\t\t...projectCfg,\n\t\t\t\t// Union both auto_allow lists so project can extend, not just replace\n\t\t\t\tauto_allow: Array.from(new Set([...(globalCfg.auto_allow ?? []), ...(projectCfg.auto_allow ?? [])])),\n\t\t\t\t// Union allowed_write_paths so project can extend\n\t\t\t\tallowed_write_paths: Array.from(\n\t\t\t\t\tnew Set([...(globalCfg.allowed_write_paths ?? []), ...(projectCfg.allowed_write_paths ?? [])]),\n\t\t\t\t),\n\t\t\t\t// enabled_tools: project wins if set, else falls back to global\n\t\t\t\tenabled_tools: projectCfg.enabled_tools ?? globalCfg.enabled_tools,\n\t\t\t\t// denied_tools: union so project can add more denied tools on top of global\n\t\t\t\tdenied_tools: Array.from(new Set([...(globalCfg.denied_tools ?? []), ...(projectCfg.denied_tools ?? [])])),\n\t\t\t\t// allowed_bash_commands: project wins if set, else falls back to global\n\t\t\t\tallowed_bash_commands: projectCfg.allowed_bash_commands ?? globalCfg.allowed_bash_commands,\n\t\t\t\t// denied_bash_commands: union so project can add more denied patterns on top of global\n\t\t\t\tdenied_bash_commands: Array.from(\n\t\t\t\t\tnew Set([...(globalCfg.denied_bash_commands ?? []), ...(projectCfg.denied_bash_commands ?? [])]),\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\t}\n\n\tif (project.mode_paths || global.mode_paths) {\n\t\t// Project paths first so they're searched before global paths\n\t\tmerged.mode_paths = dedupePaths([...(project.mode_paths ?? []), ...(global.mode_paths ?? [])]);\n\t}\n\n\treturn merged;\n}\n\nfunction dedupePaths(paths: string[]): string[] {\n\tconst seen = new Set<string>();\n\tconst out: string[] = [];\n\tfor (const p of paths) {\n\t\tif (!seen.has(p)) {\n\t\t\tseen.add(p);\n\t\t\tout.push(p);\n\t\t}\n\t}\n\treturn out;\n}\n\nexport function mergeSearchPaths(...sources: (string[] | undefined)[]): string[] {\n\tconst merged: string[] = [];\n\tfor (const source of sources) {\n\t\tif (!source) continue;\n\t\tmerged.push(...source);\n\t}\n\treturn dedupePaths(merged);\n}\n\n/**\n * Reads the global config and optionally overlays the project-local config at\n * `./.hoocode/hoo-config.json`. Project values win on all scalar fields; arrays are\n * unioned (see mergeConfigs for full rules).\n */\nexport function readMergedConfig(cwd: string): HooConfig {\n\tconst global = readConfig();\n\tconst projectPath = join(cwd, \".hoocode\", \"hoo-config.json\");\n\tif (!existsSync(projectPath)) return global;\n\ttry {\n\t\tconst project = JSON.parse(readFileSync(projectPath, \"utf8\")) as HooConfig;\n\t\treturn mergeConfigs(global, project);\n\t} catch {\n\t\treturn global;\n\t}\n}\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /cost — session token and cost totals.
|
|
3
|
+
*
|
|
4
|
+
* Walks every assistant message in the current session and sums tokens + cost,
|
|
5
|
+
* then prints a session total followed by a per-model breakdown.
|
|
6
|
+
* Per-tool attribution is intentionally not shown — tokens aren't tracked
|
|
7
|
+
* per-tool, and any heuristic would be misleading.
|
|
8
|
+
*/
|
|
9
|
+
import type { ExtensionAPI } from "../../core/extensions/types.js";
|
|
10
|
+
export declare function setupCost(pi: ExtensionAPI): void;
|
|
11
|
+
//# sourceMappingURL=cost.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../../../src/extensions/core/cost.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,gCAAgC,CAAC;AAE5F,wBAAgB,SAAS,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA2DhD","sourcesContent":["/**\n * /cost — session token and cost totals.\n *\n * Walks every assistant message in the current session and sums tokens + cost,\n * then prints a session total followed by a per-model breakdown.\n * Per-tool attribution is intentionally not shown — tokens aren't tracked\n * per-tool, and any heuristic would be misleading.\n */\n\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../core/extensions/types.js\";\n\nexport function setupCost(pi: ExtensionAPI): void {\n\tpi.registerCommand(\"cost\", {\n\t\tdescription: \"Show session token and cost totals, broken down by model.\",\n\t\tgetArgumentCompletions: () => [],\n\t\thandler: async (_args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\ttype Totals = { input: number; output: number; cacheRead: number; cacheWrite: number; cost: number };\n\t\t\tconst empty = (): Totals => ({ input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 });\n\t\t\tconst total = empty();\n\t\t\tconst perModel = new Map<string, Totals>();\n\t\t\tlet assistantTurns = 0;\n\n\t\t\tfor (const entry of ctx.sessionManager.getEntries()) {\n\t\t\t\tif (entry.type !== \"message\" || entry.message.role !== \"assistant\") continue;\n\t\t\t\tconst u = entry.message.usage;\n\t\t\t\tif (!u) continue;\n\t\t\t\tassistantTurns++;\n\t\t\t\ttotal.input += u.input;\n\t\t\t\ttotal.output += u.output;\n\t\t\t\ttotal.cacheRead += u.cacheRead;\n\t\t\t\ttotal.cacheWrite += u.cacheWrite;\n\t\t\t\ttotal.cost += u.cost.total;\n\n\t\t\t\tconst key = `${entry.message.provider}/${entry.message.model}`;\n\t\t\t\tconst t = perModel.get(key) ?? empty();\n\t\t\t\tt.input += u.input;\n\t\t\t\tt.output += u.output;\n\t\t\t\tt.cacheRead += u.cacheRead;\n\t\t\t\tt.cacheWrite += u.cacheWrite;\n\t\t\t\tt.cost += u.cost.total;\n\t\t\t\tperModel.set(key, t);\n\t\t\t}\n\n\t\t\tif (assistantTurns === 0) {\n\t\t\t\tctx.ui.notify(\"No assistant turns yet — nothing to cost.\", \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst fmt = (n: number) => n.toLocaleString();\n\t\t\tconst fmtCost = (n: number) => `$${n.toFixed(4)}`;\n\t\t\tconst lines: string[] = [];\n\t\t\tlines.push(`Session totals (${assistantTurns} assistant turn${assistantTurns === 1 ? \"\" : \"s\"})`);\n\t\t\tlines.push(` Input ${fmt(total.input)}`);\n\t\t\tlines.push(` Output ${fmt(total.output)}`);\n\t\t\tlines.push(` Cache read ${fmt(total.cacheRead)}`);\n\t\t\tlines.push(` Cache write ${fmt(total.cacheWrite)}`);\n\t\t\tlines.push(` Cost ${fmtCost(total.cost)}`);\n\n\t\t\tif (perModel.size > 1) {\n\t\t\t\tlines.push(\"\");\n\t\t\t\tlines.push(\"By model:\");\n\t\t\t\tconst sorted = [...perModel.entries()].sort((a, b) => b[1].cost - a[1].cost);\n\t\t\t\tfor (const [key, t] of sorted) {\n\t\t\t\t\tlines.push(` ${key}: ${fmt(t.input)} in / ${fmt(t.output)} out ${fmtCost(t.cost)}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tctx.ui.notify(lines.join(\"\\n\"), \"info\");\n\t\t},\n\t});\n}\n"]}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* /cost — session token and cost totals.
|
|
3
|
+
*
|
|
4
|
+
* Walks every assistant message in the current session and sums tokens + cost,
|
|
5
|
+
* then prints a session total followed by a per-model breakdown.
|
|
6
|
+
* Per-tool attribution is intentionally not shown — tokens aren't tracked
|
|
7
|
+
* per-tool, and any heuristic would be misleading.
|
|
8
|
+
*/
|
|
9
|
+
export function setupCost(pi) {
|
|
10
|
+
pi.registerCommand("cost", {
|
|
11
|
+
description: "Show session token and cost totals, broken down by model.",
|
|
12
|
+
getArgumentCompletions: () => [],
|
|
13
|
+
handler: async (_args, ctx) => {
|
|
14
|
+
const empty = () => ({ input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 });
|
|
15
|
+
const total = empty();
|
|
16
|
+
const perModel = new Map();
|
|
17
|
+
let assistantTurns = 0;
|
|
18
|
+
for (const entry of ctx.sessionManager.getEntries()) {
|
|
19
|
+
if (entry.type !== "message" || entry.message.role !== "assistant")
|
|
20
|
+
continue;
|
|
21
|
+
const u = entry.message.usage;
|
|
22
|
+
if (!u)
|
|
23
|
+
continue;
|
|
24
|
+
assistantTurns++;
|
|
25
|
+
total.input += u.input;
|
|
26
|
+
total.output += u.output;
|
|
27
|
+
total.cacheRead += u.cacheRead;
|
|
28
|
+
total.cacheWrite += u.cacheWrite;
|
|
29
|
+
total.cost += u.cost.total;
|
|
30
|
+
const key = `${entry.message.provider}/${entry.message.model}`;
|
|
31
|
+
const t = perModel.get(key) ?? empty();
|
|
32
|
+
t.input += u.input;
|
|
33
|
+
t.output += u.output;
|
|
34
|
+
t.cacheRead += u.cacheRead;
|
|
35
|
+
t.cacheWrite += u.cacheWrite;
|
|
36
|
+
t.cost += u.cost.total;
|
|
37
|
+
perModel.set(key, t);
|
|
38
|
+
}
|
|
39
|
+
if (assistantTurns === 0) {
|
|
40
|
+
ctx.ui.notify("No assistant turns yet — nothing to cost.", "info");
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const fmt = (n) => n.toLocaleString();
|
|
44
|
+
const fmtCost = (n) => `$${n.toFixed(4)}`;
|
|
45
|
+
const lines = [];
|
|
46
|
+
lines.push(`Session totals (${assistantTurns} assistant turn${assistantTurns === 1 ? "" : "s"})`);
|
|
47
|
+
lines.push(` Input ${fmt(total.input)}`);
|
|
48
|
+
lines.push(` Output ${fmt(total.output)}`);
|
|
49
|
+
lines.push(` Cache read ${fmt(total.cacheRead)}`);
|
|
50
|
+
lines.push(` Cache write ${fmt(total.cacheWrite)}`);
|
|
51
|
+
lines.push(` Cost ${fmtCost(total.cost)}`);
|
|
52
|
+
if (perModel.size > 1) {
|
|
53
|
+
lines.push("");
|
|
54
|
+
lines.push("By model:");
|
|
55
|
+
const sorted = [...perModel.entries()].sort((a, b) => b[1].cost - a[1].cost);
|
|
56
|
+
for (const [key, t] of sorted) {
|
|
57
|
+
lines.push(` ${key}: ${fmt(t.input)} in / ${fmt(t.output)} out ${fmtCost(t.cost)}`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
ctx.ui.notify(lines.join("\n"), "info");
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=cost.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost.js","sourceRoot":"","sources":["../../../src/extensions/core/cost.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * /cost — session token and cost totals.\n *\n * Walks every assistant message in the current session and sums tokens + cost,\n * then prints a session total followed by a per-model breakdown.\n * Per-tool attribution is intentionally not shown — tokens aren't tracked\n * per-tool, and any heuristic would be misleading.\n */\n\nimport type { ExtensionAPI, ExtensionCommandContext } from \"../../core/extensions/types.js\";\n\nexport function setupCost(pi: ExtensionAPI): void {\n\tpi.registerCommand(\"cost\", {\n\t\tdescription: \"Show session token and cost totals, broken down by model.\",\n\t\tgetArgumentCompletions: () => [],\n\t\thandler: async (_args: string, ctx: ExtensionCommandContext): Promise<void> => {\n\t\t\ttype Totals = { input: number; output: number; cacheRead: number; cacheWrite: number; cost: number };\n\t\t\tconst empty = (): Totals => ({ input: 0, output: 0, cacheRead: 0, cacheWrite: 0, cost: 0 });\n\t\t\tconst total = empty();\n\t\t\tconst perModel = new Map<string, Totals>();\n\t\t\tlet assistantTurns = 0;\n\n\t\t\tfor (const entry of ctx.sessionManager.getEntries()) {\n\t\t\t\tif (entry.type !== \"message\" || entry.message.role !== \"assistant\") continue;\n\t\t\t\tconst u = entry.message.usage;\n\t\t\t\tif (!u) continue;\n\t\t\t\tassistantTurns++;\n\t\t\t\ttotal.input += u.input;\n\t\t\t\ttotal.output += u.output;\n\t\t\t\ttotal.cacheRead += u.cacheRead;\n\t\t\t\ttotal.cacheWrite += u.cacheWrite;\n\t\t\t\ttotal.cost += u.cost.total;\n\n\t\t\t\tconst key = `${entry.message.provider}/${entry.message.model}`;\n\t\t\t\tconst t = perModel.get(key) ?? empty();\n\t\t\t\tt.input += u.input;\n\t\t\t\tt.output += u.output;\n\t\t\t\tt.cacheRead += u.cacheRead;\n\t\t\t\tt.cacheWrite += u.cacheWrite;\n\t\t\t\tt.cost += u.cost.total;\n\t\t\t\tperModel.set(key, t);\n\t\t\t}\n\n\t\t\tif (assistantTurns === 0) {\n\t\t\t\tctx.ui.notify(\"No assistant turns yet — nothing to cost.\", \"info\");\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst fmt = (n: number) => n.toLocaleString();\n\t\t\tconst fmtCost = (n: number) => `$${n.toFixed(4)}`;\n\t\t\tconst lines: string[] = [];\n\t\t\tlines.push(`Session totals (${assistantTurns} assistant turn${assistantTurns === 1 ? \"\" : \"s\"})`);\n\t\t\tlines.push(` Input ${fmt(total.input)}`);\n\t\t\tlines.push(` Output ${fmt(total.output)}`);\n\t\t\tlines.push(` Cache read ${fmt(total.cacheRead)}`);\n\t\t\tlines.push(` Cache write ${fmt(total.cacheWrite)}`);\n\t\t\tlines.push(` Cost ${fmtCost(total.cost)}`);\n\n\t\t\tif (perModel.size > 1) {\n\t\t\t\tlines.push(\"\");\n\t\t\t\tlines.push(\"By model:\");\n\t\t\t\tconst sorted = [...perModel.entries()].sort((a, b) => b[1].cost - a[1].cost);\n\t\t\t\tfor (const [key, t] of sorted) {\n\t\t\t\t\tlines.push(` ${key}: ${fmt(t.input)} in / ${fmt(t.output)} out ${fmtCost(t.cost)}`);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tctx.ui.notify(lines.join(\"\\n\"), \"info\");\n\t\t},\n\t});\n}\n"]}
|
|
@@ -1,185 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* hoo-core — HooCode built-in core extension
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
2
|
+
* hoo-core — HooCode built-in core extension (composition root).
|
|
3
|
+
*
|
|
4
|
+
* Each concern lives in its own module in this directory:
|
|
5
|
+
* - permission-gate.ts — prompts before bash/write/edit; hard tool/command policy
|
|
6
|
+
* - mcp-loader.ts — discovers MCP server configs, connects, registers tools
|
|
7
|
+
* - modes.ts — active mode resolution, mode prompts, /mode /plan /approve
|
|
8
|
+
* - cost.ts — /cost session token + cost totals
|
|
9
|
+
* - scaffold.ts — /new-skill /new-agent /new-command
|
|
10
|
+
* - ask-options.ts — the ask_options tool (inline decision pane)
|
|
11
|
+
* - thinking-escalation.ts — raise thinking after tool errors, then restore
|
|
12
|
+
* - loop.ts — /loop cron scheduling + autonomous continuation
|
|
13
|
+
* - marketplace.ts — /plugin marketplace + install/remove
|
|
14
|
+
* - config.ts — hoo-config.json types, I/O, and merge rules
|
|
15
|
+
*
|
|
16
|
+
* `bin/hoocode.js` loads this module's default export as the built-in
|
|
17
|
+
* extension factory.
|
|
16
18
|
*/
|
|
17
|
-
import type { ThinkingLevel } from "@kolisachint/hoocode-agent-core";
|
|
18
19
|
import type { ExtensionAPI } from "../../core/extensions/types.js";
|
|
19
|
-
interface ModeConfig {
|
|
20
|
-
/** Tool names that bypass the permission gate in this mode */
|
|
21
|
-
auto_allow?: string[];
|
|
22
|
-
/** Tool names available in this mode (if set, only these tools are active) */
|
|
23
|
-
enabled_tools?: string[];
|
|
24
|
-
/** Tool names explicitly blocked in this mode regardless of enabled_tools */
|
|
25
|
-
denied_tools?: string[];
|
|
26
|
-
/** Allowed write paths in this mode (glob patterns, only applies if write/edit is enabled) */
|
|
27
|
-
allowed_write_paths?: string[];
|
|
28
|
-
/** Regex patterns for allowed bash commands. If set, a command must match at least one to execute. */
|
|
29
|
-
allowed_bash_commands?: string[];
|
|
30
|
-
/** Regex patterns for denied bash commands. A command matching any pattern is blocked. */
|
|
31
|
-
denied_bash_commands?: string[];
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Tool-outcome-driven thinking escalation (on by default).
|
|
35
|
-
*
|
|
36
|
-
* The default (fast) path keeps thinking low so mechanical tool turns — reads,
|
|
37
|
-
* greps, successful edits — don't pay the extended-thinking prefill tax. When a
|
|
38
|
-
* tool *fails*, the next turn(s) escalate to a higher thinking level so the model
|
|
39
|
-
* reasons through the failure, then the level is restored. This buys low latency
|
|
40
|
-
* on the happy path while preserving deep reasoning exactly when something breaks.
|
|
41
|
-
*
|
|
42
|
-
* Enabled by default; set `thinking_escalation.enabled` to `false` to turn it off.
|
|
43
|
-
*
|
|
44
|
-
* Note: escalation uses the same setter as manual thinking control, so the
|
|
45
|
-
* escalated level is briefly written to settings and restored when the window
|
|
46
|
-
* ends. If a run is interrupted mid-window, the escalated level may persist until
|
|
47
|
-
* the next change.
|
|
48
|
-
*/
|
|
49
|
-
interface ThinkingEscalationConfig {
|
|
50
|
-
/** Master switch. Default: true (set to false to disable). */
|
|
51
|
-
enabled?: boolean;
|
|
52
|
-
/** Level to escalate to after a tool error. Default: "high". */
|
|
53
|
-
on_error?: ThinkingLevel;
|
|
54
|
-
/** Restrict escalation to errors from these tool names. Default: any tool. */
|
|
55
|
-
tools?: string[];
|
|
56
|
-
/** Number of subsequent turns to stay escalated after an error. Default: 1. */
|
|
57
|
-
cooldown_turns?: number;
|
|
58
|
-
}
|
|
59
|
-
export interface HooConfig {
|
|
60
|
-
/** Manually-pinned active mode (overrides default "build") */
|
|
61
|
-
active_mode?: string;
|
|
62
|
-
/** Per-mode configuration keyed by mode name */
|
|
63
|
-
modes?: Record<string, ModeConfig>;
|
|
64
|
-
/** Extra directories to search for `{name}/system.md` mode files (after project + user). */
|
|
65
|
-
mode_paths?: string[];
|
|
66
|
-
/** Raise thinking after tool failures, restore on success. On by default; set `enabled: false` to disable. */
|
|
67
|
-
thinking_escalation?: ThinkingEscalationConfig;
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* Deep-merges a project-local config on top of the global config.
|
|
71
|
-
*
|
|
72
|
-
* Merge rules:
|
|
73
|
-
* - active_mode: project wins if set
|
|
74
|
-
* - modes[x].auto_allow: union of global + project arrays
|
|
75
|
-
* - modes[x].allowed_write_paths: union of global + project arrays
|
|
76
|
-
* - modes[x].enabled_tools: project wins if set, else falls back to global
|
|
77
|
-
* - mode_paths: project list is prepended so project paths are searched first
|
|
78
|
-
* - thinking_escalation: project wins as a whole if set, else inherit global
|
|
79
|
-
*/
|
|
80
|
-
export declare function mergeConfigs(global: HooConfig, project: HooConfig): HooConfig;
|
|
81
|
-
/**
|
|
82
|
-
* Reads the global config and optionally overlays the project-local config at
|
|
83
|
-
* `./.hoocode/hoo-config.json`. Project values win on all scalar fields; arrays are
|
|
84
|
-
* unioned (see mergeConfigs for full rules).
|
|
85
|
-
*/
|
|
86
|
-
export declare function readMergedConfig(cwd: string): HooConfig;
|
|
87
|
-
export declare function setupPermissionGate(pi: ExtensionAPI): void;
|
|
88
|
-
export interface McpServerConfig {
|
|
89
|
-
/** Unique server identifier used as prefix for registered tool names */
|
|
90
|
-
name: string;
|
|
91
|
-
/** Executable to spawn */
|
|
92
|
-
command: string;
|
|
93
|
-
/** Optional arguments passed to the command */
|
|
94
|
-
args?: string[];
|
|
95
|
-
/** Optional extra environment variables for the server process */
|
|
96
|
-
env?: Record<string, string>;
|
|
97
|
-
/** Run MCP tools in background by default (default: true for MCP servers) */
|
|
98
|
-
background?: boolean;
|
|
99
|
-
}
|
|
100
|
-
export declare function setupMcpLoader(pi: ExtensionAPI): void;
|
|
101
|
-
/**
|
|
102
|
-
* Returns the system prompt for the active mode.
|
|
103
|
-
*
|
|
104
|
-
* Search order (first hit wins):
|
|
105
|
-
* - `./.hoocode/modes/{mode}/system.md`
|
|
106
|
-
* - `~/.hoocode/modes/{mode}/system.md`
|
|
107
|
-
* - each of `externalDirs` in declared order (config + CLI + extension contributions)
|
|
108
|
-
* - built-in MODE_DEFAULTS for the four known modes
|
|
109
|
-
*/
|
|
110
|
-
export declare function buildSystemPrompt(mode: string, cwd: string, options?: {
|
|
111
|
-
modePaths?: string[];
|
|
112
|
-
}): string | undefined;
|
|
113
|
-
export interface PlanSections {
|
|
114
|
-
goal?: string;
|
|
115
|
-
filesToModify?: string;
|
|
116
|
-
newFiles?: string;
|
|
117
|
-
tests?: string;
|
|
118
|
-
verification?: string;
|
|
119
|
-
/** Original full text, used as fallback if no sections parsed */
|
|
120
|
-
raw: string;
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Parses `.hoocode/plan.md` into named sections.
|
|
124
|
-
*
|
|
125
|
-
* Recognises both ATX headings (`## Goal`) and bold labels (`**Goal**`).
|
|
126
|
-
* Section names matched (case-insensitive): Goal, Files to modify, New files,
|
|
127
|
-
* Tests, Verification.
|
|
128
|
-
*/
|
|
129
|
-
export declare function parsePlanSections(planContent: string): PlanSections;
|
|
130
|
-
/**
|
|
131
|
-
* Builds the user message sent to the agent when `/approve` is run.
|
|
132
|
-
*
|
|
133
|
-
* If the plan has recognisable sections, each is presented as a numbered step
|
|
134
|
-
* so the agent works through them sequentially. Otherwise the raw plan is used.
|
|
135
|
-
*
|
|
136
|
-
* Execution order:
|
|
137
|
-
* 1. Modify existing files
|
|
138
|
-
* 2. Create new files
|
|
139
|
-
* 3. Update / add tests
|
|
140
|
-
* 4. Run verification commands
|
|
141
|
-
*/
|
|
142
|
-
export declare function buildApproveMessage(sections: PlanSections): string;
|
|
143
|
-
export declare function setupMode(pi: ExtensionAPI): void;
|
|
144
|
-
export declare function setupAskOptions(pi: ExtensionAPI): void;
|
|
145
|
-
/**
|
|
146
|
-
* Raise the thinking level for the turn(s) following a tool error, then restore
|
|
147
|
-
* it. Opt-in via `thinking_escalation.enabled` in hoo-config.json.
|
|
148
|
-
*
|
|
149
|
-
* Timing model (per agent run):
|
|
150
|
-
* turn N: assistant calls tools → tool_execution_end(s) → turn_end
|
|
151
|
-
* a failing tool here escalates the level used by turn N+1
|
|
152
|
-
* turn N+1: runs escalated; its turn_end decrements the cooldown and, at zero,
|
|
153
|
-
* restores the captured baseline so turn N+2 is fast again
|
|
154
|
-
*
|
|
155
|
-
* `escalatedThisTurn` ensures the error turn's own `turn_end` does not consume a
|
|
156
|
-
* cooldown step — the cooldown counts the turns *after* the failure.
|
|
157
|
-
*/
|
|
158
|
-
export declare function setupThinkingEscalation(pi: ExtensionAPI): void;
|
|
159
|
-
/**
|
|
160
|
-
* `/loop` schedules prompts via cron and drives autonomous continuation. The same
|
|
161
|
-
* scheduler backs the agent-callable CronCreate/CronList/CronDelete tools.
|
|
162
|
-
*
|
|
163
|
-
* /loop "<cron>" <prompt> schedule recurring (5-field cron, local time)
|
|
164
|
-
* /loop <5m|2h|1d> <prompt> schedule recurring at a simple interval
|
|
165
|
-
* /loop once "<cron>" <prompt> schedule a one-shot
|
|
166
|
-
* /loop list | /loop delete <id> | /loop stop
|
|
167
|
-
* /loop auto [--max-turns N] <task> keep iterating until the task says LOOP_DONE
|
|
168
|
-
*/
|
|
169
|
-
export declare function setupLoop(pi: ExtensionAPI): void;
|
|
170
|
-
/**
|
|
171
|
-
* `/plugin` installs plugins from marketplaces (a git repo or local dir with a
|
|
172
|
-
* Claude `.claude-plugin/marketplace.json` or Copilot-style `.github/marketplace.json`
|
|
173
|
-
* index). Installed plugins are placed in `.hoocode/plugins/<name>` and loaded by the
|
|
174
|
-
* plugin loader after a reload.
|
|
175
|
-
*
|
|
176
|
-
* /plugin marketplace add <git-url|path>
|
|
177
|
-
* /plugin marketplace list
|
|
178
|
-
* /plugin list list available plugins across marketplaces
|
|
179
|
-
* /plugin install <name>
|
|
180
|
-
* /plugin remove <name>
|
|
181
|
-
*/
|
|
182
|
-
export declare function setupMarketplace(pi: ExtensionAPI): void;
|
|
183
20
|
declare function hooCore(pi: ExtensionAPI): void;
|
|
184
21
|
declare namespace hooCore {
|
|
185
22
|
var displayName: string;
|