@kolisachint/hoocode-agent 0.4.162 → 0.4.164
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 +29 -0
- package/dist/cli/args.d.ts +0 -6
- package/dist/cli/args.d.ts.map +1 -1
- package/dist/cli/args.js +0 -31
- package/dist/cli/args.js.map +1 -1
- package/dist/config.d.ts +0 -40
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -50
- package/dist/config.js.map +1 -1
- package/dist/core/agent-frontmatter.d.ts +0 -28
- package/dist/core/agent-frontmatter.d.ts.map +1 -1
- package/dist/core/agent-frontmatter.js +0 -6
- package/dist/core/agent-frontmatter.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +0 -2
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +0 -2
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +0 -2
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/auth-guidance.d.ts +0 -1
- package/dist/core/auth-guidance.d.ts.map +1 -1
- package/dist/core/auth-guidance.js +1 -1
- package/dist/core/auth-guidance.js.map +1 -1
- package/dist/core/embsearch/chunker.d.ts +0 -2
- package/dist/core/embsearch/chunker.d.ts.map +1 -1
- package/dist/core/embsearch/chunker.js +1 -1
- package/dist/core/embsearch/chunker.js.map +1 -1
- package/dist/core/embsearch/index-meta.d.ts +0 -2
- package/dist/core/embsearch/index-meta.d.ts.map +1 -1
- package/dist/core/embsearch/index-meta.js +0 -6
- package/dist/core/embsearch/index-meta.js.map +1 -1
- package/dist/core/export-html/ansi-to-html.d.ts +0 -4
- package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
- package/dist/core/export-html/ansi-to-html.js +1 -1
- package/dist/core/export-html/ansi-to-html.js.map +1 -1
- package/dist/core/extensions/index.d.ts +3 -3
- package/dist/core/extensions/index.d.ts.map +1 -1
- package/dist/core/extensions/index.js +1 -1
- package/dist/core/extensions/index.js.map +1 -1
- package/dist/core/extensions/plugins/authoring.d.ts +2 -2
- package/dist/core/extensions/plugins/authoring.d.ts.map +1 -1
- package/dist/core/extensions/plugins/authoring.js +0 -0
- package/dist/core/extensions/plugins/authoring.js.map +1 -1
- package/dist/core/extensions/plugins/formats/index.d.ts +2 -6
- package/dist/core/extensions/plugins/formats/index.d.ts.map +1 -1
- package/dist/core/extensions/plugins/formats/index.js +2 -3
- package/dist/core/extensions/plugins/formats/index.js.map +1 -1
- package/dist/core/extensions/plugins/formats/shared.d.ts +0 -2
- package/dist/core/extensions/plugins/formats/shared.d.ts.map +1 -1
- package/dist/core/extensions/plugins/formats/shared.js +1 -1
- package/dist/core/extensions/plugins/formats/shared.js.map +1 -1
- package/dist/core/extensions/plugins/formats/types.d.ts +4 -3
- package/dist/core/extensions/plugins/formats/types.d.ts.map +1 -1
- package/dist/core/extensions/plugins/formats/types.js.map +1 -1
- package/dist/core/extensions/plugins/install.d.ts +0 -2
- package/dist/core/extensions/plugins/install.d.ts.map +1 -1
- package/dist/core/extensions/plugins/install.js +1 -1
- package/dist/core/extensions/plugins/install.js.map +1 -1
- package/dist/core/extensions/plugins/manifest.d.ts +0 -6
- package/dist/core/extensions/plugins/manifest.d.ts.map +1 -1
- package/dist/core/extensions/plugins/manifest.js +0 -6
- package/dist/core/extensions/plugins/manifest.js.map +1 -1
- package/dist/core/extensions/plugins/marketplace.d.ts +3 -3
- package/dist/core/extensions/plugins/marketplace.d.ts.map +1 -1
- package/dist/core/extensions/plugins/marketplace.js.map +1 -1
- package/dist/core/extensions/types.d.ts +28 -28
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/keybindings.d.ts +3 -3
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-resolver.d.ts +0 -7
- package/dist/core/model-resolver.d.ts.map +1 -1
- package/dist/core/model-resolver.js +0 -56
- package/dist/core/model-resolver.js.map +1 -1
- package/dist/core/package-resource-discovery.d.ts +0 -10
- package/dist/core/package-resource-discovery.d.ts.map +1 -1
- package/dist/core/package-resource-discovery.js +7 -7
- package/dist/core/package-resource-discovery.js.map +1 -1
- package/dist/core/provider-health.d.ts +0 -2
- package/dist/core/provider-health.d.ts.map +1 -1
- package/dist/core/provider-health.js +1 -1
- package/dist/core/provider-health.js.map +1 -1
- package/dist/core/resolve-config-value.d.ts +0 -4
- package/dist/core/resolve-config-value.d.ts.map +1 -1
- package/dist/core/resolve-config-value.js +0 -15
- package/dist/core/resolve-config-value.js.map +1 -1
- package/dist/core/sdk.d.ts +3 -23
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +3 -5
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/search/eval.d.ts +0 -3
- package/dist/core/search/eval.d.ts.map +1 -1
- package/dist/core/search/eval.js +1 -1
- package/dist/core/search/eval.js.map +1 -1
- package/dist/core/search/types.d.ts +2 -1
- package/dist/core/search/types.d.ts.map +1 -1
- package/dist/core/search/types.js.map +1 -1
- package/dist/core/session-cwd.d.ts +0 -1
- package/dist/core/session-cwd.d.ts.map +1 -1
- package/dist/core/session-cwd.js +1 -1
- package/dist/core/session-cwd.js.map +1 -1
- package/dist/core/settings-defaults.d.ts +0 -3
- package/dist/core/settings-defaults.d.ts.map +1 -1
- package/dist/core/settings-defaults.js +0 -3
- package/dist/core/settings-defaults.js.map +1 -1
- package/dist/core/settings-manager.d.ts +2 -9
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +0 -25
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/settings-types.d.ts +9 -11
- package/dist/core/settings-types.d.ts.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/core/subagent-inbox.d.ts +1 -3
- package/dist/core/subagent-inbox.d.ts.map +1 -1
- package/dist/core/subagent-inbox.js +1 -1
- package/dist/core/subagent-inbox.js.map +1 -1
- package/dist/core/subagent-pool.d.ts +0 -13
- package/dist/core/subagent-pool.d.ts.map +1 -1
- package/dist/core/subagent-pool.js +2 -2
- package/dist/core/subagent-pool.js.map +1 -1
- package/dist/core/task-store.d.ts +3 -3
- package/dist/core/task-store.d.ts.map +1 -1
- package/dist/core/task-store.js.map +1 -1
- package/dist/core/team-auto.d.ts +0 -2
- package/dist/core/team-auto.d.ts.map +1 -1
- package/dist/core/team-auto.js +1 -1
- package/dist/core/team-auto.js.map +1 -1
- package/dist/core/token-budget.d.ts +0 -13
- package/dist/core/token-budget.d.ts.map +1 -1
- package/dist/core/token-budget.js.map +1 -1
- package/dist/core/tools/bash.d.ts.map +1 -1
- package/dist/core/tools/bash.js +3 -1
- package/dist/core/tools/bash.js.map +1 -1
- package/dist/core/tools/edit-diff.d.ts +0 -38
- package/dist/core/tools/edit-diff.d.ts.map +1 -1
- package/dist/core/tools/edit-diff.js +2 -9
- package/dist/core/tools/edit-diff.js.map +1 -1
- package/dist/core/tools/edit.d.ts.map +1 -1
- package/dist/core/tools/edit.js +5 -5
- package/dist/core/tools/edit.js.map +1 -1
- package/dist/core/tools/find.d.ts.map +1 -1
- package/dist/core/tools/find.js +8 -10
- package/dist/core/tools/find.js.map +1 -1
- package/dist/core/tools/grep.d.ts.map +1 -1
- package/dist/core/tools/grep.js +4 -4
- package/dist/core/tools/grep.js.map +1 -1
- package/dist/core/tools/index.d.ts +0 -24
- package/dist/core/tools/index.d.ts.map +1 -1
- package/dist/core/tools/index.js +0 -20
- package/dist/core/tools/index.js.map +1 -1
- package/dist/core/tools/ls.d.ts.map +1 -1
- package/dist/core/tools/ls.js +2 -2
- package/dist/core/tools/ls.js.map +1 -1
- package/dist/core/tools/native-search.d.ts +3 -2
- package/dist/core/tools/native-search.d.ts.map +1 -1
- package/dist/core/tools/native-search.js.map +1 -1
- package/dist/core/tools/path-utils.d.ts +0 -10
- package/dist/core/tools/path-utils.d.ts.map +1 -1
- package/dist/core/tools/path-utils.js +2 -2
- package/dist/core/tools/path-utils.js.map +1 -1
- package/dist/core/tools/plugins.d.ts +1 -20
- package/dist/core/tools/plugins.d.ts.map +1 -1
- package/dist/core/tools/plugins.js +2 -2
- package/dist/core/tools/plugins.js.map +1 -1
- package/dist/core/tools/propose-plugin.d.ts +0 -12
- package/dist/core/tools/propose-plugin.d.ts.map +1 -1
- package/dist/core/tools/propose-plugin.js +0 -1
- package/dist/core/tools/propose-plugin.js.map +1 -1
- package/dist/core/tools/read-dedup.d.ts +0 -2
- package/dist/core/tools/read-dedup.d.ts.map +1 -1
- package/dist/core/tools/read-dedup.js +1 -1
- package/dist/core/tools/read-dedup.js.map +1 -1
- package/dist/core/tools/read.d.ts.map +1 -1
- package/dist/core/tools/read.js +10 -8
- package/dist/core/tools/read.js.map +1 -1
- package/dist/core/tools/render-utils.d.ts +0 -5
- package/dist/core/tools/render-utils.d.ts.map +1 -1
- package/dist/core/tools/render-utils.js.map +1 -1
- package/dist/core/tools/search.d.ts +1 -4
- package/dist/core/tools/search.d.ts.map +1 -1
- package/dist/core/tools/search.js +6 -6
- package/dist/core/tools/search.js.map +1 -1
- package/dist/core/tools/webfetch.d.ts +1 -2
- package/dist/core/tools/webfetch.d.ts.map +1 -1
- package/dist/core/tools/webfetch.js.map +1 -1
- package/dist/core/tools/websearch.d.ts +1 -2
- package/dist/core/tools/websearch.d.ts.map +1 -1
- package/dist/core/tools/websearch.js.map +1 -1
- package/dist/core/tools/webtools-shared.d.ts +3 -5
- package/dist/core/tools/webtools-shared.d.ts.map +1 -1
- package/dist/core/tools/webtools-shared.js +1 -1
- package/dist/core/tools/webtools-shared.js.map +1 -1
- package/dist/core/warm-subagent-pool-instance.d.ts +0 -4
- package/dist/core/warm-subagent-pool-instance.d.ts.map +1 -1
- package/dist/core/warm-subagent-pool-instance.js +0 -10
- package/dist/core/warm-subagent-pool-instance.js.map +1 -1
- package/dist/core/wordmark.d.ts +1 -9
- package/dist/core/wordmark.d.ts.map +1 -1
- package/dist/core/wordmark.js +2 -26
- package/dist/core/wordmark.js.map +1 -1
- package/dist/extensions/core/config.d.ts +4 -3
- package/dist/extensions/core/config.d.ts.map +1 -1
- package/dist/extensions/core/config.js.map +1 -1
- package/dist/extensions/core/mcp-loader.d.ts +0 -18
- package/dist/extensions/core/mcp-loader.d.ts.map +1 -1
- package/dist/extensions/core/mcp-loader.js.map +1 -1
- package/dist/extensions/core/prompt-reactive/policy.d.ts +0 -8
- package/dist/extensions/core/prompt-reactive/policy.d.ts.map +1 -1
- package/dist/extensions/core/prompt-reactive/policy.js +1 -1
- package/dist/extensions/core/prompt-reactive/policy.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +0 -30
- package/dist/main.js.map +1 -1
- package/dist/migrations.d.ts +0 -16
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +2 -2
- package/dist/migrations.js.map +1 -1
- package/dist/modes/interactive/brand.d.ts +0 -4
- package/dist/modes/interactive/brand.d.ts.map +1 -1
- package/dist/modes/interactive/brand.js +0 -4
- package/dist/modes/interactive/brand.js.map +1 -1
- package/dist/modes/interactive/components/index.d.ts +0 -4
- package/dist/modes/interactive/components/index.d.ts.map +1 -1
- package/dist/modes/interactive/components/index.js +0 -5
- package/dist/modes/interactive/components/index.js.map +1 -1
- package/dist/modes/interactive/components/read-output.d.ts +0 -9
- package/dist/modes/interactive/components/read-output.d.ts.map +1 -1
- package/dist/modes/interactive/components/read-output.js +0 -20
- package/dist/modes/interactive/components/read-output.js.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.d.ts +0 -17
- package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
- package/dist/modes/interactive/components/session-selector-search.js +2 -2
- package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +5 -14
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +2 -2
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +0 -18
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/login-controller.d.ts +1 -1
- package/dist/modes/interactive/login-controller.d.ts.map +1 -1
- package/dist/modes/interactive/login-controller.js +1 -1
- package/dist/modes/interactive/login-controller.js.map +1 -1
- package/dist/modes/interactive/resource-display.d.ts +0 -20
- package/dist/modes/interactive/resource-display.d.ts.map +1 -1
- package/dist/modes/interactive/resource-display.js +7 -7
- package/dist/modes/interactive/resource-display.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts +0 -4
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +0 -7
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/rpc/rpc-mode.d.ts +0 -1
- package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-mode.js.map +1 -1
- package/dist/modes/rpc/rpc-types.d.ts +0 -1
- package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
- package/dist/modes/rpc/rpc-types.js +3 -0
- package/dist/modes/rpc/rpc-types.js.map +1 -1
- package/dist/package-manager-cli.d.ts +0 -1
- package/dist/package-manager-cli.d.ts.map +1 -1
- package/dist/package-manager-cli.js.map +1 -1
- package/dist/utils/changelog.d.ts +0 -4
- package/dist/utils/changelog.d.ts.map +1 -1
- package/dist/utils/changelog.js +1 -1
- package/dist/utils/changelog.js.map +1 -1
- package/dist/utils/clipboard-native.d.ts +1 -1
- package/dist/utils/clipboard-native.d.ts.map +1 -1
- package/dist/utils/clipboard-native.js.map +1 -1
- package/dist/utils/paths.d.ts +0 -2
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +1 -1
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/plan/parser.d.ts +5 -4
- package/dist/utils/plan/parser.d.ts.map +1 -1
- package/dist/utils/plan/parser.js.map +1 -1
- package/dist/utils/tools-manager.d.ts +1 -2
- package/dist/utils/tools-manager.d.ts.map +1 -1
- package/dist/utils/tools-manager.js +2 -50
- package/dist/utils/tools-manager.js.map +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 -7
- package/dist/core/index.d.ts +0 -12
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -12
- package/dist/core/index.js.map +0 -1
- package/dist/core/tools/browser/browser-continue.d.ts +0 -25
- package/dist/core/tools/browser/browser-continue.d.ts.map +0 -1
- package/dist/core/tools/browser/browser-continue.js +0 -84
- package/dist/core/tools/browser/browser-continue.js.map +0 -1
- package/dist/core/tools/browser/browser-run.d.ts +0 -48
- package/dist/core/tools/browser/browser-run.d.ts.map +0 -1
- package/dist/core/tools/browser/browser-run.js +0 -377
- package/dist/core/tools/browser/browser-run.js.map +0 -1
- package/dist/core/tools/browser/browsertools-shared.d.ts +0 -190
- package/dist/core/tools/browser/browsertools-shared.d.ts.map +0 -1
- package/dist/core/tools/browser/browsertools-shared.js +0 -335
- package/dist/core/tools/browser/browsertools-shared.js.map +0 -1
- package/dist/core/tools/browser/index.d.ts +0 -8
- package/dist/core/tools/browser/index.d.ts.map +0 -1
- package/dist/core/tools/browser/index.js +0 -8
- package/dist/core/tools/browser/index.js.map +0 -1
- package/dist/core/tools/doc/docedit.d.ts +0 -44
- package/dist/core/tools/doc/docedit.d.ts.map +0 -1
- package/dist/core/tools/doc/docedit.js +0 -133
- package/dist/core/tools/doc/docedit.js.map +0 -1
- package/dist/core/tools/doc/docgrep.d.ts +0 -28
- package/dist/core/tools/doc/docgrep.d.ts.map +0 -1
- package/dist/core/tools/doc/docgrep.js +0 -106
- package/dist/core/tools/doc/docgrep.js.map +0 -1
- package/dist/core/tools/doc/docpeek.d.ts +0 -25
- package/dist/core/tools/doc/docpeek.d.ts.map +0 -1
- package/dist/core/tools/doc/docpeek.js +0 -112
- package/dist/core/tools/doc/docpeek.js.map +0 -1
- package/dist/core/tools/doc/docread.d.ts +0 -32
- package/dist/core/tools/doc/docread.d.ts.map +0 -1
- package/dist/core/tools/doc/docread.js +0 -113
- package/dist/core/tools/doc/docread.js.map +0 -1
- package/dist/core/tools/doc/docscan.d.ts +0 -29
- package/dist/core/tools/doc/docscan.d.ts.map +0 -1
- package/dist/core/tools/doc/docscan.js +0 -110
- package/dist/core/tools/doc/docscan.js.map +0 -1
- package/dist/core/tools/doc/docwrite.d.ts +0 -44
- package/dist/core/tools/doc/docwrite.d.ts.map +0 -1
- package/dist/core/tools/doc/docwrite.js +0 -102
- package/dist/core/tools/doc/docwrite.js.map +0 -1
- package/dist/core/tools/doc/index.d.ts +0 -11
- package/dist/core/tools/doc/index.d.ts.map +0 -1
- package/dist/core/tools/doc/index.js +0 -11
- package/dist/core/tools/doc/index.js.map +0 -1
- package/dist/core/tools/filetools-shared.d.ts +0 -271
- package/dist/core/tools/filetools-shared.d.ts.map +0 -1
- package/dist/core/tools/filetools-shared.js +0 -403
- package/dist/core/tools/filetools-shared.js.map +0 -1
|
@@ -85,29 +85,6 @@ const TOOLS = {
|
|
|
85
85
|
return null;
|
|
86
86
|
},
|
|
87
87
|
},
|
|
88
|
-
browsertools: {
|
|
89
|
-
name: "browsertools",
|
|
90
|
-
repo: "kolisachint/browsertools",
|
|
91
|
-
binaryName: "browsertools",
|
|
92
|
-
tagPrefix: "v",
|
|
93
|
-
// Release archives follow Rust target triples: browsertools-<arch>-<target>.<ext>
|
|
94
|
-
// (release.yml builds gnu + musl for linux; we prefer the gnu variant to match
|
|
95
|
-
// webtools/filetools). A missing platform asset 404s and ensureTool degrades
|
|
96
|
-
// gracefully (returns undefined; the browser tools then surface an error).
|
|
97
|
-
getAssetName: (_version, plat, architecture) => {
|
|
98
|
-
const archStr = architecture === "arm64" ? "aarch64" : "x86_64";
|
|
99
|
-
if (plat === "darwin") {
|
|
100
|
-
return `browsertools-${archStr}-apple-darwin.tar.gz`;
|
|
101
|
-
}
|
|
102
|
-
else if (plat === "linux") {
|
|
103
|
-
return `browsertools-${archStr}-unknown-linux-gnu.tar.gz`;
|
|
104
|
-
}
|
|
105
|
-
else if (plat === "win32") {
|
|
106
|
-
return `browsertools-${archStr}-pc-windows-msvc.zip`;
|
|
107
|
-
}
|
|
108
|
-
return null;
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
88
|
voicetools: {
|
|
112
89
|
name: "voicetools",
|
|
113
90
|
repo: "kolisachint/voicetools",
|
|
@@ -130,29 +107,6 @@ const TOOLS = {
|
|
|
130
107
|
return null;
|
|
131
108
|
},
|
|
132
109
|
},
|
|
133
|
-
filetools: {
|
|
134
|
-
name: "filetools",
|
|
135
|
-
repo: "kolisachint/filetools",
|
|
136
|
-
binaryName: "filetools",
|
|
137
|
-
tagPrefix: "v",
|
|
138
|
-
// Release archives are named `filetools-<target-triple>.<ext>` (see the repo's
|
|
139
|
-
// release.yml `archive: filetools-$target`). A missing platform asset 404s and
|
|
140
|
-
// ensureTool degrades gracefully (returns undefined; the doc tools then surface
|
|
141
|
-
// an error result).
|
|
142
|
-
getAssetName: (_version, plat, architecture) => {
|
|
143
|
-
const archStr = architecture === "arm64" ? "aarch64" : "x86_64";
|
|
144
|
-
if (plat === "darwin") {
|
|
145
|
-
return `filetools-${archStr}-apple-darwin.tar.gz`;
|
|
146
|
-
}
|
|
147
|
-
else if (plat === "linux") {
|
|
148
|
-
return `filetools-${archStr}-unknown-linux-gnu.tar.gz`;
|
|
149
|
-
}
|
|
150
|
-
else if (plat === "win32") {
|
|
151
|
-
return `filetools-${archStr}-pc-windows-msvc.zip`;
|
|
152
|
-
}
|
|
153
|
-
return null;
|
|
154
|
-
},
|
|
155
|
-
},
|
|
156
110
|
embsearch: {
|
|
157
111
|
name: "embsearch",
|
|
158
112
|
repo: "kolisachint/embeddingsearchtools",
|
|
@@ -193,11 +147,11 @@ function commandExists(cmd) {
|
|
|
193
147
|
// commandExists() on every grep/find/glob invocation, which blocks the event loop.
|
|
194
148
|
const resolvedToolPathCache = new Map();
|
|
195
149
|
// Get the path to a tool (system-wide or in our tools dir)
|
|
196
|
-
|
|
150
|
+
function getToolPath(tool) {
|
|
197
151
|
const config = TOOLS[tool];
|
|
198
152
|
if (!config)
|
|
199
153
|
return null;
|
|
200
|
-
// Explicit binary override (per-tool env var, e.g.
|
|
154
|
+
// Explicit binary override (per-tool env var, e.g. HOOCODE_WEBTOOLS_BINARY).
|
|
201
155
|
// Lets a developer point at a locally built binary that predates a release,
|
|
202
156
|
// bypassing the tools-dir/PATH resolution and download. Authoritative when set
|
|
203
157
|
// and the path exists.
|
|
@@ -430,8 +384,6 @@ const TERMUX_PACKAGES = {
|
|
|
430
384
|
fd: "fd",
|
|
431
385
|
rg: "ripgrep",
|
|
432
386
|
webtools: "webtools",
|
|
433
|
-
filetools: "filetools",
|
|
434
|
-
browsertools: "browsertools",
|
|
435
387
|
voicetools: "voicetools",
|
|
436
388
|
embsearch: "embsearch",
|
|
437
389
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools-manager.js","sourceRoot":"","sources":["../../src/utils/tools-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from \"chalk\";\nimport { spawnSync } from \"child_process\";\nimport { createHash, randomBytes } from \"crypto\";\nimport extractZip from \"extract-zip\";\nimport {\n\tchmodSync,\n\tcreateWriteStream,\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trenameSync,\n\trmSync,\n\tstatSync,\n} from \"fs\";\nimport { arch, platform } from \"os\";\nimport { join } from \"path\";\nimport { Readable } from \"stream\";\nimport { pipeline } from \"stream/promises\";\nimport { APP_NAME, getBinDir } from \"../config.js\";\n\nconst TOOLS_DIR = getBinDir();\nconst NETWORK_TIMEOUT_MS = 10_000;\nconst DOWNLOAD_TIMEOUT_MS = 120_000;\n\nfunction isOfflineModeEnabled(): boolean {\n\tconst value = process.env.HOOCODE_OFFLINE;\n\tif (!value) return false;\n\treturn value === \"1\" || value.toLowerCase() === \"true\" || value.toLowerCase() === \"yes\";\n}\n\n/** Tools whose binaries hoocode can resolve from PATH or download on demand. */\nexport type ManagedTool = \"fd\" | \"rg\" | \"webtools\" | \"filetools\" | \"browsertools\" | \"voicetools\" | \"embsearch\";\n\ninterface ToolConfig {\n\tname: string;\n\trepo: string; // GitHub repo (e.g., \"sharkdp/fd\")\n\tbinaryName: string; // Name of the binary inside the archive\n\tsystemBinaryNames?: string[]; // Alternative system command names to try before downloading\n\ttagPrefix: string; // Prefix for tags (e.g., \"v\" for v1.0.0, \"\" for 1.0.0)\n\tgetAssetName: (version: string, plat: string, architecture: string) => string | null;\n}\n\nconst TOOLS: Record<string, ToolConfig> = {\n\tfd: {\n\t\tname: \"fd\",\n\t\trepo: \"sharkdp/fd\",\n\t\tbinaryName: \"fd\",\n\t\tsystemBinaryNames: [\"fd\", \"fdfind\"],\n\t\ttagPrefix: \"v\",\n\t\tgetAssetName: (version, plat, architecture) => {\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `fd-v${version}-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `fd-v${version}-${archStr}-unknown-linux-gnu.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `fd-v${version}-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\trg: {\n\t\tname: \"ripgrep\",\n\t\trepo: \"BurntSushi/ripgrep\",\n\t\tbinaryName: \"rg\",\n\t\ttagPrefix: \"\",\n\t\tgetAssetName: (version, plat, architecture) => {\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `ripgrep-${version}-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\tif (architecture === \"arm64\") {\n\t\t\t\t\treturn `ripgrep-${version}-aarch64-unknown-linux-gnu.tar.gz`;\n\t\t\t\t}\n\t\t\t\treturn `ripgrep-${version}-x86_64-unknown-linux-musl.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `ripgrep-${version}-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\twebtools: {\n\t\tname: \"webtools\",\n\t\trepo: \"kolisachint/webtools\",\n\t\tbinaryName: \"webtools\",\n\t\ttagPrefix: \"v\",\n\t\t// Release assets follow Rust target triples: webtools-<arch>-<target>.<ext>.\n\t\t// Some platforms may not be published yet; a missing asset 404s and ensureTool\n\t\t// degrades gracefully (returns undefined, tools fall back to an error message).\n\t\tgetAssetName: (_version, plat, architecture) => {\n\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\treturn `webtools-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\treturn `webtools-${archStr}-unknown-linux-gnu.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\treturn `webtools-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\tbrowsertools: {\n\t\tname: \"browsertools\",\n\t\trepo: \"kolisachint/browsertools\",\n\t\tbinaryName: \"browsertools\",\n\t\ttagPrefix: \"v\",\n\t\t// Release archives follow Rust target triples: browsertools-<arch>-<target>.<ext>\n\t\t// (release.yml builds gnu + musl for linux; we prefer the gnu variant to match\n\t\t// webtools/filetools). A missing platform asset 404s and ensureTool degrades\n\t\t// gracefully (returns undefined; the browser tools then surface an error).\n\t\tgetAssetName: (_version, plat, architecture) => {\n\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\treturn `browsertools-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\treturn `browsertools-${archStr}-unknown-linux-gnu.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\treturn `browsertools-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\tvoicetools: {\n\t\tname: \"voicetools\",\n\t\trepo: \"kolisachint/voicetools\",\n\t\tbinaryName: \"voicetools\",\n\t\ttagPrefix: \"v\",\n\t\t// Release archives follow Rust target triples: voicetools-<arch>-<target>.<ext>.\n\t\t// A missing platform asset 404s and ensureTool degrades gracefully (returns\n\t\t// undefined; the voice-transcribe caller then surfaces an error message).\n\t\tgetAssetName: (_version, plat, architecture) => {\n\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\treturn `voicetools-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\treturn `voicetools-${archStr}-unknown-linux-gnu.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\treturn `voicetools-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\tfiletools: {\n\t\tname: \"filetools\",\n\t\trepo: \"kolisachint/filetools\",\n\t\tbinaryName: \"filetools\",\n\t\ttagPrefix: \"v\",\n\t\t// Release archives are named `filetools-<target-triple>.<ext>` (see the repo's\n\t\t// release.yml `archive: filetools-$target`). A missing platform asset 404s and\n\t\t// ensureTool degrades gracefully (returns undefined; the doc tools then surface\n\t\t// an error result).\n\t\tgetAssetName: (_version, plat, architecture) => {\n\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\treturn `filetools-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\treturn `filetools-${archStr}-unknown-linux-gnu.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\treturn `filetools-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\tembsearch: {\n\t\tname: \"embsearch\",\n\t\trepo: \"kolisachint/embeddingsearchtools\",\n\t\tbinaryName: \"embsearch\",\n\t\ttagPrefix: \"v\",\n\t\t// Release archives follow Rust target triples: embsearch-<arch>-<target>.<ext>.\n\t\t// Must be the ONNX build (model bundled); the mock build is rejected by the\n\t\t// EmbsearchService. A missing platform asset 404s and ensureTool degrades\n\t\t// gracefully (returns undefined; the search tool stays lexical-only).\n\t\tgetAssetName: (_version, plat, architecture) => {\n\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\treturn `embsearch-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\treturn `embsearch-${archStr}-unknown-linux-gnu.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\treturn `embsearch-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n};\n\n// Check if a command exists in PATH by trying to run it\nfunction commandExists(cmd: string): boolean {\n\ttry {\n\t\tconst result = spawnSync(cmd, [\"--version\"], { stdio: \"pipe\" });\n\t\t// Check for ENOENT error (command not found)\n\t\treturn result.error === undefined || result.error === null;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n// Resolved tool paths are stable for the life of the process. Cache the first\n// successful resolution so we never re-run the synchronous spawnSync probe in\n// commandExists() on every grep/find/glob invocation, which blocks the event loop.\nconst resolvedToolPathCache = new Map<ManagedTool, string>();\n\n// Get the path to a tool (system-wide or in our tools dir)\nexport function getToolPath(tool: ManagedTool): string | null {\n\tconst config = TOOLS[tool];\n\tif (!config) return null;\n\n\t// Explicit binary override (per-tool env var, e.g. HOOCODE_BROWSERTOOLS_BINARY).\n\t// Lets a developer point at a locally built binary that predates a release,\n\t// bypassing the tools-dir/PATH resolution and download. Authoritative when set\n\t// and the path exists.\n\tconst overrideEnv = `HOOCODE_${tool.toUpperCase()}_BINARY`;\n\tconst override = process.env[overrideEnv]?.trim();\n\tif (override && existsSync(override)) {\n\t\treturn override;\n\t}\n\n\t// Reuse a previously resolved path. A bare command name resolves via PATH;\n\t// an absolute path must still exist (revalidate cheaply with existsSync).\n\tconst cached = resolvedToolPathCache.get(tool);\n\tif (cached !== undefined) {\n\t\tconst isAbsolutePath = cached.includes(\"/\") || cached.includes(\"\\\\\");\n\t\tif (!isAbsolutePath || existsSync(cached)) {\n\t\t\treturn cached;\n\t\t}\n\t\tresolvedToolPathCache.delete(tool);\n\t}\n\n\t// Check our tools directory first\n\tconst localPath = join(TOOLS_DIR, config.binaryName + (platform() === \"win32\" ? \".exe\" : \"\"));\n\tif (existsSync(localPath)) {\n\t\tresolvedToolPathCache.set(tool, localPath);\n\t\treturn localPath;\n\t}\n\n\t// Check system PATH - if found, just return the command name (it's in PATH)\n\tconst systemBinaryNames = config.systemBinaryNames ?? [config.binaryName];\n\tfor (const systemBinaryName of systemBinaryNames) {\n\t\tif (commandExists(systemBinaryName)) {\n\t\t\tresolvedToolPathCache.set(tool, systemBinaryName);\n\t\t\treturn systemBinaryName;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n// Fetch latest release version from GitHub\nasync function getLatestVersion(repo: string): Promise<string> {\n\tconst response = await fetch(`https://api.github.com/repos/${repo}/releases/latest`, {\n\t\theaders: { \"User-Agent\": `${APP_NAME}-coding-agent` },\n\t\tsignal: AbortSignal.timeout(NETWORK_TIMEOUT_MS),\n\t});\n\n\tif (!response.ok) {\n\t\tthrow new Error(`GitHub API error: ${response.status}`);\n\t}\n\n\tconst data = (await response.json()) as { tag_name: string };\n\treturn data.tag_name.replace(/^v/, \"\");\n}\n\n// Best-effort SHA-256 verification: fetch \"<downloadUrl>.sha256\" and, when it is\n// served (HTTP 200), verify the downloaded file against it. A 404 (or any other\n// non-200 / network error) means no published checksum, so verification is\n// skipped rather than treated as a failure. A genuine mismatch throws.\nasync function verifyChecksum(downloadUrl: string, filePath: string): Promise<void> {\n\tlet checksumResponse: Awaited<ReturnType<typeof fetch>>;\n\ttry {\n\t\tchecksumResponse = await fetch(`${downloadUrl}.sha256`, {\n\t\t\tsignal: AbortSignal.timeout(NETWORK_TIMEOUT_MS),\n\t\t});\n\t} catch {\n\t\t// Network error fetching the checksum is non-fatal for best-effort verification.\n\t\treturn;\n\t}\n\n\tif (checksumResponse.status !== 200) {\n\t\treturn;\n\t}\n\n\t// sha256 files are commonly \"<hex> <filename>\"; take the leading token.\n\tconst expectedHash = (await checksumResponse.text()).trim().split(/\\s+/)[0]?.toLowerCase();\n\tif (!expectedHash || !/^[0-9a-f]{64}$/.test(expectedHash)) {\n\t\t// Unusable checksum body: skip rather than fail (still best-effort).\n\t\treturn;\n\t}\n\n\tconst actualHash = createHash(\"sha256\").update(readFileSync(filePath)).digest(\"hex\");\n\tif (actualHash !== expectedHash) {\n\t\tthrow new Error(`Checksum mismatch for ${downloadUrl}: expected ${expectedHash}, got ${actualHash}`);\n\t}\n}\n\n/**\n * Live download progress: bytes received so far and the total from\n * Content-Length (null when the server doesn't send one). Callers use it to\n * drive a progress bar instead of an indefinite spinner.\n */\nexport type DownloadProgress = (receivedBytes: number, totalBytes: number | null) => void;\n\n// Download a file from URL into `dest`, validating integrity. Throws (and removes\n// the partial file) on a truncated transfer (bytes written != Content-Length when\n// the header is present) or a SHA-256 mismatch, so a corrupt artifact is never\n// left behind. Exported for tests.\nexport async function downloadFile(url: string, dest: string, onProgress?: DownloadProgress): Promise<void> {\n\ttry {\n\t\tconst response = await fetch(url, {\n\t\t\tsignal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to download: ${response.status}`);\n\t\t}\n\n\t\tif (!response.body) {\n\t\t\tthrow new Error(\"No response body\");\n\t\t}\n\n\t\tconst contentLengthHeader = response.headers.get(\"content-length\");\n\t\tconst expectedBytes =\n\t\t\tcontentLengthHeader !== null && contentLengthHeader.trim() !== \"\" ? Number(contentLengthHeader) : null;\n\n\t\tconst fileStream = createWriteStream(dest);\n\t\tconst source = Readable.fromWeb(response.body as Parameters<typeof Readable.fromWeb>[0]);\n\t\tif (onProgress) {\n\t\t\tlet received = 0;\n\t\t\tsource.on(\"data\", (chunk: Buffer) => {\n\t\t\t\treceived += chunk.length;\n\t\t\t\tonProgress(received, expectedBytes);\n\t\t\t});\n\t\t}\n\t\tawait pipeline(source, fileStream);\n\n\t\tif (expectedBytes !== null && Number.isFinite(expectedBytes)) {\n\t\t\tconst bytesWritten = statSync(dest).size;\n\t\t\tif (bytesWritten !== expectedBytes) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Truncated download from ${url}: expected ${expectedBytes} bytes, received ${bytesWritten}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tawait verifyChecksum(url, dest);\n\t} catch (e) {\n\t\t// Never leave a partial/corrupt file behind on any failure.\n\t\trmSync(dest, { force: true });\n\t\tthrow e;\n\t}\n}\n\nfunction findBinaryRecursively(rootDir: string, binaryFileName: string): string | null {\n\tconst stack: string[] = [rootDir];\n\n\twhile (stack.length > 0) {\n\t\tconst currentDir = stack.pop();\n\t\tif (!currentDir) continue;\n\n\t\tconst entries = readdirSync(currentDir, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tconst fullPath = join(currentDir, entry.name);\n\t\t\tif (entry.isFile() && entry.name === binaryFileName) {\n\t\t\t\treturn fullPath;\n\t\t\t}\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tstack.push(fullPath);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n\n// Download and install a tool\nasync function downloadTool(tool: ManagedTool, onProgress?: DownloadProgress): Promise<string> {\n\tconst config = TOOLS[tool];\n\tif (!config) throw new Error(`Unknown tool: ${tool}`);\n\n\tconst plat = platform();\n\tconst architecture = arch();\n\n\t// Get latest version\n\tconst version = await getLatestVersion(config.repo);\n\n\t// Get asset name for this platform\n\tconst assetName = config.getAssetName(version, plat, architecture);\n\tif (!assetName) {\n\t\tthrow new Error(`Unsupported platform: ${plat}/${architecture}`);\n\t}\n\n\t// Create tools directory\n\tmkdirSync(TOOLS_DIR, { recursive: true });\n\n\tconst downloadUrl = `https://github.com/${config.repo}/releases/download/${config.tagPrefix}${version}/${assetName}`;\n\tconst archivePath = join(TOOLS_DIR, assetName);\n\tconst binaryExt = plat === \"win32\" ? \".exe\" : \"\";\n\tconst binaryPath = join(TOOLS_DIR, config.binaryName + binaryExt);\n\n\t// Download to a unique temp path, validate, then atomically rename into place.\n\t// Writing the shared archive path directly would leave a corrupt partial behind\n\t// if the transfer fails or is truncated. fd/rg/webtools can also download\n\t// concurrently at startup, so the per-attempt temp name must be unique.\n\tconst tempArchivePath = `${archivePath}.${process.pid}.${randomBytes(6).toString(\"hex\")}.part`;\n\n\t// Extract into a unique temp directory. fd and rg downloads can run concurrently\n\t// during startup, so sharing a fixed directory causes races.\n\tconst extractDir = join(\n\t\tTOOLS_DIR,\n\t\t`extract_tmp_${config.binaryName}_${process.pid}_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`,\n\t);\n\n\ttry {\n\t\t// One retry (2 attempts total) around download + integrity verification.\n\t\t// downloadFile removes its own partial on failure, so each attempt is clean.\n\t\tlet lastError: unknown;\n\t\tlet downloaded = false;\n\t\tfor (let attempt = 1; attempt <= 2 && !downloaded; attempt++) {\n\t\t\ttry {\n\t\t\t\tawait downloadFile(downloadUrl, tempArchivePath, onProgress);\n\t\t\t\tdownloaded = true;\n\t\t\t} catch (e) {\n\t\t\t\tlastError = e;\n\t\t\t\trmSync(tempArchivePath, { force: true });\n\t\t\t}\n\t\t}\n\t\tif (!downloaded) {\n\t\t\tthrow lastError instanceof Error ? lastError : new Error(String(lastError));\n\t\t}\n\n\t\t// Atomic publish of the verified archive, then extract.\n\t\trenameSync(tempArchivePath, archivePath);\n\t\tmkdirSync(extractDir, { recursive: true });\n\n\t\tif (assetName.endsWith(\".tar.gz\")) {\n\t\t\tconst extractResult = spawnSync(\"tar\", [\"xzf\", archivePath, \"-C\", extractDir], { stdio: \"pipe\" });\n\t\t\tif (extractResult.error || extractResult.status !== 0) {\n\t\t\t\tconst errMsg = extractResult.error?.message ?? extractResult.stderr?.toString().trim() ?? \"unknown error\";\n\t\t\t\tthrow new Error(`Failed to extract ${assetName}: ${errMsg}`);\n\t\t\t}\n\t\t} else if (assetName.endsWith(\".zip\")) {\n\t\t\tawait extractZip(archivePath, { dir: extractDir });\n\t\t} else {\n\t\t\tthrow new Error(`Unsupported archive format: ${assetName}`);\n\t\t}\n\n\t\t// Find the binary in extracted files. Some archives contain files directly\n\t\t// at root, others nest under a versioned subdirectory.\n\t\tconst binaryFileName = config.binaryName + binaryExt;\n\t\tconst extractedDir = join(extractDir, assetName.replace(/\\.(tar\\.gz|zip)$/, \"\"));\n\t\tconst extractedBinaryCandidates = [join(extractedDir, binaryFileName), join(extractDir, binaryFileName)];\n\t\tlet extractedBinary = extractedBinaryCandidates.find((candidate) => existsSync(candidate));\n\n\t\tif (!extractedBinary) {\n\t\t\textractedBinary = findBinaryRecursively(extractDir, binaryFileName) ?? undefined;\n\t\t}\n\n\t\tif (extractedBinary) {\n\t\t\trenameSync(extractedBinary, binaryPath);\n\t\t} else {\n\t\t\tthrow new Error(`Binary not found in archive: expected ${binaryFileName} under ${extractDir}`);\n\t\t}\n\n\t\t// Make executable (Unix only)\n\t\tif (plat !== \"win32\") {\n\t\t\tchmodSync(binaryPath, 0o755);\n\t\t}\n\t} finally {\n\t\t// Guaranteed cleanup of every transient artifact on ANY outcome: the temp\n\t\t// download (if a failure left it before the rename), the published archive,\n\t\t// and the temp extract dir.\n\t\trmSync(tempArchivePath, { force: true });\n\t\trmSync(archivePath, { force: true });\n\t\trmSync(extractDir, { recursive: true, force: true });\n\t}\n\n\treturn binaryPath;\n}\n\n// Termux package names for tools\nconst TERMUX_PACKAGES: Record<string, string> = {\n\tfd: \"fd\",\n\trg: \"ripgrep\",\n\twebtools: \"webtools\",\n\tfiletools: \"filetools\",\n\tbrowsertools: \"browsertools\",\n\tvoicetools: \"voicetools\",\n\tembsearch: \"embsearch\",\n};\n\n// Ensure a tool is available, downloading if necessary\n// Returns the path to the tool, or null if unavailable\n// onProgress receives live byte counts while the release archive downloads.\nexport async function ensureTool(\n\ttool: ManagedTool,\n\tsilent: boolean = false,\n\tonProgress?: DownloadProgress,\n): Promise<string | undefined> {\n\tconst existingPath = getToolPath(tool);\n\tif (existingPath) {\n\t\treturn existingPath;\n\t}\n\n\tconst config = TOOLS[tool];\n\tif (!config) return undefined;\n\n\tif (isOfflineModeEnabled()) {\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`${config.name} not found. Offline mode enabled, skipping download.`));\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t// On Android/Termux, Linux binaries don't work due to Bionic libc incompatibility.\n\t// Users must install via pkg.\n\tif (platform() === \"android\") {\n\t\tconst pkgName = TERMUX_PACKAGES[tool] ?? tool;\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`${config.name} not found. Install with: pkg install ${pkgName}`));\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t// Tool not found - download it\n\tif (!silent) {\n\t\tconsole.log(chalk.dim(`${config.name} not found. Downloading...`));\n\t}\n\n\ttry {\n\t\tconst path = await downloadTool(tool, onProgress);\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.dim(`${config.name} installed to ${path}`));\n\t\t}\n\t\treturn path;\n\t} catch (e) {\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`Failed to download ${config.name}: ${e instanceof Error ? e.message : e}`));\n\t\t}\n\t\treturn undefined;\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"tools-manager.js","sourceRoot":"","sources":["../../src/utils/tools-manager.ts"],"names":[],"mappings":"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","sourcesContent":["import chalk from \"chalk\";\nimport { spawnSync } from \"child_process\";\nimport { createHash, randomBytes } from \"crypto\";\nimport extractZip from \"extract-zip\";\nimport {\n\tchmodSync,\n\tcreateWriteStream,\n\texistsSync,\n\tmkdirSync,\n\treaddirSync,\n\treadFileSync,\n\trenameSync,\n\trmSync,\n\tstatSync,\n} from \"fs\";\nimport { arch, platform } from \"os\";\nimport { join } from \"path\";\nimport { Readable } from \"stream\";\nimport { pipeline } from \"stream/promises\";\nimport { APP_NAME, getBinDir } from \"../config.js\";\n\nconst TOOLS_DIR = getBinDir();\nconst NETWORK_TIMEOUT_MS = 10_000;\nconst DOWNLOAD_TIMEOUT_MS = 120_000;\n\nfunction isOfflineModeEnabled(): boolean {\n\tconst value = process.env.HOOCODE_OFFLINE;\n\tif (!value) return false;\n\treturn value === \"1\" || value.toLowerCase() === \"true\" || value.toLowerCase() === \"yes\";\n}\n\n/** Tools whose binaries hoocode can resolve from PATH or download on demand. */\nexport type ManagedTool = \"fd\" | \"rg\" | \"webtools\" | \"voicetools\" | \"embsearch\";\n\ninterface ToolConfig {\n\tname: string;\n\trepo: string; // GitHub repo (e.g., \"sharkdp/fd\")\n\tbinaryName: string; // Name of the binary inside the archive\n\tsystemBinaryNames?: string[]; // Alternative system command names to try before downloading\n\ttagPrefix: string; // Prefix for tags (e.g., \"v\" for v1.0.0, \"\" for 1.0.0)\n\tgetAssetName: (version: string, plat: string, architecture: string) => string | null;\n}\n\nconst TOOLS: Record<string, ToolConfig> = {\n\tfd: {\n\t\tname: \"fd\",\n\t\trepo: \"sharkdp/fd\",\n\t\tbinaryName: \"fd\",\n\t\tsystemBinaryNames: [\"fd\", \"fdfind\"],\n\t\ttagPrefix: \"v\",\n\t\tgetAssetName: (version, plat, architecture) => {\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `fd-v${version}-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `fd-v${version}-${archStr}-unknown-linux-gnu.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `fd-v${version}-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\trg: {\n\t\tname: \"ripgrep\",\n\t\trepo: \"BurntSushi/ripgrep\",\n\t\tbinaryName: \"rg\",\n\t\ttagPrefix: \"\",\n\t\tgetAssetName: (version, plat, architecture) => {\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `ripgrep-${version}-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\tif (architecture === \"arm64\") {\n\t\t\t\t\treturn `ripgrep-${version}-aarch64-unknown-linux-gnu.tar.gz`;\n\t\t\t\t}\n\t\t\t\treturn `ripgrep-${version}-x86_64-unknown-linux-musl.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\t\treturn `ripgrep-${version}-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\twebtools: {\n\t\tname: \"webtools\",\n\t\trepo: \"kolisachint/webtools\",\n\t\tbinaryName: \"webtools\",\n\t\ttagPrefix: \"v\",\n\t\t// Release assets follow Rust target triples: webtools-<arch>-<target>.<ext>.\n\t\t// Some platforms may not be published yet; a missing asset 404s and ensureTool\n\t\t// degrades gracefully (returns undefined, tools fall back to an error message).\n\t\tgetAssetName: (_version, plat, architecture) => {\n\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\treturn `webtools-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\treturn `webtools-${archStr}-unknown-linux-gnu.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\treturn `webtools-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\tvoicetools: {\n\t\tname: \"voicetools\",\n\t\trepo: \"kolisachint/voicetools\",\n\t\tbinaryName: \"voicetools\",\n\t\ttagPrefix: \"v\",\n\t\t// Release archives follow Rust target triples: voicetools-<arch>-<target>.<ext>.\n\t\t// A missing platform asset 404s and ensureTool degrades gracefully (returns\n\t\t// undefined; the voice-transcribe caller then surfaces an error message).\n\t\tgetAssetName: (_version, plat, architecture) => {\n\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\treturn `voicetools-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\treturn `voicetools-${archStr}-unknown-linux-gnu.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\treturn `voicetools-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n\tembsearch: {\n\t\tname: \"embsearch\",\n\t\trepo: \"kolisachint/embeddingsearchtools\",\n\t\tbinaryName: \"embsearch\",\n\t\ttagPrefix: \"v\",\n\t\t// Release archives follow Rust target triples: embsearch-<arch>-<target>.<ext>.\n\t\t// Must be the ONNX build (model bundled); the mock build is rejected by the\n\t\t// EmbsearchService. A missing platform asset 404s and ensureTool degrades\n\t\t// gracefully (returns undefined; the search tool stays lexical-only).\n\t\tgetAssetName: (_version, plat, architecture) => {\n\t\t\tconst archStr = architecture === \"arm64\" ? \"aarch64\" : \"x86_64\";\n\t\t\tif (plat === \"darwin\") {\n\t\t\t\treturn `embsearch-${archStr}-apple-darwin.tar.gz`;\n\t\t\t} else if (plat === \"linux\") {\n\t\t\t\treturn `embsearch-${archStr}-unknown-linux-gnu.tar.gz`;\n\t\t\t} else if (plat === \"win32\") {\n\t\t\t\treturn `embsearch-${archStr}-pc-windows-msvc.zip`;\n\t\t\t}\n\t\t\treturn null;\n\t\t},\n\t},\n};\n\n// Check if a command exists in PATH by trying to run it\nfunction commandExists(cmd: string): boolean {\n\ttry {\n\t\tconst result = spawnSync(cmd, [\"--version\"], { stdio: \"pipe\" });\n\t\t// Check for ENOENT error (command not found)\n\t\treturn result.error === undefined || result.error === null;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n// Resolved tool paths are stable for the life of the process. Cache the first\n// successful resolution so we never re-run the synchronous spawnSync probe in\n// commandExists() on every grep/find/glob invocation, which blocks the event loop.\nconst resolvedToolPathCache = new Map<ManagedTool, string>();\n\n// Get the path to a tool (system-wide or in our tools dir)\nfunction getToolPath(tool: ManagedTool): string | null {\n\tconst config = TOOLS[tool];\n\tif (!config) return null;\n\n\t// Explicit binary override (per-tool env var, e.g. HOOCODE_WEBTOOLS_BINARY).\n\t// Lets a developer point at a locally built binary that predates a release,\n\t// bypassing the tools-dir/PATH resolution and download. Authoritative when set\n\t// and the path exists.\n\tconst overrideEnv = `HOOCODE_${tool.toUpperCase()}_BINARY`;\n\tconst override = process.env[overrideEnv]?.trim();\n\tif (override && existsSync(override)) {\n\t\treturn override;\n\t}\n\n\t// Reuse a previously resolved path. A bare command name resolves via PATH;\n\t// an absolute path must still exist (revalidate cheaply with existsSync).\n\tconst cached = resolvedToolPathCache.get(tool);\n\tif (cached !== undefined) {\n\t\tconst isAbsolutePath = cached.includes(\"/\") || cached.includes(\"\\\\\");\n\t\tif (!isAbsolutePath || existsSync(cached)) {\n\t\t\treturn cached;\n\t\t}\n\t\tresolvedToolPathCache.delete(tool);\n\t}\n\n\t// Check our tools directory first\n\tconst localPath = join(TOOLS_DIR, config.binaryName + (platform() === \"win32\" ? \".exe\" : \"\"));\n\tif (existsSync(localPath)) {\n\t\tresolvedToolPathCache.set(tool, localPath);\n\t\treturn localPath;\n\t}\n\n\t// Check system PATH - if found, just return the command name (it's in PATH)\n\tconst systemBinaryNames = config.systemBinaryNames ?? [config.binaryName];\n\tfor (const systemBinaryName of systemBinaryNames) {\n\t\tif (commandExists(systemBinaryName)) {\n\t\t\tresolvedToolPathCache.set(tool, systemBinaryName);\n\t\t\treturn systemBinaryName;\n\t\t}\n\t}\n\n\treturn null;\n}\n\n// Fetch latest release version from GitHub\nasync function getLatestVersion(repo: string): Promise<string> {\n\tconst response = await fetch(`https://api.github.com/repos/${repo}/releases/latest`, {\n\t\theaders: { \"User-Agent\": `${APP_NAME}-coding-agent` },\n\t\tsignal: AbortSignal.timeout(NETWORK_TIMEOUT_MS),\n\t});\n\n\tif (!response.ok) {\n\t\tthrow new Error(`GitHub API error: ${response.status}`);\n\t}\n\n\tconst data = (await response.json()) as { tag_name: string };\n\treturn data.tag_name.replace(/^v/, \"\");\n}\n\n// Best-effort SHA-256 verification: fetch \"<downloadUrl>.sha256\" and, when it is\n// served (HTTP 200), verify the downloaded file against it. A 404 (or any other\n// non-200 / network error) means no published checksum, so verification is\n// skipped rather than treated as a failure. A genuine mismatch throws.\nasync function verifyChecksum(downloadUrl: string, filePath: string): Promise<void> {\n\tlet checksumResponse: Awaited<ReturnType<typeof fetch>>;\n\ttry {\n\t\tchecksumResponse = await fetch(`${downloadUrl}.sha256`, {\n\t\t\tsignal: AbortSignal.timeout(NETWORK_TIMEOUT_MS),\n\t\t});\n\t} catch {\n\t\t// Network error fetching the checksum is non-fatal for best-effort verification.\n\t\treturn;\n\t}\n\n\tif (checksumResponse.status !== 200) {\n\t\treturn;\n\t}\n\n\t// sha256 files are commonly \"<hex> <filename>\"; take the leading token.\n\tconst expectedHash = (await checksumResponse.text()).trim().split(/\\s+/)[0]?.toLowerCase();\n\tif (!expectedHash || !/^[0-9a-f]{64}$/.test(expectedHash)) {\n\t\t// Unusable checksum body: skip rather than fail (still best-effort).\n\t\treturn;\n\t}\n\n\tconst actualHash = createHash(\"sha256\").update(readFileSync(filePath)).digest(\"hex\");\n\tif (actualHash !== expectedHash) {\n\t\tthrow new Error(`Checksum mismatch for ${downloadUrl}: expected ${expectedHash}, got ${actualHash}`);\n\t}\n}\n\n/**\n * Live download progress: bytes received so far and the total from\n * Content-Length (null when the server doesn't send one). Callers use it to\n * drive a progress bar instead of an indefinite spinner.\n */\nexport type DownloadProgress = (receivedBytes: number, totalBytes: number | null) => void;\n\n// Download a file from URL into `dest`, validating integrity. Throws (and removes\n// the partial file) on a truncated transfer (bytes written != Content-Length when\n// the header is present) or a SHA-256 mismatch, so a corrupt artifact is never\n// left behind. Exported for tests.\nexport async function downloadFile(url: string, dest: string, onProgress?: DownloadProgress): Promise<void> {\n\ttry {\n\t\tconst response = await fetch(url, {\n\t\t\tsignal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS),\n\t\t});\n\n\t\tif (!response.ok) {\n\t\t\tthrow new Error(`Failed to download: ${response.status}`);\n\t\t}\n\n\t\tif (!response.body) {\n\t\t\tthrow new Error(\"No response body\");\n\t\t}\n\n\t\tconst contentLengthHeader = response.headers.get(\"content-length\");\n\t\tconst expectedBytes =\n\t\t\tcontentLengthHeader !== null && contentLengthHeader.trim() !== \"\" ? Number(contentLengthHeader) : null;\n\n\t\tconst fileStream = createWriteStream(dest);\n\t\tconst source = Readable.fromWeb(response.body as Parameters<typeof Readable.fromWeb>[0]);\n\t\tif (onProgress) {\n\t\t\tlet received = 0;\n\t\t\tsource.on(\"data\", (chunk: Buffer) => {\n\t\t\t\treceived += chunk.length;\n\t\t\t\tonProgress(received, expectedBytes);\n\t\t\t});\n\t\t}\n\t\tawait pipeline(source, fileStream);\n\n\t\tif (expectedBytes !== null && Number.isFinite(expectedBytes)) {\n\t\t\tconst bytesWritten = statSync(dest).size;\n\t\t\tif (bytesWritten !== expectedBytes) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Truncated download from ${url}: expected ${expectedBytes} bytes, received ${bytesWritten}`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tawait verifyChecksum(url, dest);\n\t} catch (e) {\n\t\t// Never leave a partial/corrupt file behind on any failure.\n\t\trmSync(dest, { force: true });\n\t\tthrow e;\n\t}\n}\n\nfunction findBinaryRecursively(rootDir: string, binaryFileName: string): string | null {\n\tconst stack: string[] = [rootDir];\n\n\twhile (stack.length > 0) {\n\t\tconst currentDir = stack.pop();\n\t\tif (!currentDir) continue;\n\n\t\tconst entries = readdirSync(currentDir, { withFileTypes: true });\n\t\tfor (const entry of entries) {\n\t\t\tconst fullPath = join(currentDir, entry.name);\n\t\t\tif (entry.isFile() && entry.name === binaryFileName) {\n\t\t\t\treturn fullPath;\n\t\t\t}\n\t\t\tif (entry.isDirectory()) {\n\t\t\t\tstack.push(fullPath);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn null;\n}\n\n// Download and install a tool\nasync function downloadTool(tool: ManagedTool, onProgress?: DownloadProgress): Promise<string> {\n\tconst config = TOOLS[tool];\n\tif (!config) throw new Error(`Unknown tool: ${tool}`);\n\n\tconst plat = platform();\n\tconst architecture = arch();\n\n\t// Get latest version\n\tconst version = await getLatestVersion(config.repo);\n\n\t// Get asset name for this platform\n\tconst assetName = config.getAssetName(version, plat, architecture);\n\tif (!assetName) {\n\t\tthrow new Error(`Unsupported platform: ${plat}/${architecture}`);\n\t}\n\n\t// Create tools directory\n\tmkdirSync(TOOLS_DIR, { recursive: true });\n\n\tconst downloadUrl = `https://github.com/${config.repo}/releases/download/${config.tagPrefix}${version}/${assetName}`;\n\tconst archivePath = join(TOOLS_DIR, assetName);\n\tconst binaryExt = plat === \"win32\" ? \".exe\" : \"\";\n\tconst binaryPath = join(TOOLS_DIR, config.binaryName + binaryExt);\n\n\t// Download to a unique temp path, validate, then atomically rename into place.\n\t// Writing the shared archive path directly would leave a corrupt partial behind\n\t// if the transfer fails or is truncated. fd/rg/webtools can also download\n\t// concurrently at startup, so the per-attempt temp name must be unique.\n\tconst tempArchivePath = `${archivePath}.${process.pid}.${randomBytes(6).toString(\"hex\")}.part`;\n\n\t// Extract into a unique temp directory. fd and rg downloads can run concurrently\n\t// during startup, so sharing a fixed directory causes races.\n\tconst extractDir = join(\n\t\tTOOLS_DIR,\n\t\t`extract_tmp_${config.binaryName}_${process.pid}_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`,\n\t);\n\n\ttry {\n\t\t// One retry (2 attempts total) around download + integrity verification.\n\t\t// downloadFile removes its own partial on failure, so each attempt is clean.\n\t\tlet lastError: unknown;\n\t\tlet downloaded = false;\n\t\tfor (let attempt = 1; attempt <= 2 && !downloaded; attempt++) {\n\t\t\ttry {\n\t\t\t\tawait downloadFile(downloadUrl, tempArchivePath, onProgress);\n\t\t\t\tdownloaded = true;\n\t\t\t} catch (e) {\n\t\t\t\tlastError = e;\n\t\t\t\trmSync(tempArchivePath, { force: true });\n\t\t\t}\n\t\t}\n\t\tif (!downloaded) {\n\t\t\tthrow lastError instanceof Error ? lastError : new Error(String(lastError));\n\t\t}\n\n\t\t// Atomic publish of the verified archive, then extract.\n\t\trenameSync(tempArchivePath, archivePath);\n\t\tmkdirSync(extractDir, { recursive: true });\n\n\t\tif (assetName.endsWith(\".tar.gz\")) {\n\t\t\tconst extractResult = spawnSync(\"tar\", [\"xzf\", archivePath, \"-C\", extractDir], { stdio: \"pipe\" });\n\t\t\tif (extractResult.error || extractResult.status !== 0) {\n\t\t\t\tconst errMsg = extractResult.error?.message ?? extractResult.stderr?.toString().trim() ?? \"unknown error\";\n\t\t\t\tthrow new Error(`Failed to extract ${assetName}: ${errMsg}`);\n\t\t\t}\n\t\t} else if (assetName.endsWith(\".zip\")) {\n\t\t\tawait extractZip(archivePath, { dir: extractDir });\n\t\t} else {\n\t\t\tthrow new Error(`Unsupported archive format: ${assetName}`);\n\t\t}\n\n\t\t// Find the binary in extracted files. Some archives contain files directly\n\t\t// at root, others nest under a versioned subdirectory.\n\t\tconst binaryFileName = config.binaryName + binaryExt;\n\t\tconst extractedDir = join(extractDir, assetName.replace(/\\.(tar\\.gz|zip)$/, \"\"));\n\t\tconst extractedBinaryCandidates = [join(extractedDir, binaryFileName), join(extractDir, binaryFileName)];\n\t\tlet extractedBinary = extractedBinaryCandidates.find((candidate) => existsSync(candidate));\n\n\t\tif (!extractedBinary) {\n\t\t\textractedBinary = findBinaryRecursively(extractDir, binaryFileName) ?? undefined;\n\t\t}\n\n\t\tif (extractedBinary) {\n\t\t\trenameSync(extractedBinary, binaryPath);\n\t\t} else {\n\t\t\tthrow new Error(`Binary not found in archive: expected ${binaryFileName} under ${extractDir}`);\n\t\t}\n\n\t\t// Make executable (Unix only)\n\t\tif (plat !== \"win32\") {\n\t\t\tchmodSync(binaryPath, 0o755);\n\t\t}\n\t} finally {\n\t\t// Guaranteed cleanup of every transient artifact on ANY outcome: the temp\n\t\t// download (if a failure left it before the rename), the published archive,\n\t\t// and the temp extract dir.\n\t\trmSync(tempArchivePath, { force: true });\n\t\trmSync(archivePath, { force: true });\n\t\trmSync(extractDir, { recursive: true, force: true });\n\t}\n\n\treturn binaryPath;\n}\n\n// Termux package names for tools\nconst TERMUX_PACKAGES: Record<string, string> = {\n\tfd: \"fd\",\n\trg: \"ripgrep\",\n\twebtools: \"webtools\",\n\tvoicetools: \"voicetools\",\n\tembsearch: \"embsearch\",\n};\n\n// Ensure a tool is available, downloading if necessary\n// Returns the path to the tool, or null if unavailable\n// onProgress receives live byte counts while the release archive downloads.\nexport async function ensureTool(\n\ttool: ManagedTool,\n\tsilent: boolean = false,\n\tonProgress?: DownloadProgress,\n): Promise<string | undefined> {\n\tconst existingPath = getToolPath(tool);\n\tif (existingPath) {\n\t\treturn existingPath;\n\t}\n\n\tconst config = TOOLS[tool];\n\tif (!config) return undefined;\n\n\tif (isOfflineModeEnabled()) {\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`${config.name} not found. Offline mode enabled, skipping download.`));\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t// On Android/Termux, Linux binaries don't work due to Bionic libc incompatibility.\n\t// Users must install via pkg.\n\tif (platform() === \"android\") {\n\t\tconst pkgName = TERMUX_PACKAGES[tool] ?? tool;\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`${config.name} not found. Install with: pkg install ${pkgName}`));\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t// Tool not found - download it\n\tif (!silent) {\n\t\tconsole.log(chalk.dim(`${config.name} not found. Downloading...`));\n\t}\n\n\ttry {\n\t\tconst path = await downloadTool(tool, onProgress);\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.dim(`${config.name} installed to ${path}`));\n\t\t}\n\t\treturn path;\n\t} catch (e) {\n\t\tif (!silent) {\n\t\t\tconsole.log(chalk.yellow(`Failed to download ${config.name}: ${e instanceof Error ? e.message : e}`));\n\t\t}\n\t\treturn undefined;\n\t}\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kolisachint/hoocode-agent",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.164",
|
|
4
4
|
"description": "Coding agent CLI with read, bash, edit, write tools and session management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"hoocodeConfig": {
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"prepublishOnly": "npm run clean && npm run build"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@kolisachint/hoocode-agent-core": "^0.4.
|
|
49
|
-
"@kolisachint/hoocode-ai": "^0.4.
|
|
50
|
-
"@kolisachint/hoocode-tui": "^0.4.
|
|
48
|
+
"@kolisachint/hoocode-agent-core": "^0.4.164",
|
|
49
|
+
"@kolisachint/hoocode-ai": "^0.4.164",
|
|
50
|
+
"@kolisachint/hoocode-tui": "^0.4.164",
|
|
51
51
|
"@silvia-odwyer/photon-node": "^0.3.4",
|
|
52
52
|
"chalk": "^5.5.0",
|
|
53
53
|
"cli-highlight": "^2.1.11",
|
|
@@ -58,7 +58,6 @@
|
|
|
58
58
|
"hosted-git-info": "^9.0.2",
|
|
59
59
|
"ignore": "^7.0.5",
|
|
60
60
|
"jiti": "^2.7.0",
|
|
61
|
-
"marked": "^15.0.12",
|
|
62
61
|
"minimatch": "^10.2.3",
|
|
63
62
|
"proper-lockfile": "^4.1.2",
|
|
64
63
|
"strip-ansi": "^7.1.0",
|
|
@@ -77,9 +76,7 @@
|
|
|
77
76
|
"@mariozechner/clipboard": "^0.3.5"
|
|
78
77
|
},
|
|
79
78
|
"devDependencies": {
|
|
80
|
-
"@types/diff": "^7.0.2",
|
|
81
79
|
"@types/hosted-git-info": "^3.0.5",
|
|
82
|
-
"@types/ms": "^2.1.0",
|
|
83
80
|
"@types/node": "^24.3.0",
|
|
84
81
|
"@types/proper-lockfile": "^4.1.4",
|
|
85
82
|
"shx": "^0.4.0",
|
package/dist/core/index.d.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core modules shared between all run modes.
|
|
3
|
-
*/
|
|
4
|
-
export type { CompactionResult } from "@kolisachint/hoocode-agent-core";
|
|
5
|
-
export { AgentSession, type AgentSessionConfig, type AgentSessionEvent, type AgentSessionEventListener, type ModelCycleResult, type PromptOptions, type SessionStats, } from "./agent-session.js";
|
|
6
|
-
export { AgentSessionRuntime, type CreateAgentSessionRuntimeFactory, type CreateAgentSessionRuntimeResult, createAgentSessionRuntime, } from "./agent-session-runtime.js";
|
|
7
|
-
export { type AgentSessionRuntimeDiagnostic, type AgentSessionServices, type CreateAgentSessionFromServicesOptions, type CreateAgentSessionServicesOptions, createAgentSessionFromServices, createAgentSessionServices, } from "./agent-session-services.js";
|
|
8
|
-
export { type BashExecutorOptions, type BashResult, executeBashWithOperations } from "./bash-executor.js";
|
|
9
|
-
export { createEventBus, type EventBus, type EventBusController } from "./event-bus.js";
|
|
10
|
-
export { type AgentEndEvent, type AgentStartEvent, type AgentToolResult, type AgentToolUpdateCallback, type BeforeAgentStartEvent, type BeforeAgentStartEventResult, type BuildSystemPromptOptions, type ContextEvent, defineTool, discoverAndLoadExtensions, type ExecOptions, type ExecResult, type Extension, type ExtensionAPI, type ExtensionCommandContext, type ExtensionContext, type ExtensionError, type ExtensionEvent, type ExtensionFactory, type ExtensionFlag, type ExtensionHandler, ExtensionRunner, type ExtensionShortcut, type ExtensionUIContext, type LoadExtensionsResult, type MessageRenderer, type RegisteredCommand, type SessionBeforeCompactEvent, type SessionBeforeForkEvent, type SessionBeforeSwitchEvent, type SessionBeforeTreeEvent, type SessionCompactEvent, type SessionShutdownEvent, type SessionStartEvent, type SessionTreeEvent, type ToolCallEvent, type ToolCallEventResult, type ToolDefinition, type ToolRenderResultOptions, type ToolResultEvent, type TurnEndEvent, type TurnStartEvent, type WorkingIndicatorOptions, } from "./extensions/index.js";
|
|
11
|
-
export { createSyntheticSourceInfo } from "./source-info.js";
|
|
12
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/core/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,EACN,YAAY,EACZ,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,YAAY,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,mBAAmB,EACnB,KAAK,gCAAgC,EACrC,KAAK,+BAA+B,EACpC,yBAAyB,GACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACN,KAAK,6BAA6B,EAClC,KAAK,oBAAoB,EACzB,KAAK,qCAAqC,EAC1C,KAAK,iCAAiC,EACtC,8BAA8B,EAC9B,0BAA0B,GAC1B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,KAAK,mBAAmB,EAAE,KAAK,UAAU,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC1G,OAAO,EAAE,cAAc,EAAE,KAAK,QAAQ,EAAE,KAAK,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAExF,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,eAAe,EACpB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC7B,KAAK,YAAY,EACjB,UAAU,EACV,yBAAyB,EACzB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,uBAAuB,EAC5B,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,eAAe,EACf,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAC7B,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,mBAAmB,EACxB,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC5B,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,uBAAuB,GAC5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["/**\n * Core modules shared between all run modes.\n */\n\nexport type { CompactionResult } from \"@kolisachint/hoocode-agent-core\";\nexport {\n\tAgentSession,\n\ttype AgentSessionConfig,\n\ttype AgentSessionEvent,\n\ttype AgentSessionEventListener,\n\ttype ModelCycleResult,\n\ttype PromptOptions,\n\ttype SessionStats,\n} from \"./agent-session.js\";\nexport {\n\tAgentSessionRuntime,\n\ttype CreateAgentSessionRuntimeFactory,\n\ttype CreateAgentSessionRuntimeResult,\n\tcreateAgentSessionRuntime,\n} from \"./agent-session-runtime.js\";\nexport {\n\ttype AgentSessionRuntimeDiagnostic,\n\ttype AgentSessionServices,\n\ttype CreateAgentSessionFromServicesOptions,\n\ttype CreateAgentSessionServicesOptions,\n\tcreateAgentSessionFromServices,\n\tcreateAgentSessionServices,\n} from \"./agent-session-services.js\";\nexport { type BashExecutorOptions, type BashResult, executeBashWithOperations } from \"./bash-executor.js\";\nexport { createEventBus, type EventBus, type EventBusController } from \"./event-bus.js\";\n// Extensions system\nexport {\n\ttype AgentEndEvent,\n\ttype AgentStartEvent,\n\ttype AgentToolResult,\n\ttype AgentToolUpdateCallback,\n\ttype BeforeAgentStartEvent,\n\ttype BeforeAgentStartEventResult,\n\ttype BuildSystemPromptOptions,\n\ttype ContextEvent,\n\tdefineTool,\n\tdiscoverAndLoadExtensions,\n\ttype ExecOptions,\n\ttype ExecResult,\n\ttype Extension,\n\ttype ExtensionAPI,\n\ttype ExtensionCommandContext,\n\ttype ExtensionContext,\n\ttype ExtensionError,\n\ttype ExtensionEvent,\n\ttype ExtensionFactory,\n\ttype ExtensionFlag,\n\ttype ExtensionHandler,\n\tExtensionRunner,\n\ttype ExtensionShortcut,\n\ttype ExtensionUIContext,\n\ttype LoadExtensionsResult,\n\ttype MessageRenderer,\n\ttype RegisteredCommand,\n\ttype SessionBeforeCompactEvent,\n\ttype SessionBeforeForkEvent,\n\ttype SessionBeforeSwitchEvent,\n\ttype SessionBeforeTreeEvent,\n\ttype SessionCompactEvent,\n\ttype SessionShutdownEvent,\n\ttype SessionStartEvent,\n\ttype SessionTreeEvent,\n\ttype ToolCallEvent,\n\ttype ToolCallEventResult,\n\ttype ToolDefinition,\n\ttype ToolRenderResultOptions,\n\ttype ToolResultEvent,\n\ttype TurnEndEvent,\n\ttype TurnStartEvent,\n\ttype WorkingIndicatorOptions,\n} from \"./extensions/index.js\";\nexport { createSyntheticSourceInfo } from \"./source-info.js\";\n"]}
|
package/dist/core/index.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core modules shared between all run modes.
|
|
3
|
-
*/
|
|
4
|
-
export { AgentSession, } from "./agent-session.js";
|
|
5
|
-
export { AgentSessionRuntime, createAgentSessionRuntime, } from "./agent-session-runtime.js";
|
|
6
|
-
export { createAgentSessionFromServices, createAgentSessionServices, } from "./agent-session-services.js";
|
|
7
|
-
export { executeBashWithOperations } from "./bash-executor.js";
|
|
8
|
-
export { createEventBus } from "./event-bus.js";
|
|
9
|
-
// Extensions system
|
|
10
|
-
export { defineTool, discoverAndLoadExtensions, ExtensionRunner, } from "./extensions/index.js";
|
|
11
|
-
export { createSyntheticSourceInfo } from "./source-info.js";
|
|
12
|
-
//# sourceMappingURL=index.js.map
|
package/dist/core/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACN,YAAY,GAOZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACN,mBAAmB,EAGnB,yBAAyB,GACzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAKN,8BAA8B,EAC9B,0BAA0B,GAC1B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAA6C,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC1G,OAAO,EAAE,cAAc,EAA0C,MAAM,gBAAgB,CAAC;AACxF,oBAAoB;AACpB,OAAO,EASN,UAAU,EACV,yBAAyB,EAYzB,eAAe,GAsBf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC","sourcesContent":["/**\n * Core modules shared between all run modes.\n */\n\nexport type { CompactionResult } from \"@kolisachint/hoocode-agent-core\";\nexport {\n\tAgentSession,\n\ttype AgentSessionConfig,\n\ttype AgentSessionEvent,\n\ttype AgentSessionEventListener,\n\ttype ModelCycleResult,\n\ttype PromptOptions,\n\ttype SessionStats,\n} from \"./agent-session.js\";\nexport {\n\tAgentSessionRuntime,\n\ttype CreateAgentSessionRuntimeFactory,\n\ttype CreateAgentSessionRuntimeResult,\n\tcreateAgentSessionRuntime,\n} from \"./agent-session-runtime.js\";\nexport {\n\ttype AgentSessionRuntimeDiagnostic,\n\ttype AgentSessionServices,\n\ttype CreateAgentSessionFromServicesOptions,\n\ttype CreateAgentSessionServicesOptions,\n\tcreateAgentSessionFromServices,\n\tcreateAgentSessionServices,\n} from \"./agent-session-services.js\";\nexport { type BashExecutorOptions, type BashResult, executeBashWithOperations } from \"./bash-executor.js\";\nexport { createEventBus, type EventBus, type EventBusController } from \"./event-bus.js\";\n// Extensions system\nexport {\n\ttype AgentEndEvent,\n\ttype AgentStartEvent,\n\ttype AgentToolResult,\n\ttype AgentToolUpdateCallback,\n\ttype BeforeAgentStartEvent,\n\ttype BeforeAgentStartEventResult,\n\ttype BuildSystemPromptOptions,\n\ttype ContextEvent,\n\tdefineTool,\n\tdiscoverAndLoadExtensions,\n\ttype ExecOptions,\n\ttype ExecResult,\n\ttype Extension,\n\ttype ExtensionAPI,\n\ttype ExtensionCommandContext,\n\ttype ExtensionContext,\n\ttype ExtensionError,\n\ttype ExtensionEvent,\n\ttype ExtensionFactory,\n\ttype ExtensionFlag,\n\ttype ExtensionHandler,\n\tExtensionRunner,\n\ttype ExtensionShortcut,\n\ttype ExtensionUIContext,\n\ttype LoadExtensionsResult,\n\ttype MessageRenderer,\n\ttype RegisteredCommand,\n\ttype SessionBeforeCompactEvent,\n\ttype SessionBeforeForkEvent,\n\ttype SessionBeforeSwitchEvent,\n\ttype SessionBeforeTreeEvent,\n\ttype SessionCompactEvent,\n\ttype SessionShutdownEvent,\n\ttype SessionStartEvent,\n\ttype SessionTreeEvent,\n\ttype ToolCallEvent,\n\ttype ToolCallEventResult,\n\ttype ToolDefinition,\n\ttype ToolRenderResultOptions,\n\ttype ToolResultEvent,\n\ttype TurnEndEvent,\n\ttype TurnStartEvent,\n\ttype WorkingIndicatorOptions,\n} from \"./extensions/index.js\";\nexport { createSyntheticSourceInfo } from \"./source-info.js\";\n"]}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `browser_continue` tool: answer a `NeedsParent` suspension from `browser_run`.
|
|
3
|
-
*
|
|
4
|
-
* Looks up the paused serve session by its `ResumeToken`, issues `flow_resume`
|
|
5
|
-
* with the parent's decision (a `ParentResponse` object), and maps the next
|
|
6
|
-
* outcome the same way `browser_run` does — completing, failing, or suspending
|
|
7
|
-
* again with a fresh token. The live serve process (and its browser state) is
|
|
8
|
-
* reused across rounds. See {@link browsertools-shared}.
|
|
9
|
-
*/
|
|
10
|
-
import type { AgentTool } from "@kolisachint/hoocode-agent-core";
|
|
11
|
-
import { type Static, Type } from "typebox";
|
|
12
|
-
import { type ToolDefinition } from "../../extensions/types.js";
|
|
13
|
-
import { type BrowserRunDetails } from "./browser-run.js";
|
|
14
|
-
import { type BrowsertoolsToolOptions } from "./browsertools-shared.js";
|
|
15
|
-
declare const browserContinueSchema: Type.TObject<{
|
|
16
|
-
token: Type.TString;
|
|
17
|
-
response: Type.TRecord<"^.*$", Type.TUnknown>;
|
|
18
|
-
}>;
|
|
19
|
-
export type BrowserContinueInput = Static<typeof browserContinueSchema>;
|
|
20
|
-
export interface BrowserContinueToolOptions extends BrowsertoolsToolOptions {
|
|
21
|
-
}
|
|
22
|
-
export declare function createBrowserContinueToolDefinition(_cwd: string, options?: BrowserContinueToolOptions): ToolDefinition<typeof browserContinueSchema, BrowserRunDetails>;
|
|
23
|
-
export declare function createBrowserContinueTool(cwd: string, options?: BrowserContinueToolOptions): AgentTool<typeof browserContinueSchema>;
|
|
24
|
-
export {};
|
|
25
|
-
//# sourceMappingURL=browser-continue.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browser-continue.d.ts","sourceRoot":"","sources":["../../../../src/core/tools/browser/browser-continue.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AACjE,OAAO,EAAE,KAAK,MAAM,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE5E,OAAO,EAAe,KAAK,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAEN,KAAK,uBAAuB,EAI5B,MAAM,0BAA0B,CAAC;AAElC,QAAA,MAAM,qBAAqB;;;EAOzB,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,MAAM,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAExE,MAAM,WAAW,0BAA2B,SAAQ,uBAAuB;CAAG;AAE9E,wBAAgB,mCAAmC,CAGlD,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,0BAA0B,GAClC,cAAc,CAAC,OAAO,qBAAqB,EAAE,iBAAiB,CAAC,CAyDjE;AAED,wBAAgB,yBAAyB,CACxC,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,0BAA0B,GAClC,SAAS,CAAC,OAAO,qBAAqB,CAAC,CAEzC","sourcesContent":["/**\n * `browser_continue` tool: answer a `NeedsParent` suspension from `browser_run`.\n *\n * Looks up the paused serve session by its `ResumeToken`, issues `flow_resume`\n * with the parent's decision (a `ParentResponse` object), and maps the next\n * outcome the same way `browser_run` does — completing, failing, or suspending\n * again with a fresh token. The live serve process (and its browser state) is\n * reused across rounds. See {@link browsertools-shared}.\n */\n\nimport type { AgentTool } from \"@kolisachint/hoocode-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport { defineTool, type ToolDefinition } from \"../../extensions/types.js\";\nimport { wrapToolDefinition } from \"../tool-definition-wrapper.js\";\nimport { advanceFlow, type BrowserRunDetails } from \"./browser-run.js\";\nimport {\n\ttype BrowserClientConfig,\n\ttype BrowsertoolsToolOptions,\n\ttype FlowOutcome,\n\tresolveBrowsertoolsOptions,\n\ttakeSession,\n} from \"./browsertools-shared.js\";\n\nconst browserContinueSchema = Type.Object({\n\ttoken: Type.String({ description: \"The resume token returned by a browser_run NeedsParent result.\" }),\n\tresponse: Type.Record(Type.String(), Type.Unknown(), {\n\t\tdescription:\n\t\t\t\"The ParentResponse object answering the request, e.g. \" +\n\t\t\t'{ \"response\": \"state\", \"state\": \"logged_in\" } or { \"response\": \"verified\", \"passed\": true }.',\n\t}),\n});\n\nexport type BrowserContinueInput = Static<typeof browserContinueSchema>;\n\nexport interface BrowserContinueToolOptions extends BrowsertoolsToolOptions {}\n\nexport function createBrowserContinueToolDefinition(\n\t// cwd is part of the factory signature for parity with other tools, but continue\n\t// reuses the serve process parked by browser_run, so it is not needed here.\n\t_cwd: string,\n\toptions?: BrowserContinueToolOptions,\n): ToolDefinition<typeof browserContinueSchema, BrowserRunDetails> {\n\tconst opts = resolveBrowsertoolsOptions(options);\n\treturn defineTool({\n\t\tname: \"browser_continue\",\n\t\tlabel: \"browser continue\",\n\t\tdescription:\n\t\t\t\"Continue a browser flow that suspended with a NeedsParent request. Pass the token from the \" +\n\t\t\t\"browser_run result and a ParentResponse object answering the request. The flow continues \" +\n\t\t\t\"deterministically and either completes, fails, or suspends again with a new token — in which \" +\n\t\t\t\"case read the new screenshot and call browser_continue again, looping until the outcome is \" +\n\t\t\t\"`complete`. Do not abandon the loop to read the page with webfetch. ParentResponse by request \" +\n\t\t\t'kind: decide_next_action -> { response: \"next_action\", action: <Action e.g. {action:\"click\", ' +\n\t\t\t'selector, fallbacks?}> }; classify_state -> { response: \"state\", state }; verify_visual -> ' +\n\t\t\t'{ response: \"verified\", passed }; extract_semantic -> { response: \"extracted\", fields }; ' +\n\t\t\t'reidentify_element -> { response: \"element\", selector }. Off by default; enabled with ' +\n\t\t\t\"--enable-browsertools.\",\n\t\tparameters: browserContinueSchema,\n\t\tasync execute(_toolCallId, params: BrowserContinueInput, signal) {\n\t\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\n\t\t\tconst session = takeSession(params.token);\n\t\t\tif (!session) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No paused browser flow for token \"${params.token}\" — it may have completed, expired (idle ` +\n\t\t\t\t\t\t`timeout), or never existed. Start a new flow with browser_run.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst { client } = session;\n\t\t\tconst onAbort = () => client.dispose();\n\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\ttry {\n\t\t\t\tconst outcome = await client.request<FlowOutcome>(\"flow_resume\", {\n\t\t\t\t\ttoken: params.token,\n\t\t\t\t\tresponse: params.response,\n\t\t\t\t});\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tclient.dispose();\n\t\t\t\t\tthrow new Error(\"Operation aborted\");\n\t\t\t\t}\n\t\t\t\t// Preserve the original browser config so the idle client can be reused\n\t\t\t\t// by a subsequent browser_run with the same headful/browserPath settings.\n\t\t\t\tconst browserConfig: BrowserClientConfig = {\n\t\t\t\t\theadful: session.headful,\n\t\t\t\t\tbrowserPath: session.browserPath,\n\t\t\t\t\tidleTimeoutMs: opts.idleTimeoutMs,\n\t\t\t\t};\n\t\t\t\t// Count this resume as one more NeedsParent round if it suspends again.\n\t\t\t\treturn await advanceFlow(client, outcome, session.rounds + 1, opts, browserConfig);\n\t\t\t} catch (error) {\n\t\t\t\tclient.dispose();\n\t\t\t\tthrow error;\n\t\t\t} finally {\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t}\n\t\t},\n\t});\n}\n\nexport function createBrowserContinueTool(\n\tcwd: string,\n\toptions?: BrowserContinueToolOptions,\n): AgentTool<typeof browserContinueSchema> {\n\treturn wrapToolDefinition(createBrowserContinueToolDefinition(cwd, options));\n}\n"]}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `browser_continue` tool: answer a `NeedsParent` suspension from `browser_run`.
|
|
3
|
-
*
|
|
4
|
-
* Looks up the paused serve session by its `ResumeToken`, issues `flow_resume`
|
|
5
|
-
* with the parent's decision (a `ParentResponse` object), and maps the next
|
|
6
|
-
* outcome the same way `browser_run` does — completing, failing, or suspending
|
|
7
|
-
* again with a fresh token. The live serve process (and its browser state) is
|
|
8
|
-
* reused across rounds. See {@link browsertools-shared}.
|
|
9
|
-
*/
|
|
10
|
-
import { Type } from "typebox";
|
|
11
|
-
import { defineTool } from "../../extensions/types.js";
|
|
12
|
-
import { wrapToolDefinition } from "../tool-definition-wrapper.js";
|
|
13
|
-
import { advanceFlow } from "./browser-run.js";
|
|
14
|
-
import { resolveBrowsertoolsOptions, takeSession, } from "./browsertools-shared.js";
|
|
15
|
-
const browserContinueSchema = Type.Object({
|
|
16
|
-
token: Type.String({ description: "The resume token returned by a browser_run NeedsParent result." }),
|
|
17
|
-
response: Type.Record(Type.String(), Type.Unknown(), {
|
|
18
|
-
description: "The ParentResponse object answering the request, e.g. " +
|
|
19
|
-
'{ "response": "state", "state": "logged_in" } or { "response": "verified", "passed": true }.',
|
|
20
|
-
}),
|
|
21
|
-
});
|
|
22
|
-
export function createBrowserContinueToolDefinition(
|
|
23
|
-
// cwd is part of the factory signature for parity with other tools, but continue
|
|
24
|
-
// reuses the serve process parked by browser_run, so it is not needed here.
|
|
25
|
-
_cwd, options) {
|
|
26
|
-
const opts = resolveBrowsertoolsOptions(options);
|
|
27
|
-
return defineTool({
|
|
28
|
-
name: "browser_continue",
|
|
29
|
-
label: "browser continue",
|
|
30
|
-
description: "Continue a browser flow that suspended with a NeedsParent request. Pass the token from the " +
|
|
31
|
-
"browser_run result and a ParentResponse object answering the request. The flow continues " +
|
|
32
|
-
"deterministically and either completes, fails, or suspends again with a new token — in which " +
|
|
33
|
-
"case read the new screenshot and call browser_continue again, looping until the outcome is " +
|
|
34
|
-
"`complete`. Do not abandon the loop to read the page with webfetch. ParentResponse by request " +
|
|
35
|
-
'kind: decide_next_action -> { response: "next_action", action: <Action e.g. {action:"click", ' +
|
|
36
|
-
'selector, fallbacks?}> }; classify_state -> { response: "state", state }; verify_visual -> ' +
|
|
37
|
-
'{ response: "verified", passed }; extract_semantic -> { response: "extracted", fields }; ' +
|
|
38
|
-
'reidentify_element -> { response: "element", selector }. Off by default; enabled with ' +
|
|
39
|
-
"--enable-browsertools.",
|
|
40
|
-
parameters: browserContinueSchema,
|
|
41
|
-
async execute(_toolCallId, params, signal) {
|
|
42
|
-
if (signal?.aborted)
|
|
43
|
-
throw new Error("Operation aborted");
|
|
44
|
-
const session = takeSession(params.token);
|
|
45
|
-
if (!session) {
|
|
46
|
-
throw new Error(`No paused browser flow for token "${params.token}" — it may have completed, expired (idle ` +
|
|
47
|
-
`timeout), or never existed. Start a new flow with browser_run.`);
|
|
48
|
-
}
|
|
49
|
-
const { client } = session;
|
|
50
|
-
const onAbort = () => client.dispose();
|
|
51
|
-
signal?.addEventListener("abort", onAbort, { once: true });
|
|
52
|
-
try {
|
|
53
|
-
const outcome = await client.request("flow_resume", {
|
|
54
|
-
token: params.token,
|
|
55
|
-
response: params.response,
|
|
56
|
-
});
|
|
57
|
-
if (signal?.aborted) {
|
|
58
|
-
client.dispose();
|
|
59
|
-
throw new Error("Operation aborted");
|
|
60
|
-
}
|
|
61
|
-
// Preserve the original browser config so the idle client can be reused
|
|
62
|
-
// by a subsequent browser_run with the same headful/browserPath settings.
|
|
63
|
-
const browserConfig = {
|
|
64
|
-
headful: session.headful,
|
|
65
|
-
browserPath: session.browserPath,
|
|
66
|
-
idleTimeoutMs: opts.idleTimeoutMs,
|
|
67
|
-
};
|
|
68
|
-
// Count this resume as one more NeedsParent round if it suspends again.
|
|
69
|
-
return await advanceFlow(client, outcome, session.rounds + 1, opts, browserConfig);
|
|
70
|
-
}
|
|
71
|
-
catch (error) {
|
|
72
|
-
client.dispose();
|
|
73
|
-
throw error;
|
|
74
|
-
}
|
|
75
|
-
finally {
|
|
76
|
-
signal?.removeEventListener("abort", onAbort);
|
|
77
|
-
}
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
export function createBrowserContinueTool(cwd, options) {
|
|
82
|
-
return wrapToolDefinition(createBrowserContinueToolDefinition(cwd, options));
|
|
83
|
-
}
|
|
84
|
-
//# sourceMappingURL=browser-continue.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"browser-continue.js","sourceRoot":"","sources":["../../../../src/core/tools/browser/browser-continue.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * `browser_continue` tool: answer a `NeedsParent` suspension from `browser_run`.\n *\n * Looks up the paused serve session by its `ResumeToken`, issues `flow_resume`\n * with the parent's decision (a `ParentResponse` object), and maps the next\n * outcome the same way `browser_run` does — completing, failing, or suspending\n * again with a fresh token. The live serve process (and its browser state) is\n * reused across rounds. See {@link browsertools-shared}.\n */\n\nimport type { AgentTool } from \"@kolisachint/hoocode-agent-core\";\nimport { type Static, Type } from \"typebox\";\nimport { defineTool, type ToolDefinition } from \"../../extensions/types.js\";\nimport { wrapToolDefinition } from \"../tool-definition-wrapper.js\";\nimport { advanceFlow, type BrowserRunDetails } from \"./browser-run.js\";\nimport {\n\ttype BrowserClientConfig,\n\ttype BrowsertoolsToolOptions,\n\ttype FlowOutcome,\n\tresolveBrowsertoolsOptions,\n\ttakeSession,\n} from \"./browsertools-shared.js\";\n\nconst browserContinueSchema = Type.Object({\n\ttoken: Type.String({ description: \"The resume token returned by a browser_run NeedsParent result.\" }),\n\tresponse: Type.Record(Type.String(), Type.Unknown(), {\n\t\tdescription:\n\t\t\t\"The ParentResponse object answering the request, e.g. \" +\n\t\t\t'{ \"response\": \"state\", \"state\": \"logged_in\" } or { \"response\": \"verified\", \"passed\": true }.',\n\t}),\n});\n\nexport type BrowserContinueInput = Static<typeof browserContinueSchema>;\n\nexport interface BrowserContinueToolOptions extends BrowsertoolsToolOptions {}\n\nexport function createBrowserContinueToolDefinition(\n\t// cwd is part of the factory signature for parity with other tools, but continue\n\t// reuses the serve process parked by browser_run, so it is not needed here.\n\t_cwd: string,\n\toptions?: BrowserContinueToolOptions,\n): ToolDefinition<typeof browserContinueSchema, BrowserRunDetails> {\n\tconst opts = resolveBrowsertoolsOptions(options);\n\treturn defineTool({\n\t\tname: \"browser_continue\",\n\t\tlabel: \"browser continue\",\n\t\tdescription:\n\t\t\t\"Continue a browser flow that suspended with a NeedsParent request. Pass the token from the \" +\n\t\t\t\"browser_run result and a ParentResponse object answering the request. The flow continues \" +\n\t\t\t\"deterministically and either completes, fails, or suspends again with a new token — in which \" +\n\t\t\t\"case read the new screenshot and call browser_continue again, looping until the outcome is \" +\n\t\t\t\"`complete`. Do not abandon the loop to read the page with webfetch. ParentResponse by request \" +\n\t\t\t'kind: decide_next_action -> { response: \"next_action\", action: <Action e.g. {action:\"click\", ' +\n\t\t\t'selector, fallbacks?}> }; classify_state -> { response: \"state\", state }; verify_visual -> ' +\n\t\t\t'{ response: \"verified\", passed }; extract_semantic -> { response: \"extracted\", fields }; ' +\n\t\t\t'reidentify_element -> { response: \"element\", selector }. Off by default; enabled with ' +\n\t\t\t\"--enable-browsertools.\",\n\t\tparameters: browserContinueSchema,\n\t\tasync execute(_toolCallId, params: BrowserContinueInput, signal) {\n\t\t\tif (signal?.aborted) throw new Error(\"Operation aborted\");\n\n\t\t\tconst session = takeSession(params.token);\n\t\t\tif (!session) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`No paused browser flow for token \"${params.token}\" — it may have completed, expired (idle ` +\n\t\t\t\t\t\t`timeout), or never existed. Start a new flow with browser_run.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst { client } = session;\n\t\t\tconst onAbort = () => client.dispose();\n\t\t\tsignal?.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\ttry {\n\t\t\t\tconst outcome = await client.request<FlowOutcome>(\"flow_resume\", {\n\t\t\t\t\ttoken: params.token,\n\t\t\t\t\tresponse: params.response,\n\t\t\t\t});\n\t\t\t\tif (signal?.aborted) {\n\t\t\t\t\tclient.dispose();\n\t\t\t\t\tthrow new Error(\"Operation aborted\");\n\t\t\t\t}\n\t\t\t\t// Preserve the original browser config so the idle client can be reused\n\t\t\t\t// by a subsequent browser_run with the same headful/browserPath settings.\n\t\t\t\tconst browserConfig: BrowserClientConfig = {\n\t\t\t\t\theadful: session.headful,\n\t\t\t\t\tbrowserPath: session.browserPath,\n\t\t\t\t\tidleTimeoutMs: opts.idleTimeoutMs,\n\t\t\t\t};\n\t\t\t\t// Count this resume as one more NeedsParent round if it suspends again.\n\t\t\t\treturn await advanceFlow(client, outcome, session.rounds + 1, opts, browserConfig);\n\t\t\t} catch (error) {\n\t\t\t\tclient.dispose();\n\t\t\t\tthrow error;\n\t\t\t} finally {\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t}\n\t\t},\n\t});\n}\n\nexport function createBrowserContinueTool(\n\tcwd: string,\n\toptions?: BrowserContinueToolOptions,\n): AgentTool<typeof browserContinueSchema> {\n\treturn wrapToolDefinition(createBrowserContinueToolDefinition(cwd, options));\n}\n"]}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `browser_run` tool: start a deterministic browsertools flow.
|
|
3
|
-
*
|
|
4
|
-
* Spawns a `browsertools serve` process and issues `flow_start`. If the flow
|
|
5
|
-
* runs to completion deterministically it returns the evidence inline. If replay
|
|
6
|
-
* hits a point only an LLM can resolve, the serve process suspends with
|
|
7
|
-
* `Outcome::NeedsParent`: this tool fetches the suspension screenshot, parks the
|
|
8
|
-
* live session under its `ResumeToken`, and returns the typed `ParentRequest`
|
|
9
|
-
* (plus the screenshot as an image) to the agent. The agent reasons and answers
|
|
10
|
-
* with the companion `browser_continue` tool. See {@link browsertools-shared}.
|
|
11
|
-
*/
|
|
12
|
-
import type { AgentTool } from "@kolisachint/hoocode-agent-core";
|
|
13
|
-
import { type Static, Type } from "typebox";
|
|
14
|
-
import type { AgentToolResult } from "../../extensions/types.js";
|
|
15
|
-
import { type ToolDefinition } from "../../extensions/types.js";
|
|
16
|
-
import { type BrowserClientConfig, BrowsertoolsServeClient, type BrowsertoolsToolOptions, type FlowOutcome, type ParentRequest, type ResumeToken, resolveBrowsertoolsOptions } from "./browsertools-shared.js";
|
|
17
|
-
declare const browserRunSchema: Type.TObject<{
|
|
18
|
-
flow_path: Type.TOptional<Type.TString>;
|
|
19
|
-
flow: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
20
|
-
vars: Type.TOptional<Type.TRecord<"^.*$", Type.TUnknown>>;
|
|
21
|
-
store: Type.TOptional<Type.TString>;
|
|
22
|
-
live_view: Type.TOptional<Type.TBoolean>;
|
|
23
|
-
headful: Type.TOptional<Type.TBoolean>;
|
|
24
|
-
}>;
|
|
25
|
-
export type BrowserRunInput = Static<typeof browserRunSchema>;
|
|
26
|
-
/** Structured details surfaced alongside the model-facing content. */
|
|
27
|
-
export interface BrowserRunDetails {
|
|
28
|
-
status: "complete" | "needs_parent";
|
|
29
|
-
/** Present when status is "needs_parent": resume with this token. */
|
|
30
|
-
token?: ResumeToken;
|
|
31
|
-
/** Present when status is "needs_parent": the kind of parent request. */
|
|
32
|
-
requestKind?: ParentRequest["request"];
|
|
33
|
-
/** Present when status is "complete": the flow result/evidence. */
|
|
34
|
-
result?: unknown;
|
|
35
|
-
}
|
|
36
|
-
export interface BrowserRunToolOptions extends BrowsertoolsToolOptions {
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* Map a `flow_start`/`flow_resume` outcome to a tool result, owning the live
|
|
40
|
-
* client: dispose it on terminal outcomes, or park it under the new resume token
|
|
41
|
-
* when the flow suspends again. `rounds` is the number of NeedsParent yields seen
|
|
42
|
-
* so far for this flow (including the one being processed), used for the cap.
|
|
43
|
-
*/
|
|
44
|
-
export declare function advanceFlow(client: BrowsertoolsServeClient, outcome: FlowOutcome, rounds: number, opts: ReturnType<typeof resolveBrowsertoolsOptions>, browserConfig?: BrowserClientConfig): Promise<AgentToolResult<BrowserRunDetails>>;
|
|
45
|
-
export declare function createBrowserRunToolDefinition(cwd: string, options?: BrowserRunToolOptions): ToolDefinition<typeof browserRunSchema, BrowserRunDetails>;
|
|
46
|
-
export declare function createBrowserRunTool(cwd: string, options?: BrowserRunToolOptions): AgentTool<typeof browserRunSchema>;
|
|
47
|
-
export {};
|
|
48
|
-
//# sourceMappingURL=browser-run.d.ts.map
|