@kolisachint/hoocode-agent 0.5.42 → 0.5.43

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/core/settings-defaults.d.ts +1 -0
  3. package/dist/core/settings-defaults.d.ts.map +1 -1
  4. package/dist/core/settings-defaults.js +1 -0
  5. package/dist/core/settings-defaults.js.map +1 -1
  6. package/dist/core/settings-manager.d.ts +14 -0
  7. package/dist/core/settings-manager.d.ts.map +1 -1
  8. package/dist/core/settings-manager.js +15 -0
  9. package/dist/core/settings-manager.js.map +1 -1
  10. package/dist/core/settings-types.d.ts +3 -0
  11. package/dist/core/settings-types.d.ts.map +1 -1
  12. package/dist/core/settings-types.js.map +1 -1
  13. package/dist/core/tools/webtools-shared.d.ts +53 -2
  14. package/dist/core/tools/webtools-shared.d.ts.map +1 -1
  15. package/dist/core/tools/webtools-shared.js +43 -2
  16. package/dist/core/tools/webtools-shared.js.map +1 -1
  17. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  18. package/dist/modes/interactive/components/settings-selector.js +11 -0
  19. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  20. package/dist/modes/interactive/interactive-mode.d.ts +6 -0
  21. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  22. package/dist/modes/interactive/interactive-mode.js +16 -0
  23. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  24. package/dist/modes/interactive/websearch-warning.d.ts +35 -0
  25. package/dist/modes/interactive/websearch-warning.d.ts.map +1 -0
  26. package/dist/modes/interactive/websearch-warning.js +40 -0
  27. package/dist/modes/interactive/websearch-warning.js.map +1 -0
  28. package/docs/settings.md +52 -2
  29. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  30. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  31. package/examples/extensions/sandbox/package.json +1 -1
  32. package/examples/extensions/with-deps/package.json +1 -1
  33. package/package.json +4 -4
@@ -0,0 +1,35 @@
1
+ /**
2
+ * The "websearch has no API key" startup notice.
3
+ *
4
+ * `websearch` works with no configuration at all, but the keyless default is
5
+ * scraped DuckDuckGo HTML: it is rate-limited hard and can fail outright, and
6
+ * the failure surfaces as a bad search rather than as a setup problem. So when
7
+ * the tool is active and no keyed backend is configured, the session says so
8
+ * once — the same shape as the Anthropic extra-usage notice, including the
9
+ * `/settings` switch that turns it off.
10
+ */
11
+ import type { WarningSettings } from "../../core/settings-types.js";
12
+ import { type WebtoolsSearchSettings } from "../../core/tools/webtools-shared.js";
13
+ export declare const WEBSEARCH_API_KEY_TITLE = "Web search has no API key";
14
+ export interface WebSearchApiKeyNoticeInput {
15
+ /** Tools the session actually exposes; the notice is pointless without `websearch`. */
16
+ activeToolNames: readonly string[];
17
+ /** Warning switches from settings (`warnings.websearchApiKey`). */
18
+ warnings: WarningSettings;
19
+ /** The `webtools.search` block, as the binary would read it. */
20
+ search?: WebtoolsSearchSettings;
21
+ }
22
+ export interface WebSearchApiKeyNotice {
23
+ title: string;
24
+ body: string[];
25
+ }
26
+ /**
27
+ * The notice to show, or undefined when there is nothing to say: the tool is
28
+ * off, a keyed backend is configured, the user pinned the keyless backend on
29
+ * purpose, or the warning is switched off.
30
+ *
31
+ * Pure, so the decision is testable without a TUI; the caller owns the
32
+ * once-per-session latch.
33
+ */
34
+ export declare function websearchApiKeyNotice(input: WebSearchApiKeyNoticeInput): WebSearchApiKeyNotice | undefined;
35
+ //# sourceMappingURL=websearch-warning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websearch-warning.d.ts","sourceRoot":"","sources":["../../../src/modes/interactive/websearch-warning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAA+B,KAAK,sBAAsB,EAAE,MAAM,qCAAqC,CAAC;AAE/G,eAAO,MAAM,uBAAuB,8BAA8B,CAAC;AAEnE,MAAM,WAAW,0BAA0B;IAC1C,uFAAuF;IACvF,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,mEAAmE;IACnE,QAAQ,EAAE,eAAe,CAAC;IAC1B,gEAAgE;IAChE,MAAM,CAAC,EAAE,sBAAsB,CAAC;CAChC;AAED,MAAM,WAAW,qBAAqB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,EAAE,CAAC;CACf;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,0BAA0B,GAAG,qBAAqB,GAAG,SAAS,CAiB1G","sourcesContent":["/**\n * The \"websearch has no API key\" startup notice.\n *\n * `websearch` works with no configuration at all, but the keyless default is\n * scraped DuckDuckGo HTML: it is rate-limited hard and can fail outright, and\n * the failure surfaces as a bad search rather than as a setup problem. So when\n * the tool is active and no keyed backend is configured, the session says so\n * once — the same shape as the Anthropic extra-usage notice, including the\n * `/settings` switch that turns it off.\n */\n\nimport type { WarningSettings } from \"../../core/settings-types.js\";\nimport { resolveWebSearchCredentials, type WebtoolsSearchSettings } from \"../../core/tools/webtools-shared.js\";\n\nexport const WEBSEARCH_API_KEY_TITLE = \"Web search has no API key\";\n\nexport interface WebSearchApiKeyNoticeInput {\n\t/** Tools the session actually exposes; the notice is pointless without `websearch`. */\n\tactiveToolNames: readonly string[];\n\t/** Warning switches from settings (`warnings.websearchApiKey`). */\n\twarnings: WarningSettings;\n\t/** The `webtools.search` block, as the binary would read it. */\n\tsearch?: WebtoolsSearchSettings;\n}\n\nexport interface WebSearchApiKeyNotice {\n\ttitle: string;\n\tbody: string[];\n}\n\n/**\n * The notice to show, or undefined when there is nothing to say: the tool is\n * off, a keyed backend is configured, the user pinned the keyless backend on\n * purpose, or the warning is switched off.\n *\n * Pure, so the decision is testable without a TUI; the caller owns the\n * once-per-session latch.\n */\nexport function websearchApiKeyNotice(input: WebSearchApiKeyNoticeInput): WebSearchApiKeyNotice | undefined {\n\tif (input.warnings.websearchApiKey === false) return undefined;\n\tif (!input.activeToolNames.includes(\"websearch\")) return undefined;\n\n\tconst credentials = resolveWebSearchCredentials(input.search);\n\tif (credentials.configured || credentials.explicitKeyless) return undefined;\n\n\treturn {\n\t\ttitle: WEBSEARCH_API_KEY_TITLE,\n\t\t// Two lines, like the Anthropic notice: what is wrong and the one setting\n\t\t// that fixes it. The other backends and the settings.json block are in\n\t\t// the docs — a startup notice is not the place to list them.\n\t\tbody: [\n\t\t\t\"Searching keyless DuckDuckGo, which is rate-limited. Set BRAVE_API_KEY or TAVILY_API_KEY.\",\n\t\t\t\"Turn off in /settings → Web search API key.\",\n\t\t],\n\t};\n}\n"]}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * The "websearch has no API key" startup notice.
3
+ *
4
+ * `websearch` works with no configuration at all, but the keyless default is
5
+ * scraped DuckDuckGo HTML: it is rate-limited hard and can fail outright, and
6
+ * the failure surfaces as a bad search rather than as a setup problem. So when
7
+ * the tool is active and no keyed backend is configured, the session says so
8
+ * once — the same shape as the Anthropic extra-usage notice, including the
9
+ * `/settings` switch that turns it off.
10
+ */
11
+ import { resolveWebSearchCredentials } from "../../core/tools/webtools-shared.js";
12
+ export const WEBSEARCH_API_KEY_TITLE = "Web search has no API key";
13
+ /**
14
+ * The notice to show, or undefined when there is nothing to say: the tool is
15
+ * off, a keyed backend is configured, the user pinned the keyless backend on
16
+ * purpose, or the warning is switched off.
17
+ *
18
+ * Pure, so the decision is testable without a TUI; the caller owns the
19
+ * once-per-session latch.
20
+ */
21
+ export function websearchApiKeyNotice(input) {
22
+ if (input.warnings.websearchApiKey === false)
23
+ return undefined;
24
+ if (!input.activeToolNames.includes("websearch"))
25
+ return undefined;
26
+ const credentials = resolveWebSearchCredentials(input.search);
27
+ if (credentials.configured || credentials.explicitKeyless)
28
+ return undefined;
29
+ return {
30
+ title: WEBSEARCH_API_KEY_TITLE,
31
+ // Two lines, like the Anthropic notice: what is wrong and the one setting
32
+ // that fixes it. The other backends and the settings.json block are in
33
+ // the docs — a startup notice is not the place to list them.
34
+ body: [
35
+ "Searching keyless DuckDuckGo, which is rate-limited. Set BRAVE_API_KEY or TAVILY_API_KEY.",
36
+ "Turn off in /settings → Web search API key.",
37
+ ],
38
+ };
39
+ }
40
+ //# sourceMappingURL=websearch-warning.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websearch-warning.js","sourceRoot":"","sources":["../../../src/modes/interactive/websearch-warning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,2BAA2B,EAA+B,MAAM,qCAAqC,CAAC;AAE/G,MAAM,CAAC,MAAM,uBAAuB,GAAG,2BAA2B,CAAC;AAgBnE;;;;;;;GAOG;AACH,MAAM,UAAU,qBAAqB,CAAC,KAAiC,EAAqC;IAC3G,IAAI,KAAK,CAAC,QAAQ,CAAC,eAAe,KAAK,KAAK;QAAE,OAAO,SAAS,CAAC;IAC/D,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,QAAQ,CAAC,WAAW,CAAC;QAAE,OAAO,SAAS,CAAC;IAEnE,MAAM,WAAW,GAAG,2BAA2B,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9D,IAAI,WAAW,CAAC,UAAU,IAAI,WAAW,CAAC,eAAe;QAAE,OAAO,SAAS,CAAC;IAE5E,OAAO;QACN,KAAK,EAAE,uBAAuB;QAC9B,0EAA0E;QAC1E,uEAAuE;QACvE,+DAA6D;QAC7D,IAAI,EAAE;YACL,2FAA2F;YAC3F,+CAA6C;SAC7C;KACD,CAAC;AAAA,CACF","sourcesContent":["/**\n * The \"websearch has no API key\" startup notice.\n *\n * `websearch` works with no configuration at all, but the keyless default is\n * scraped DuckDuckGo HTML: it is rate-limited hard and can fail outright, and\n * the failure surfaces as a bad search rather than as a setup problem. So when\n * the tool is active and no keyed backend is configured, the session says so\n * once — the same shape as the Anthropic extra-usage notice, including the\n * `/settings` switch that turns it off.\n */\n\nimport type { WarningSettings } from \"../../core/settings-types.js\";\nimport { resolveWebSearchCredentials, type WebtoolsSearchSettings } from \"../../core/tools/webtools-shared.js\";\n\nexport const WEBSEARCH_API_KEY_TITLE = \"Web search has no API key\";\n\nexport interface WebSearchApiKeyNoticeInput {\n\t/** Tools the session actually exposes; the notice is pointless without `websearch`. */\n\tactiveToolNames: readonly string[];\n\t/** Warning switches from settings (`warnings.websearchApiKey`). */\n\twarnings: WarningSettings;\n\t/** The `webtools.search` block, as the binary would read it. */\n\tsearch?: WebtoolsSearchSettings;\n}\n\nexport interface WebSearchApiKeyNotice {\n\ttitle: string;\n\tbody: string[];\n}\n\n/**\n * The notice to show, or undefined when there is nothing to say: the tool is\n * off, a keyed backend is configured, the user pinned the keyless backend on\n * purpose, or the warning is switched off.\n *\n * Pure, so the decision is testable without a TUI; the caller owns the\n * once-per-session latch.\n */\nexport function websearchApiKeyNotice(input: WebSearchApiKeyNoticeInput): WebSearchApiKeyNotice | undefined {\n\tif (input.warnings.websearchApiKey === false) return undefined;\n\tif (!input.activeToolNames.includes(\"websearch\")) return undefined;\n\n\tconst credentials = resolveWebSearchCredentials(input.search);\n\tif (credentials.configured || credentials.explicitKeyless) return undefined;\n\n\treturn {\n\t\ttitle: WEBSEARCH_API_KEY_TITLE,\n\t\t// Two lines, like the Anthropic notice: what is wrong and the one setting\n\t\t// that fixes it. The other backends and the settings.json block are in\n\t\t// the docs — a startup notice is not the place to list them.\n\t\tbody: [\n\t\t\t\"Searching keyless DuckDuckGo, which is rate-limited. Set BRAVE_API_KEY or TAVILY_API_KEY.\",\n\t\t\t\"Turn off in /settings → Web search API key.\",\n\t\t],\n\t};\n}\n"]}
package/docs/settings.md CHANGED
@@ -74,15 +74,20 @@ Set `HOOCODE_SKIP_VERSION_CHECK=1` to disable the HooCode version update check.
74
74
  | Setting | Type | Default | Description |
75
75
  |---------|------|---------|-------------|
76
76
  | `warnings.anthropicExtraUsage` | boolean | `true` | Show a warning when Anthropic subscription auth may use paid extra usage |
77
+ | `warnings.websearchApiKey` | boolean | `true` | Show a warning when `websearch` is enabled with no search API key, so it falls back to keyless DuckDuckGo |
77
78
 
78
79
  ```json
79
80
  {
80
81
  "warnings": {
81
- "anthropicExtraUsage": false
82
+ "anthropicExtraUsage": false,
83
+ "websearchApiKey": false
82
84
  }
83
85
  }
84
86
  ```
85
87
 
88
+ Both warnings are shown once per session in the TUI and can also be toggled from
89
+ `/settings` → Warnings.
90
+
86
91
  ### Compaction
87
92
 
88
93
  | Setting | Type | Default | Description |
@@ -329,6 +334,7 @@ there.
329
334
  |---------|------|---------|-------------|
330
335
  | `enableWebTools` | boolean | `false` | Enable `webfetch` + `websearch` (network access). Needs the `webtools` binary. |
331
336
  | `webtools.timeoutSecs` | number | `15` | Per-request timeout in seconds, clamped 1–120. Wins over `HOOCODE_WEBTOOLS_TIMEOUT`. |
337
+ | `webtools.search` | object | — | Search backend and credentials, read by the `webtools` binary itself. See [Web search providers](#web-search-providers). |
332
338
  | `enableEmbsearchTools` | boolean | `true` | Build and fuse the semantic index into `search`. Set false to run `search` lexical-only. `grep`/`find` are unaffected. |
333
339
  | `embsearchBinaryPath` | string | — | Explicit path to the `embsearch` binary. Default: resolve from `PATH`. |
334
340
  | `embsearchThresholdBytes` | number | `0` | Minimum indexable source bytes before a repo is embedded. `0` indexes every repo. |
@@ -346,6 +352,49 @@ Environment variables:
346
352
  On Android/Termux the published Linux builds do not run; install with
347
353
  `pkg install <name>` instead.
348
354
 
355
+ #### Web search providers
356
+
357
+ `websearch` needs no configuration: it defaults to keyless DuckDuckGo Lite.
358
+ That backend is scraped HTML, though — rate-limited hard, and it can fail
359
+ outright — so when search reliability matters, point it at a backend with an
360
+ actual API contract. With none configured, the TUI says so once per session
361
+ (see [`warnings.websearchApiKey`](#warnings)).
362
+
363
+ The `webtools` binary reads its own `webtools` key out of the user-level
364
+ `~/.hoocode/settings.json`, using its own (snake_case) key names. HooCode never
365
+ writes this block; it only reads it to tell whether a keyed backend exists. Put
366
+ it in the user-level file — a project `.hoocode/settings.json` is not read by the
367
+ binary, and a file holding credentials is worth keeping out of a working tree.
368
+
369
+ ```json
370
+ {
371
+ "webtools": {
372
+ "search": {
373
+ "provider": "brave",
374
+ "fallback": "duckduckgo",
375
+ "providers": {
376
+ "brave": { "api_key": "..." },
377
+ "tavily": { "api_key": "..." },
378
+ "searxng": { "base_url": "https://searx.internal" }
379
+ }
380
+ }
381
+ }
382
+ }
383
+ ```
384
+
385
+ Environment variables win over the file, so a key can stay out of it entirely:
386
+
387
+ | Variable | Effect |
388
+ |---|---|
389
+ | `WEBTOOLS_SEARCH_PROVIDER` | Backend to use: `duckduckgo` (default), `brave`, `tavily`, `searxng`. Pin `duckduckgo` to accept the keyless backend and silence the warning. |
390
+ | `WEBTOOLS_SEARCH_FALLBACK` | Backend tried when the primary fails; `none` disables the fallback. |
391
+ | `WEBTOOLS_BRAVE_API_KEY`, `BRAVE_API_KEY` | Brave Search key. |
392
+ | `WEBTOOLS_TAVILY_API_KEY`, `TAVILY_API_KEY` | Tavily key. Returns cleaned page content, so a search often answers without a follow-up `webfetch`. |
393
+ | `WEBTOOLS_SEARXNG_URL`, `WEBTOOLS_SEARXNG_API_KEY` | Self-hosted SearXNG endpoint (and optional key), for networks where the public APIs are unreachable. |
394
+
395
+ Every result records the backend that answered it, so a fallback to the scraped
396
+ backend is never silent.
397
+
349
398
  ### Resources
350
399
 
351
400
  These settings define where to load extensions, skills, prompts, and themes from.
@@ -408,7 +457,8 @@ See [packages.md](packages.md) for package management details.
408
457
  },
409
458
  "enabledModels": ["claude-*", "gpt-4o"],
410
459
  "warnings": {
411
- "anthropicExtraUsage": true
460
+ "anthropicExtraUsage": true,
461
+ "websearchApiKey": true
412
462
  },
413
463
  "packages": ["hoocode-skills"]
414
464
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-extension-custom-provider-anthropic",
3
3
  "private": true,
4
- "version": "0.3.42",
4
+ "version": "0.3.43",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "bun": ">=1.0.0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-extension-custom-provider-gitlab-duo",
3
3
  "private": true,
4
- "version": "0.3.42",
4
+ "version": "0.3.43",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "bun": ">=1.0.0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-extension-sandbox",
3
3
  "private": true,
4
- "version": "0.3.42",
4
+ "version": "0.3.43",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "bun": ">=1.0.0"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-extension-with-deps",
3
3
  "private": true,
4
- "version": "0.3.42",
4
+ "version": "0.3.43",
5
5
  "type": "module",
6
6
  "engines": {
7
7
  "bun": ">=1.0.0"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kolisachint/hoocode-agent",
3
- "version": "0.5.42",
3
+ "version": "0.5.43",
4
4
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
5
5
  "type": "module",
6
6
  "hoocodeConfig": {
@@ -50,9 +50,9 @@
50
50
  "prepublishOnly": "npm run clean && npm run build"
51
51
  },
52
52
  "dependencies": {
53
- "@kolisachint/hoocode-agent-core": "^0.5.42",
54
- "@kolisachint/hoocode-ai": "^0.5.42",
55
- "@kolisachint/hoocode-tui": "^0.5.42",
53
+ "@kolisachint/hoocode-agent-core": "^0.5.43",
54
+ "@kolisachint/hoocode-ai": "^0.5.43",
55
+ "@kolisachint/hoocode-tui": "^0.5.43",
56
56
  "@silvia-odwyer/photon-node": "^0.3.4",
57
57
  "chalk": "^5.5.0",
58
58
  "cli-highlight": "^2.1.11",