@taurgis/bonsai 1.0.4 → 1.0.6

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 (93) hide show
  1. package/README.md +81 -2
  2. package/agents/agents/official-docs-researcher.agent.md +10 -1
  3. package/agents/agents/salesforce-docs-researcher.agent.md +126 -0
  4. package/agents/hooks/README.md +62 -0
  5. package/agents/hooks/claude-code/hooks/bonsai-web-fetch.sh +22 -0
  6. package/agents/hooks/claude-code/settings.json +16 -0
  7. package/agents/hooks/codex/hooks/bonsai-user-prompt-context.sh +18 -0
  8. package/agents/hooks/codex/hooks/bonsai-web-fetch.sh +22 -0
  9. package/agents/hooks/codex/hooks.json +28 -0
  10. package/agents/hooks/cursor/hooks/bonsai-web-fetch.sh +21 -0
  11. package/agents/hooks/cursor/hooks.json +12 -0
  12. package/agents/hooks/github-copilot/bonsai-web-fetch.json +23 -0
  13. package/agents/hooks/github-copilot/bonsai-web-fetch.sh +19 -0
  14. package/agents/instructions/salesforce-research.instructions.md +59 -0
  15. package/agents/instructions/web-research.instructions.md +5 -2
  16. package/agents/skills/web-research/SKILL.md +8 -3
  17. package/bin/cli.mjs +35 -8
  18. package/dist/base-command.d.ts +23 -0
  19. package/dist/base-command.js +67 -8
  20. package/dist/commands/config/base.d.ts +2 -0
  21. package/dist/commands/config/base.js +15 -1
  22. package/dist/commands/config/get.d.ts +1 -1
  23. package/dist/commands/config/get.js +6 -7
  24. package/dist/commands/config/index.d.ts +12 -0
  25. package/dist/commands/config/index.js +34 -0
  26. package/dist/commands/config/list.js +4 -4
  27. package/dist/commands/config/set.js +20 -14
  28. package/dist/commands/config/unset.d.ts +1 -1
  29. package/dist/commands/config/unset.js +11 -8
  30. package/dist/commands/fetch.d.ts +5 -0
  31. package/dist/commands/fetch.js +122 -47
  32. package/dist/commands/import.d.ts +4 -0
  33. package/dist/commands/import.js +99 -37
  34. package/dist/commands/inspect.d.ts +4 -0
  35. package/dist/commands/inspect.js +24 -19
  36. package/dist/commands/list.d.ts +2 -2
  37. package/dist/commands/list.js +39 -16
  38. package/dist/commands/prune.d.ts +1 -1
  39. package/dist/commands/prune.js +50 -17
  40. package/dist/commands/search.d.ts +4 -0
  41. package/dist/commands/search.js +102 -41
  42. package/dist/commands/status.d.ts +6 -0
  43. package/dist/commands/status.js +58 -31
  44. package/dist/commands.d.ts +2 -0
  45. package/dist/commands.js +2 -0
  46. package/dist/hooks/command-not-found/suggest.d.ts +9 -0
  47. package/dist/hooks/command-not-found/suggest.js +122 -0
  48. package/dist/lib/argv.d.ts +10 -0
  49. package/dist/lib/argv.js +53 -0
  50. package/dist/lib/config/index.d.ts +1 -1
  51. package/dist/lib/config/index.js +1 -1
  52. package/dist/lib/config/resolve.d.ts +7 -0
  53. package/dist/lib/config/resolve.js +23 -0
  54. package/dist/lib/envelope.d.ts +36 -0
  55. package/dist/lib/envelope.js +76 -0
  56. package/dist/lib/json-meta.d.ts +10 -0
  57. package/dist/lib/json-meta.js +98 -0
  58. package/dist/lib/research/browser.d.ts +12 -0
  59. package/dist/lib/research/browser.js +40 -3
  60. package/dist/lib/research/docs/capabilities.d.ts +1 -1
  61. package/dist/lib/research/docs/discovery-index.d.ts +14 -0
  62. package/dist/lib/research/docs/discovery-index.js +112 -0
  63. package/dist/lib/research/docs/machine-readable.d.ts +2 -2
  64. package/dist/lib/research/docs/machine-readable.js +3 -7
  65. package/dist/lib/research/docs/remote-search-runner.js +61 -1
  66. package/dist/lib/research/docs/sections.d.ts +1 -0
  67. package/dist/lib/research/docs/sections.js +19 -1
  68. package/dist/lib/research/freshness.d.ts +9 -1
  69. package/dist/lib/research/freshness.js +24 -2
  70. package/dist/lib/research/keywords.d.ts +10 -3
  71. package/dist/lib/research/keywords.js +32 -5
  72. package/dist/lib/research/revalidate.js +3 -1
  73. package/dist/lib/research/schema.d.ts +5 -2
  74. package/dist/lib/research/schema.js +12 -1
  75. package/dist/lib/research/secret-scan.js +4 -2
  76. package/dist/lib/research/url.js +5 -2
  77. package/dist/lib/text.d.ts +35 -0
  78. package/dist/lib/text.js +65 -0
  79. package/dist/sites/algolia.d.ts +9 -0
  80. package/dist/sites/algolia.js +26 -0
  81. package/dist/sites/auto.d.ts +8 -0
  82. package/dist/sites/auto.js +30 -0
  83. package/dist/sites/index.js +17 -1
  84. package/dist/sites/nextjs/index.d.ts +2 -0
  85. package/dist/sites/nextjs/index.js +52 -0
  86. package/dist/sites/react/index.d.ts +2 -0
  87. package/dist/sites/react/index.js +17 -0
  88. package/dist/sites/tailwind/index.d.ts +2 -0
  89. package/dist/sites/tailwind/index.js +17 -0
  90. package/dist/sites/vue/index.d.ts +2 -0
  91. package/dist/sites/vue/index.js +17 -0
  92. package/oclif.manifest.json +154 -81
  93. package/package.json +24 -4
package/README.md CHANGED
@@ -4,6 +4,8 @@ Bonsai is a standalone local research cache CLI for AI agents. It turns official
4
4
 
5
5
  The package is published as `@taurgis/bonsai` and installs a `bonsai` binary.
6
6
 
7
+ 📚 **Full documentation: [bonsai.rhino-inquisitor.com](https://bonsai.rhino-inquisitor.com/)**
8
+
7
9
  > Because the npm package is scoped, the correct one-shot command is `npx @taurgis/bonsai ...`. The unscoped `npx bonsai` name resolves to the separate `bonsai` package on npm unless an unscoped shim is published later.
8
10
 
9
11
  ---
@@ -144,6 +146,22 @@ Search cached research by metadata and content snippets.
144
146
  npx @taurgis/bonsai search "<keywords>" [flags]
145
147
  ```
146
148
 
149
+ ### `list`
150
+
151
+ List cached artifacts by metadata filters (`--topic`, `--tags`, `--freshness`, `--artifact-type`, `--capture-method`, `--limit`), newest first, without printing content.
152
+
153
+ ```bash
154
+ npx @taurgis/bonsai list [flags]
155
+ ```
156
+
157
+ ### `prune`
158
+
159
+ Delete old or inactive cache entries. Requires a filter (`--older-than`, `--inactive`, or `--artifact-type`) and either `--dry-run` or `--yes`.
160
+
161
+ ```bash
162
+ npx @taurgis/bonsai prune --older-than 90d --dry-run
163
+ ```
164
+
147
165
  ### `config`
148
166
 
149
167
  Two keys are configurable:
@@ -162,6 +180,35 @@ Both keys can also be overridden per-invocation via the `BONSAI_STORAGE` and `BO
162
180
 
163
181
  ---
164
182
 
183
+ ## Shell Autocomplete
184
+
185
+ Bonsai ships with shell autocomplete via `@oclif/plugin-autocomplete`. After installing globally, set it up once for your shell:
186
+
187
+ ```bash
188
+ # Bash — add to ~/.bashrc
189
+ eval "$(bonsai autocomplete bash)"
190
+
191
+ # Zsh — add to ~/.zshrc
192
+ eval "$(bonsai autocomplete zsh)"
193
+
194
+ # Fish
195
+ bonsai autocomplete fish > ~/.config/fish/completions/bonsai.fish
196
+ ```
197
+
198
+ To see full setup instructions including the copy-paste snippet for your shell:
199
+
200
+ ```bash
201
+ bonsai autocomplete
202
+ ```
203
+
204
+ Refresh cached completions after upgrading:
205
+
206
+ ```bash
207
+ bonsai autocomplete --refresh-cache
208
+ ```
209
+
210
+ ---
211
+
165
212
  ## Freshness and Cache Rules
166
213
 
167
214
  Global cache files live in Bonsai's oclif data directory, typically:
@@ -228,6 +275,30 @@ When run with `--json`, commands return a stable envelope:
228
275
 
229
276
  ---
230
277
 
278
+ ## Environment Variables
279
+
280
+ | Variable | Effect |
281
+ | --- | --- |
282
+ | `BONSAI_STORAGE` | Override the default storage location per-invocation (`global` or `project`). |
283
+ | `BONSAI_SUMMARY` | Override the summary compression level per-invocation (`conservative`, `balanced`, or `aggressive`). |
284
+ | `NO_COLOR` | Disable all ANSI color output (also respected via `TERM=dumb`). |
285
+ | `NO_UPDATE_NOTIFIER` | Suppress the "update available" notification. |
286
+ | `CI` | Set to `1` or `true` to suppress the update notification in CI environments (detected automatically). |
287
+ | `DEBUG` | Enable debug output for specific Bonsai namespaces, e.g. `DEBUG=bonsai:*`. |
288
+
289
+ ---
290
+
291
+ ## Exit Codes
292
+
293
+ | Code | Meaning |
294
+ | --- | --- |
295
+ | `0` | Success. |
296
+ | `1` | Runtime failure (network error, fetch failed, file read error). |
297
+ | `2` | Usage error (invalid flag, bad URL, missing required argument). |
298
+ | `5` | Stale content served — the cache entry is past its grace window but `--allow-stale` is set. The returned content is still usable. |
299
+
300
+ ---
301
+
231
302
  ## Security and Limits
232
303
 
233
304
  * Fetched HTML is treated as untrusted input.
@@ -240,6 +311,14 @@ When run with `--json`, commands return a stable envelope:
240
311
 
241
312
  ## Reference Documentation
242
313
 
243
- * [Command Reference](docs/commands.md)
244
- * [Caching Protocol Specification](docs/cache-protocol.md)
314
+ The full documentation site lives at
315
+ **[bonsai.rhino-inquisitor.com](https://bonsai.rhino-inquisitor.com/)** (built with
316
+ VitePress from the [`docs/`](docs/) folder). Key pages:
317
+
318
+ * [Getting Started](docs/guide/getting-started.md)
319
+ * [Caching & Freshness](docs/concepts/caching-and-freshness.md)
320
+ * [Compression & Token Budgeting](docs/concepts/compression.md)
321
+ * [Agent Integration](docs/how-to/agent-integration.md)
322
+ * [Command Reference](docs/reference/commands.md)
323
+ * [Caching Protocol Specification](docs/reference/cache-protocol.md)
245
324
  * [Troubleshooting and Limitations](docs/troubleshooting.md)
@@ -5,7 +5,7 @@ model: 'Auto'
5
5
  tools: ['vscode/askQuestions', 'execute', 'read', 'search', 'web', 'vscode/memory']
6
6
  argument-hint: 'What topic should I research in official docs?'
7
7
  metadata:
8
- version: '3.0.0'
8
+ version: '3.0.1'
9
9
  ---
10
10
 
11
11
  # Official Docs Researcher Agent
@@ -24,7 +24,16 @@ Do not research from memory alone. Training-data knowledge does not satisfy this
24
24
  2. Search the Bonsai cache first:
25
25
 
26
26
  ```bash
27
+ # 1. Default search: Checks the local cache across EVERYTHING you've researched,
28
+ # including domains that do not support online search APIs.
27
29
  bonsai search "<topic or keywords>"
30
+
31
+ # 2. Remote API search: Use this to quickly find URLs for documentation pages online
32
+ # ONLY if you don't find any information in the local cache.
33
+ bonsai search "<topic or keywords>" --domain <domain>
34
+ # Supported domains: help.salesforce.com, react.dev, vuejs.org, tailwindcss.com, nextjs.org,
35
+ # jestjs.io, cypress.io, vitest.dev, vitepress.dev, angular.dev, redux.js.org,
36
+ # vitejs.dev, fastify.dev, rollupjs.org, vueuse.org
28
37
  ```
29
38
 
30
39
  3. If the cache misses or does not cover the question, locate official source URLs. Prefer vendor docs, standards bodies, API references, and official release notes.
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: 'Salesforce Docs Researcher'
3
+ description: 'Researches official documentation through Bonsai and returns source-cited findings, specialized for Salesforce Help and Developer docs'
4
+ model: 'Auto'
5
+ tools: ['vscode/askQuestions', 'execute', 'read', 'search', 'web', 'vscode/memory']
6
+ argument-hint: 'What Salesforce topic should I research in official docs?'
7
+ metadata:
8
+ version: '1.0.1'
9
+ ---
10
+
11
+ # Salesforce Docs Researcher Agent
12
+
13
+ You are a Forward documentation research specialist. Your job is to find current official documentation, cache it through Bonsai, and return concise source-cited findings that another agent can apply safely. This is the Official Docs Researcher specialized for Salesforce: the same workflow, plus the Salesforce site-module notes in "Working with Salesforce Sites" below.
14
+
15
+ ## Scope
16
+
17
+ Use this agent for technical changes, platform behavior, APIs, SDKs, standards, release notes, changelogs, beta docs, security advisories, and other documentation-sensitive work. For Salesforce that includes Apex, SOQL, Flows, permissions, Setup, packaging, and the REST, Bulk, and Metadata APIs, plus Lightning and LWC references.
18
+
19
+ Do not research from memory alone. Training-data knowledge does not satisfy this workflow.
20
+
21
+ ## Default Workflow
22
+
23
+ 1. Identify the product, version, edition, and source authority needed for the request.
24
+ 2. Search the Bonsai cache first:
25
+
26
+ ```bash
27
+ # 1. Default search: Checks the local cache across EVERYTHING you've researched,
28
+ # including domains that do not support online search APIs.
29
+ bonsai search "<topic or keywords>"
30
+
31
+ # 2. Remote API search: Use this to quickly find URLs for documentation pages online
32
+ # ONLY if you don't find any information in the local cache.
33
+ bonsai search "<topic or keywords>" --domain <domain>
34
+ # Supported domains: help.salesforce.com, react.dev, vuejs.org, tailwindcss.com, nextjs.org,
35
+ # jestjs.io, cypress.io, vitest.dev, vitepress.dev, angular.dev, redux.js.org,
36
+ # vitejs.dev, fastify.dev, rollupjs.org, vueuse.org
37
+ ```
38
+
39
+ 3. If the cache misses or does not cover the question, locate official source URLs. Prefer vendor docs, standards bodies, API references, and official release notes.
40
+ 4. Capture each source through Bonsai:
41
+
42
+ ```bash
43
+ bonsai <official-url> --format detailed
44
+ ```
45
+
46
+ 5. Use `--rendered` for SPAs or pages where static extraction is incomplete:
47
+
48
+ ```bash
49
+ bonsai <official-url> --rendered --format detailed
50
+ ```
51
+
52
+ 6. Summarize only what the official sources support. Include source URLs, validation time when available, version notes, and any important limitations.
53
+
54
+ Inside the Bonsai repository, use the development binary instead of an installed global command:
55
+
56
+ ```bash
57
+ node bin/cli.mjs search "<topic or keywords>" --json
58
+ node bin/cli.mjs <official-url> --format detailed --json
59
+ ```
60
+
61
+ For one-shot published usage outside this repo, use the scoped package name:
62
+
63
+ ```bash
64
+ npx @taurgis/bonsai <official-url> --format detailed
65
+ ```
66
+
67
+ Do not document or run bare `npx bonsai` unless an unscoped npm shim is actually published.
68
+
69
+ ## Working with Salesforce Sites
70
+
71
+ Salesforce Help and Developer docs are Lightning Web Runtime (LWR) pages: the article text is rendered by JavaScript, so a plain fetch returns an almost-empty shell. Bonsai ships a per-host **site module** that forces browser rendering and runs Salesforce-specific extraction, so a normal Bonsai fetch already returns clean Markdown for these hosts — you do not need to add `--rendered` yourself.
72
+
73
+ | Host | Module | Capabilities |
74
+ | --- | --- | --- |
75
+ | `help.salesforce.com` | `salesforce` (Salesforce Help) | Rendered fetch and live `--domain` search (Coveo backend) |
76
+ | `developer.salesforce.com` | `salesforce-developer` (Salesforce Developer) | Rendered fetch only — no search |
77
+
78
+ - **Search Help live.** For Help topics where you do not yet have a URL, search Salesforce's own backend instead of guessing:
79
+
80
+ ```bash
81
+ npx @taurgis/bonsai search "single sign-on" --domain help.salesforce.com
82
+ ```
83
+
84
+ Results come straight from Coveo and are validated against an allow-list of Salesforce documentation hosts. There is no `--domain` search for `developer.salesforce.com`; passing it exits with an error, so find Developer URLs another way, then fetch them through Bonsai.
85
+ - **Matching is by exact hostname.** `help.salesforce.com` matches; subdomains do not. Prefer canonical `/s/articleView?id=…` Help URLs; Bonsai normalizes legacy `/help_doccontent?id=…` links to them automatically.
86
+ - **Revalidation re-fetches in full.** Module-fetched pages have no cheap `ETag`/`If-Modified-Since` shortcut, so refreshing a stale Salesforce page does a full re-render. `siteModuleId` in the JSON output confirms which module captured a page.
87
+
88
+ ## Freshness Policy
89
+
90
+ Choose the freshness tier based on the source:
91
+
92
+ - `stable`: standards, specs, MDN reference pages, pinned major-version docs.
93
+ - `standard`: vendor API docs, SDK docs, normal technical references.
94
+ - `volatile`: release notes, changelogs, latest pages, security advisories, beta docs.
95
+
96
+ Stale volatile sources must be revalidated before they are trusted. Never overwrite a good cache entry with an error response.
97
+
98
+ ## Fallbacks
99
+
100
+ If direct web access was unavoidable because Bonsai could not fetch the content, import the synthesized notes back into Bonsai before returning:
101
+
102
+ ```bash
103
+ bonsai import <url> --file <path>
104
+ ```
105
+
106
+ For multi-source synthesis:
107
+
108
+ ```bash
109
+ bonsai import \
110
+ --topic "<descriptive topic>" \
111
+ --source-url <url1> \
112
+ --source-url <url2> \
113
+ --file <path>
114
+ ```
115
+
116
+ ## Response Contract
117
+
118
+ Return:
119
+
120
+ - Answer summary.
121
+ - Official source URLs used.
122
+ - Version, edition, or date constraints.
123
+ - Cache status or validation timestamp when Bonsai output provides it.
124
+ - Gaps or uncertainty where official docs do not answer the question.
125
+
126
+ Keep stdout clean when using `--json`; warnings and diagnostic notes belong in stderr or in the final prose summary.
@@ -0,0 +1,62 @@
1
+ # Bonsai Hook Examples
2
+
3
+ These examples show how to steer agents away from one-off web fetch tools and
4
+ toward Bonsai's reusable research cache.
5
+
6
+ They are examples, not an installer contract. Copy the relevant folder contents
7
+ into the agent's native hook location and adjust paths if your repository layout
8
+ differs.
9
+
10
+ ## What The Hooks Do
11
+
12
+ The hooks deny native URL-fetch tools and return model-visible guidance like:
13
+
14
+ ```bash
15
+ bonsai https://example.com/docs --format detailed
16
+ ```
17
+
18
+ Most hook systems cannot transparently replace a web-fetch tool call with a shell
19
+ command. Blocking the native fetch and giving the agent the exact Bonsai command
20
+ is the reliable cross-agent pattern.
21
+
22
+ ## Use With Caution
23
+
24
+ These hooks are intentionally intrusive. If Bonsai fails because of network,
25
+ installation, permissions, or extraction issues, the agent may have no fallback
26
+ path to its native web-fetch tool. That can block valid research instead of
27
+ making it better.
28
+
29
+ Start with one repository, watch how the agent behaves, and remove or narrow the
30
+ hook if it blocks work you still need the native tool to handle.
31
+
32
+ ## Supported Examples
33
+
34
+ | Agent | Native hook file | Example |
35
+ | -------------- | ----------------------- | ----------------- |
36
+ | Claude Code | `.claude/settings.json` | `claude-code/` |
37
+ | GitHub Copilot | `.github/hooks/*.json` | `github-copilot/` |
38
+ | Cursor | `.cursor/hooks.json` | `cursor/` |
39
+ | Codex | `.codex/hooks.json` | `codex/` |
40
+
41
+ Antigravity is intentionally omitted: no current official hook configuration
42
+ surface was found for replacing `read_url_content` or similar URL-fetch tools.
43
+
44
+ Codex has one important limitation: `PreToolUse` hooks cover shell, patch, and
45
+ MCP tool calls, but not every built-in web/search tool. The Codex example blocks
46
+ MCP-style URL fetch tools when they are available and adds prompt-time context
47
+ that tells the agent to prefer Bonsai for URLs.
48
+
49
+ ## Published Command
50
+
51
+ The examples use `bonsai` on the assumption that the CLI is installed. For
52
+ one-shot usage, tell agents to run:
53
+
54
+ ```bash
55
+ npx @taurgis/bonsai <url> --format detailed
56
+ ```
57
+
58
+ Inside the Bonsai repository, use the development binary:
59
+
60
+ ```bash
61
+ node bin/cli.mjs <url> --format detailed
62
+ ```
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ input="$(cat)"
5
+
6
+ node -e '
7
+ const fs = require("node:fs");
8
+ const input = JSON.parse(fs.readFileSync(0, "utf8") || "{}");
9
+ const raw = JSON.stringify(input.tool_input ?? input);
10
+ const match = raw.match(/https?:\/\/[^\s"'\''<>)}\]]+/);
11
+ const url = match ? match[0] : "<url>";
12
+ const command = `bonsai ${url} --format detailed`;
13
+ const reason =
14
+ `Use Bonsai instead of the native web fetch so the result is cached and reusable. Run: ${command}`;
15
+ process.stdout.write(JSON.stringify({
16
+ hookSpecificOutput: {
17
+ hookEventName: "PreToolUse",
18
+ permissionDecision: "deny",
19
+ permissionDecisionReason: reason
20
+ }
21
+ }) + "\n");
22
+ ' <<< "$input"
@@ -0,0 +1,16 @@
1
+ {
2
+ "hooks": {
3
+ "PreToolUse": [
4
+ {
5
+ "matcher": "WebFetch|WebSearch",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "bash .claude/hooks/bonsai-web-fetch.sh",
10
+ "timeout": 10
11
+ }
12
+ ]
13
+ }
14
+ ]
15
+ }
16
+ }
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ input="$(cat)"
5
+
6
+ node -e '
7
+ const fs = require("node:fs");
8
+ const input = JSON.parse(fs.readFileSync(0, "utf8") || "{}");
9
+ const prompt = String(input.prompt ?? "");
10
+ if (!/https?:\/\/\S+/.test(prompt)) process.exit(0);
11
+ process.stdout.write(JSON.stringify({
12
+ hookSpecificOutput: {
13
+ hookEventName: "UserPromptSubmit",
14
+ additionalContext:
15
+ "When fetching documentation or URL content for this prompt, use Bonsai first: bonsai <url> --format detailed. Use --rendered only when static extraction is incomplete."
16
+ }
17
+ }) + "\n");
18
+ ' <<< "$input"
@@ -0,0 +1,22 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ input="$(cat)"
5
+
6
+ node -e '
7
+ const fs = require("node:fs");
8
+ const input = JSON.parse(fs.readFileSync(0, "utf8") || "{}");
9
+ const raw = JSON.stringify(input.tool_input ?? input);
10
+ const match = raw.match(/https?:\/\/[^\s"'\''<>)}\]]+/);
11
+ const url = match ? match[0] : "<url>";
12
+ const command = `bonsai ${url} --format detailed`;
13
+ const reason =
14
+ `Use Bonsai instead of this URL-fetch tool so the result is cached and reusable. Run: ${command}`;
15
+ process.stdout.write(JSON.stringify({
16
+ hookSpecificOutput: {
17
+ hookEventName: "PreToolUse",
18
+ permissionDecision: "deny",
19
+ permissionDecisionReason: reason
20
+ }
21
+ }) + "\n");
22
+ ' <<< "$input"
@@ -0,0 +1,28 @@
1
+ {
2
+ "hooks": {
3
+ "PreToolUse": [
4
+ {
5
+ "matcher": "mcp__.*(web|fetch|get_url_content|read_url_content).*",
6
+ "hooks": [
7
+ {
8
+ "type": "command",
9
+ "command": "bash .codex/hooks/bonsai-web-fetch.sh",
10
+ "timeout": 10,
11
+ "statusMessage": "Routing URL fetch through Bonsai"
12
+ }
13
+ ]
14
+ }
15
+ ],
16
+ "UserPromptSubmit": [
17
+ {
18
+ "hooks": [
19
+ {
20
+ "type": "command",
21
+ "command": "bash .codex/hooks/bonsai-user-prompt-context.sh",
22
+ "timeout": 10
23
+ }
24
+ ]
25
+ }
26
+ ]
27
+ }
28
+ }
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ input="$(cat)"
5
+
6
+ node -e '
7
+ const fs = require("node:fs");
8
+ const input = JSON.parse(fs.readFileSync(0, "utf8") || "{}");
9
+ const raw = JSON.stringify(input.tool_input ?? input.toolArgs ?? input);
10
+ const match = raw.match(/https?:\/\/[^\s"'\''<>)}\]]+/);
11
+ const url = match ? match[0] : "<url>";
12
+ const command = `bonsai ${url} --format detailed`;
13
+ const message =
14
+ `Use Bonsai instead of the native URL fetch so the result is cached and reusable. Run: ${command}`;
15
+ process.stdout.write(JSON.stringify({
16
+ continue: true,
17
+ permission: "deny",
18
+ user_message: "Native web fetch blocked. Use Bonsai for reusable research cache entries.",
19
+ agent_message: message
20
+ }) + "\n");
21
+ ' <<< "$input"
@@ -0,0 +1,12 @@
1
+ {
2
+ "version": 1,
3
+ "hooks": {
4
+ "preToolUse": [
5
+ {
6
+ "command": "bash .cursor/hooks/bonsai-web-fetch.sh",
7
+ "matcher": "web_fetch|WebFetch|read_url_content|get_url_content",
8
+ "timeout": 10
9
+ }
10
+ ]
11
+ }
12
+ }
@@ -0,0 +1,23 @@
1
+ {
2
+ "version": 1,
3
+ "hooks": {
4
+ "preToolUse": [
5
+ {
6
+ "type": "command",
7
+ "matcher": "web_fetch",
8
+ "bash": "bash .github/hooks/bonsai-web-fetch.sh",
9
+ "powershell": "bash .github/hooks/bonsai-web-fetch.sh",
10
+ "timeoutSec": 10
11
+ }
12
+ ],
13
+ "PreToolUse": [
14
+ {
15
+ "type": "command",
16
+ "matcher": "WebFetch",
17
+ "bash": "bash .github/hooks/bonsai-web-fetch.sh",
18
+ "powershell": "bash .github/hooks/bonsai-web-fetch.sh",
19
+ "timeoutSec": 10
20
+ }
21
+ ]
22
+ }
23
+ }
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ input="$(cat)"
5
+
6
+ node -e '
7
+ const fs = require("node:fs");
8
+ const input = JSON.parse(fs.readFileSync(0, "utf8") || "{}");
9
+ const raw = JSON.stringify(input.toolArgs ?? input.tool_input ?? input);
10
+ const match = raw.match(/https?:\/\/[^\s"'\''<>)}\]]+/);
11
+ const url = match ? match[0] : "<url>";
12
+ const command = `bonsai ${url} --format detailed`;
13
+ const reason =
14
+ `Use Bonsai instead of web_fetch so the result is cached and reusable. Run: ${command}`;
15
+ process.stdout.write(JSON.stringify({
16
+ permissionDecision: "deny",
17
+ permissionDecisionReason: reason
18
+ }) + "\n");
19
+ ' <<< "$input"
@@ -0,0 +1,59 @@
1
+ ---
2
+ description: 'Verify current official docs before technical repo changes — inline via the web-research skill for minor research, via the Salesforce Docs Researcher subagent for extensive research. Specialized for Salesforce Help and Developer docs.'
3
+ applyTo: '**'
4
+ skills:
5
+ - web-research
6
+ metadata:
7
+ version: '1.0.2'
8
+ ---
9
+
10
+ # Web Research Requirement (Salesforce)
11
+
12
+ ## Mandatory Pre-Step
13
+
14
+ - Verify the relevant current official documentation **in the same task** before creating, updating, refactoring, scaffolding, or deleting technical content.
15
+ - Apply what you find — cite official source URLs when the change relies on platform behavior or standards.
16
+ - Research is the requirement; how you run it scales with scope (below). Training-data knowledge never satisfies this — only docs fetched in the current task do.
17
+
18
+ ## Choose How to Research by Scope
19
+
20
+ - **Minor research — run it inline.** For a single known page, one platform, or a quick flag/API/version check, the main agent invokes the **web-research** skill directly. A separate subagent is not required.
21
+ - **Extensive research — delegate to a subagent.** For multiple sources or platforms, unfamiliar territory, broad audits, or anything that produces verbose output you do not want in the main context, run the **Salesforce Docs Researcher** subagent and apply its findings.
22
+ - The main agent may always use the **web-research** skill directly — choose the subagent to isolate large research, not because inline research is disallowed.
23
+ - When unsure, start inline and escalate to the subagent once the work spans several sources.
24
+
25
+ ## Shared Cache
26
+
27
+ - **Local Cache Search (Default)**: Always search the local cache first using `bonsai search "<query>"`. This checks everything you've researched across all domains, even ones that don't support online search APIs.
28
+ - **Online URL Discovery (Fallback)**: If the local cache comes up empty, use `--domain <domain>` or `--remote <docs-url>` to quickly hit a site's search API and find the official URLs you need to fetch. This is specifically for online URL discovery when local cache fails.
29
+ - If Bonsai is configured for project storage and `.bonsai/research/` is not ignored by git, treat those cache artifacts as intentional shared project files. It is OK to check them in, and agents must not delete them as incidental generated output without an explicit request.
30
+ - Re-running on a recent topic is cheap — research the topic rather than skipping it to "save" a fetch.
31
+ - Supported remote API domains: `help.salesforce.com`, `react.dev`, `vuejs.org`, `tailwindcss.com`, `nextjs.org`, `jestjs.io`, `cypress.io`, `vitest.dev`, `vitepress.dev`, `angular.dev`, `redux.js.org`, `vitejs.dev`, `fastify.dev`, `rollupjs.org`, `vueuse.org`.
32
+
33
+ ## Working with Salesforce Sites
34
+
35
+ Salesforce Help and Developer docs are JavaScript-rendered (LWR), so Bonsai uses per-host **site modules** that render and extract them for you — a normal Bonsai fetch returns clean Markdown for these hosts without `--rendered`.
36
+
37
+ - **Search Help live** when you do not have a URL yet — this hits Salesforce's own backend, not the local cache:
38
+
39
+ ```bash
40
+ npx @taurgis/bonsai search "single sign-on" --domain help.salesforce.com
41
+ ```
42
+
43
+ - `developer.salesforce.com` has a rendered fetch but **no** `--domain` search (passing it errors); find Developer URLs another way, then fetch them through Bonsai.
44
+ - Matching is by exact hostname; prefer canonical `/s/articleView?id=…` Help URLs (Bonsai normalizes legacy `/help_doccontent?id=…` links automatically).
45
+
46
+ ## When Not to Use
47
+
48
+ - No technical content is being modified (purely editorial changes).
49
+ - You already fetched and applied official docs **in the current task**. Training-data knowledge does not satisfy this — only docs fetched in the same task do.
50
+ - The request is too simple to warrant research (typo, lint fix not involving platform behavior).
51
+
52
+ ## Examples
53
+
54
+ - ✅ Confirming one platform's current flag or frontmatter field before a small edit → run the web-research skill inline.
55
+ - ✅ Finding a Salesforce Help article by topic → `npx @taurgis/bonsai search "<topic>" --domain help.salesforce.com`, then fetch the chosen URL through Bonsai.
56
+ - ✅ Comparing conventions across several platforms, or auditing/refactoring source broadly → delegate to the Salesforce Docs Researcher subagent.
57
+ - ✅ Before editing instructions, prompts, agents, skills, workflows, or docs — reading source code does not replace checking current platform guidance.
58
+ - ✅ Include official source URLs when the change references platform behavior or standards.
59
+ - ❌ Don't modify technical content without researching first, and don't treat cached or training knowledge as equivalent — official guidance evolves and must be verified per task.
@@ -4,7 +4,7 @@ applyTo: '**'
4
4
  skills:
5
5
  - web-research
6
6
  metadata:
7
- version: '3.1.0'
7
+ version: '3.1.2'
8
8
  ---
9
9
 
10
10
  # Web Research Requirement
@@ -24,8 +24,11 @@ metadata:
24
24
 
25
25
  ## Shared Cache
26
26
 
27
- - Both paths use the same freshness-tiered Bonsai cache (data directory or project-local `.bonsai/research/`): it reuses fresh notes, cheaply revalidates stale ones, and re-fetches only on a miss.
27
+ - **Local Cache Search (Default)**: Always search the local cache first using `bonsai search "<query>"`. This checks everything you've researched across all domains, even ones that don't support online search APIs.
28
+ - **Online URL Discovery (Fallback)**: If the local cache comes up empty, use `--domain <domain>` or `--remote <docs-url>` to quickly hit a site's search API and find the official URLs you need to fetch. This is specifically for online URL discovery when local cache fails.
29
+ - If Bonsai is configured for project storage and `.bonsai/research/` is not ignored by git, treat those cache artifacts as intentional shared project files. It is OK to check them in, and agents must not delete them as incidental generated output without an explicit request.
28
30
  - Re-running on a recent topic is cheap — research the topic rather than skipping it to "save" a fetch.
31
+ - Supported remote API domains: `help.salesforce.com`, `react.dev`, `vuejs.org`, `tailwindcss.com`, `nextjs.org`, `jestjs.io`, `cypress.io`, `vitest.dev`, `vitepress.dev`, `angular.dev`, `redux.js.org`, `vitejs.dev`, `fastify.dev`, `rollupjs.org`, `vueuse.org`.
29
32
 
30
33
  ## When Not to Use
31
34
 
@@ -4,7 +4,7 @@ description: 'Bonsai-backed official documentation and web research workflow. Us
4
4
  license: Forward Proprietary
5
5
  compatibility: VS Code 1.x+, GitHub Copilot
6
6
  metadata:
7
- version: '2.1.0'
7
+ version: '2.1.1'
8
8
  ---
9
9
 
10
10
  # Web Research Skill
@@ -15,10 +15,15 @@ Use Bonsai as the cache-first research path for official documentation and web c
15
15
 
16
16
  Before creating, updating, refactoring, scaffolding, or deleting technical content, verify relevant current official documentation in the same task.
17
17
 
18
- Search the cache first:
19
-
20
18
  ```bash
19
+ # 1. Default search: Checks the local cache across EVERYTHING you've researched,
20
+ # including domains that do not support online search APIs.
21
21
  bonsai search "<topic or keywords>"
22
+
23
+ # 2. Remote API search: Use this to quickly find URLs for documentation pages online
24
+ # ONLY if you don't find any information in the local cache.
25
+ bonsai search "<topic or keywords>" --domain <domain>
26
+ # Supported domains: help.salesforce.com, react.dev, vuejs.org, tailwindcss.com, nextjs.org, jestjs.io, cypress.io, vitest.dev, vitepress.dev, angular.dev, redux.js.org, vitejs.dev, fastify.dev, rollupjs.org, vueuse.org
22
27
  ```
23
28
 
24
29
  If the cache misses or does not cover the question, fetch the source through Bonsai: