@taurgis/bonsai 1.0.5 → 3.0.0

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 (126) hide show
  1. package/README.md +59 -12
  2. package/agents/agents/official-docs-researcher.agent.md +15 -26
  3. package/agents/agents/salesforce-docs-researcher.agent.md +17 -35
  4. package/agents/hooks/README.md +2 -9
  5. package/agents/hooks/claude-code/hooks/bonsai-web-fetch.sh +1 -1
  6. package/agents/hooks/codex/hooks/bonsai-user-prompt-context.sh +1 -1
  7. package/agents/hooks/codex/hooks/bonsai-web-fetch.sh +1 -1
  8. package/agents/hooks/cursor/hooks/bonsai-web-fetch.sh +1 -1
  9. package/agents/hooks/github-copilot/bonsai-web-fetch.sh +1 -1
  10. package/agents/instructions/salesforce-research.instructions.md +7 -6
  11. package/agents/instructions/web-research.instructions.md +3 -2
  12. package/agents/skills/web-research/SKILL.md +24 -32
  13. package/bin/cli.mjs +44 -14
  14. package/dist/base-command.d.ts +17 -1
  15. package/dist/base-command.js +70 -9
  16. package/dist/commands/config/base.d.ts +2 -0
  17. package/dist/commands/config/base.js +15 -1
  18. package/dist/commands/config/get.d.ts +1 -1
  19. package/dist/commands/config/get.js +4 -5
  20. package/dist/commands/config/index.d.ts +12 -0
  21. package/dist/commands/config/index.js +34 -0
  22. package/dist/commands/config/list.js +2 -2
  23. package/dist/commands/config/set.js +18 -12
  24. package/dist/commands/config/unset.d.ts +1 -1
  25. package/dist/commands/config/unset.js +9 -6
  26. package/dist/commands/fetch.d.ts +2 -0
  27. package/dist/commands/fetch.js +69 -45
  28. package/dist/commands/import.d.ts +3 -0
  29. package/dist/commands/import.js +91 -53
  30. package/dist/commands/inspect.d.ts +8 -0
  31. package/dist/commands/inspect.js +59 -30
  32. package/dist/commands/list.d.ts +5 -3
  33. package/dist/commands/list.js +60 -35
  34. package/dist/commands/prune.d.ts +2 -1
  35. package/dist/commands/prune.js +62 -19
  36. package/dist/commands/status.d.ts +8 -0
  37. package/dist/commands/status.js +84 -26
  38. package/dist/commands.d.ts +2 -2
  39. package/dist/commands.js +2 -2
  40. package/dist/hooks/command-not-found/suggest.d.ts +7 -1
  41. package/dist/hooks/command-not-found/suggest.js +100 -46
  42. package/dist/lib/argv.d.ts +10 -0
  43. package/dist/lib/argv.js +97 -0
  44. package/dist/lib/color.d.ts +20 -0
  45. package/dist/lib/color.js +36 -0
  46. package/dist/lib/envelope.d.ts +36 -0
  47. package/dist/lib/envelope.js +82 -0
  48. package/dist/lib/help-preflight.d.ts +15 -0
  49. package/dist/lib/help-preflight.js +81 -0
  50. package/dist/lib/json-meta.d.ts +10 -0
  51. package/dist/lib/json-meta.js +98 -0
  52. package/dist/lib/limit-flag.d.ts +1 -0
  53. package/dist/lib/limit-flag.js +24 -0
  54. package/dist/lib/research/{search-index.d.ts → artifact-index.d.ts} +5 -5
  55. package/dist/lib/research/{search-index.js → artifact-index.js} +10 -10
  56. package/dist/lib/research/browser.d.ts +0 -8
  57. package/dist/lib/research/browser.js +20 -43
  58. package/dist/lib/research/regression.d.ts +18 -0
  59. package/dist/lib/research/regression.js +47 -0
  60. package/dist/lib/research/revalidate.js +3 -1
  61. package/dist/lib/research/schema.d.ts +5 -2
  62. package/dist/lib/research/schema.js +12 -1
  63. package/dist/lib/research/storage.d.ts +0 -1
  64. package/dist/lib/research/storage.js +15 -13
  65. package/dist/lib/research/url.d.ts +22 -0
  66. package/dist/lib/research/url.js +63 -1
  67. package/dist/lib/text.d.ts +5 -1
  68. package/dist/lib/text.js +11 -1
  69. package/dist/sites/coveo.d.ts +7 -0
  70. package/dist/sites/coveo.js +33 -0
  71. package/dist/sites/index.js +1 -2
  72. package/dist/sites/salesforce/fetch-page.js +1 -1
  73. package/dist/sites/salesforce/index.js +3 -8
  74. package/dist/sites/salesforce-developer/fetch-page.js +3 -1
  75. package/dist/sites/salesforce-developer/index.js +1 -2
  76. package/dist/sites/salesforce-doc-fetch.d.ts +11 -0
  77. package/dist/sites/salesforce-doc-fetch.js +117 -76
  78. package/dist/sites/salesforce-dom-probe.d.ts +16 -0
  79. package/dist/sites/salesforce-dom-probe.js +114 -0
  80. package/dist/sites/types.d.ts +0 -6
  81. package/oclif.manifest.json +153 -155
  82. package/package.json +38 -25
  83. package/dist/commands/index.d.ts +0 -35
  84. package/dist/commands/index.js +0 -306
  85. package/dist/commands/research/config/base.d.ts +0 -23
  86. package/dist/commands/research/config/base.js +0 -46
  87. package/dist/commands/research/config/get.d.ts +0 -20
  88. package/dist/commands/research/config/get.js +0 -45
  89. package/dist/commands/research/config/list.d.ts +0 -17
  90. package/dist/commands/research/config/list.js +0 -42
  91. package/dist/commands/research/config/set.d.ts +0 -31
  92. package/dist/commands/research/config/set.js +0 -94
  93. package/dist/commands/research/config/unset.d.ts +0 -21
  94. package/dist/commands/research/config/unset.js +0 -59
  95. package/dist/commands/research/import.d.ts +0 -38
  96. package/dist/commands/research/import.js +0 -313
  97. package/dist/commands/research/inspect.d.ts +0 -13
  98. package/dist/commands/research/inspect.js +0 -86
  99. package/dist/commands/research/list.d.ts +0 -25
  100. package/dist/commands/research/list.js +0 -143
  101. package/dist/commands/research/prune.d.ts +0 -24
  102. package/dist/commands/research/prune.js +0 -141
  103. package/dist/commands/research/search.d.ts +0 -32
  104. package/dist/commands/research/search.js +0 -334
  105. package/dist/commands/research/status.d.ts +0 -17
  106. package/dist/commands/research/status.js +0 -108
  107. package/dist/commands/research.d.ts +0 -36
  108. package/dist/commands/research.js +0 -304
  109. package/dist/commands/search.d.ts +0 -31
  110. package/dist/commands/search.js +0 -329
  111. package/dist/lib/research/docs/__fixtures__/sphinx-searchindex.d.ts +0 -1
  112. package/dist/lib/research/docs/__fixtures__/sphinx-searchindex.js +0 -2
  113. package/dist/lib/research/docs/discovery-index.d.ts +0 -14
  114. package/dist/lib/research/docs/discovery-index.js +0 -112
  115. package/dist/lib/research/docs/remote-search-runner.d.ts +0 -21
  116. package/dist/lib/research/docs/remote-search-runner.js +0 -114
  117. package/dist/lib/research/docs/remote-search.d.ts +0 -14
  118. package/dist/lib/research/docs/remote-search.js +0 -101
  119. package/dist/lib/research/docs/search-index.d.ts +0 -13
  120. package/dist/lib/research/docs/search-index.js +0 -176
  121. package/dist/sites/salesforce/browser-search.d.ts +0 -7
  122. package/dist/sites/salesforce/browser-search.js +0 -82
  123. package/dist/sites/salesforce/coveo.d.ts +0 -23
  124. package/dist/sites/salesforce/coveo.js +0 -161
  125. package/dist/sites/salesforce/token.d.ts +0 -26
  126. package/dist/sites/salesforce/token.js +0 -154
package/README.md CHANGED
@@ -20,7 +20,7 @@ The package is published as `@taurgis/bonsai` and installs a `bonsai` binary.
20
20
  | **Freshness tiers** | Supports `stable`, `standard`, `volatile`, custom TTLs, and stale revalidation | Handling standards differently from release notes or beta docs |
21
21
  | **Browser fallback** | Uses `--rendered` for pages that need client-side JavaScript | Capturing SPA documentation when static HTML is incomplete |
22
22
  | **Manual import** | Stores agent-supplied Markdown from stdin or files | Caching synthesized notes, private docs, or manually extracted pages |
23
- | **Search** | Ranks local cache entries by topic, tags, snippets, fuzzy terms, and phrases | Finding existing research before fetching again |
23
+ | **List** | Filters cached entries by topic, tags, freshness, and metadata | Seeing what is already cached without reading full content |
24
24
 
25
25
  ---
26
26
 
@@ -82,10 +82,10 @@ echo "# My Custom Node API Notes" | npx @taurgis/bonsai import https://nodejs.or
82
82
  echo "# Synthesized React Cache Guide" | npx @taurgis/bonsai import --stdin --topic "React Suspense" --source-url https://react.dev/a --source-url https://react.dev/b
83
83
  ```
84
84
 
85
- ### 5. Search before fetching
85
+ ### 5. List cached entries
86
86
 
87
87
  ```bash
88
- npx @taurgis/bonsai search "node api url"
88
+ npx @taurgis/bonsai list --tags node
89
89
  ```
90
90
 
91
91
  ---
@@ -138,14 +138,6 @@ Display stored YAML frontmatter metadata for a URL.
138
138
  npx @taurgis/bonsai inspect <url>
139
139
  ```
140
140
 
141
- ### `search <query>`
142
-
143
- Search cached research by metadata and content snippets.
144
-
145
- ```bash
146
- npx @taurgis/bonsai search "<keywords>" [flags]
147
- ```
148
-
149
141
  ### `list`
150
142
 
151
143
  List cached artifacts by metadata filters (`--topic`, `--tags`, `--freshness`, `--artifact-type`, `--capture-method`, `--limit`), newest first, without printing content.
@@ -156,7 +148,7 @@ npx @taurgis/bonsai list [flags]
156
148
 
157
149
  ### `prune`
158
150
 
159
- Delete old or inactive cache entries. Requires a filter (`--older-than`, `--inactive`, or `--artifact-type`) and either `--dry-run` or `--yes`.
151
+ Delete old or inactive cache entries. Requires a filter (`--older-than`, `--inactive`, `--artifact-type`, or `--url`) and exactly one of `--dry-run` or `--yes` (passing both is a usage error).
160
152
 
161
153
  ```bash
162
154
  npx @taurgis/bonsai prune --older-than 90d --dry-run
@@ -180,6 +172,35 @@ Both keys can also be overridden per-invocation via the `BONSAI_STORAGE` and `BO
180
172
 
181
173
  ---
182
174
 
175
+ ## Shell Autocomplete
176
+
177
+ Bonsai ships with shell autocomplete via `@oclif/plugin-autocomplete`. After installing globally, set it up once for your shell:
178
+
179
+ ```bash
180
+ # Bash — add to ~/.bashrc
181
+ eval "$(bonsai autocomplete bash)"
182
+
183
+ # Zsh — add to ~/.zshrc
184
+ eval "$(bonsai autocomplete zsh)"
185
+
186
+ # Fish
187
+ bonsai autocomplete fish > ~/.config/fish/completions/bonsai.fish
188
+ ```
189
+
190
+ To see full setup instructions including the copy-paste snippet for your shell:
191
+
192
+ ```bash
193
+ bonsai autocomplete
194
+ ```
195
+
196
+ Refresh cached completions after upgrading:
197
+
198
+ ```bash
199
+ bonsai autocomplete --refresh-cache
200
+ ```
201
+
202
+ ---
203
+
183
204
  ## Freshness and Cache Rules
184
205
 
185
206
  Global cache files live in Bonsai's oclif data directory, typically:
@@ -246,6 +267,32 @@ When run with `--json`, commands return a stable envelope:
246
267
 
247
268
  ---
248
269
 
270
+ ## Environment Variables
271
+
272
+ | Variable | Effect |
273
+ | --- | --- |
274
+ | `BONSAI_STORAGE` | Override the default storage location per-invocation (`global` or `project`). |
275
+ | `BONSAI_SUMMARY` | Override the summary compression level per-invocation (`conservative`, `balanced`, or `aggressive`). |
276
+ | `NO_COLOR` | Set to any non-empty value to disable all ANSI color output. An empty `NO_COLOR` is treated as unset. |
277
+ | `FORCE_COLOR` | Set to any value other than an empty string, `0`, or `false` to force ANSI color on, even in non-TTY environments. |
278
+ | `TERM=dumb` | Disables ANSI color output when the terminal cannot render escape sequences. |
279
+ | `NO_UPDATE_NOTIFIER` | Suppress the "update available" notification. |
280
+ | `CI` | Set to `1` or `true` to suppress the update notification in CI environments (detected automatically). |
281
+ | `DEBUG` | Enable debug output for specific Bonsai namespaces, e.g. `DEBUG=bonsai:*`. |
282
+
283
+ ---
284
+
285
+ ## Exit Codes
286
+
287
+ | Code | Meaning |
288
+ | --- | --- |
289
+ | `0` | Success. |
290
+ | `1` | Runtime failure (network error, fetch failed, file read error). |
291
+ | `2` | Usage error (invalid flag, bad URL, missing required argument). |
292
+ | `5` | Stale content served — the cache entry is past its grace window but `--allow-stale` is set. The returned content is still usable. |
293
+
294
+ ---
295
+
249
296
  ## Security and Limits
250
297
 
251
298
  * Fetched HTML is treated as untrusted input.
@@ -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: '4.0.0'
9
9
  ---
10
10
 
11
11
  # Official Docs Researcher Agent
@@ -18,45 +18,34 @@ Use this agent for technical changes, platform behavior, APIs, SDKs, standards,
18
18
 
19
19
  Do not research from memory alone. Training-data knowledge does not satisfy this workflow.
20
20
 
21
- ## Default Workflow
21
+ ## Invocation
22
22
 
23
- 1. Identify the product, version, edition, and source authority needed for the request.
24
- 2. Search the Bonsai cache first:
23
+ Run Bonsai as `npx @taurgis/bonsai ...`. Add `--json` when you need structured output.
25
24
 
26
- ```bash
27
- bonsai search "<topic or keywords>"
28
- ```
25
+ ## Default Workflow
29
26
 
30
- 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.
31
- 4. Capture each source through Bonsai:
27
+ 1. Identify the product, version, edition, and source authority needed for the request.
28
+ 2. Locate official source URLs. Prefer vendor docs, standards bodies, API references, and official release notes. Use your native web/search tools when you do not yet know the URL.
29
+ 3. Capture each source through Bonsai:
32
30
 
33
31
  ```bash
34
- bonsai <official-url> --format detailed
32
+ npx @taurgis/bonsai <official-url> --format detailed
35
33
  ```
36
34
 
37
- 5. Use `--rendered` for SPAs or pages where static extraction is incomplete:
35
+ 4. Use `--rendered` for SPAs or pages where static extraction is incomplete:
38
36
 
39
37
  ```bash
40
- bonsai <official-url> --rendered --format detailed
38
+ npx @taurgis/bonsai <official-url> --rendered --format detailed
41
39
  ```
42
40
 
43
- 6. Summarize only what the official sources support. Include source URLs, validation time when available, version notes, and any important limitations.
41
+ 5. Summarize only what the official sources support. Include source URLs, validation time when available, version notes, and any important limitations.
44
42
 
45
- Inside the Bonsai repository, use the development binary instead of an installed global command:
43
+ For structured output:
46
44
 
47
45
  ```bash
48
- node bin/cli.mjs search "<topic or keywords>" --json
49
- node bin/cli.mjs <official-url> --format detailed --json
46
+ npx @taurgis/bonsai <official-url> --format detailed --json
50
47
  ```
51
48
 
52
- For one-shot published usage outside this repo, use the scoped package name:
53
-
54
- ```bash
55
- npx @taurgis/bonsai <official-url> --format detailed
56
- ```
57
-
58
- Do not document or run bare `npx bonsai` unless an unscoped npm shim is actually published.
59
-
60
49
  ## Freshness Policy
61
50
 
62
51
  Choose the freshness tier based on the source:
@@ -72,13 +61,13 @@ Stale volatile sources must be revalidated before they are trusted. Never overwr
72
61
  If direct web access was unavoidable because Bonsai could not fetch the content, import the synthesized notes back into Bonsai before returning:
73
62
 
74
63
  ```bash
75
- bonsai import <url> --file <path>
64
+ npx @taurgis/bonsai import <url> --file <path>
76
65
  ```
77
66
 
78
67
  For multi-source synthesis:
79
68
 
80
69
  ```bash
81
- bonsai import \
70
+ npx @taurgis/bonsai import \
82
71
  --topic "<descriptive topic>" \
83
72
  --source-url <url1> \
84
73
  --source-url <url2> \
@@ -5,7 +5,7 @@ model: 'Auto'
5
5
  tools: ['vscode/askQuestions', 'execute', 'read', 'search', 'web', 'vscode/memory']
6
6
  argument-hint: 'What Salesforce topic should I research in official docs?'
7
7
  metadata:
8
- version: '1.0.0'
8
+ version: '2.0.0'
9
9
  ---
10
10
 
11
11
  # Salesforce Docs Researcher Agent
@@ -18,61 +18,43 @@ Use this agent for technical changes, platform behavior, APIs, SDKs, standards,
18
18
 
19
19
  Do not research from memory alone. Training-data knowledge does not satisfy this workflow.
20
20
 
21
- ## Default Workflow
21
+ ## Invocation
22
22
 
23
- 1. Identify the product, version, edition, and source authority needed for the request.
24
- 2. Search the Bonsai cache first:
23
+ Run Bonsai as `npx @taurgis/bonsai ...`. Add `--json` when you need structured output.
25
24
 
26
- ```bash
27
- bonsai search "<topic or keywords>"
28
- ```
25
+ ## Default Workflow
29
26
 
30
- 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.
31
- 4. Capture each source through Bonsai:
27
+ 1. Identify the product, version, edition, and source authority needed for the request.
28
+ 2. Locate official Salesforce source URLs. Use your native web/search tools when you do not yet know the URL.
29
+ 3. Capture each source through Bonsai:
32
30
 
33
31
  ```bash
34
- bonsai <official-url> --format detailed
32
+ npx @taurgis/bonsai <official-url> --format detailed
35
33
  ```
36
34
 
37
- 5. Use `--rendered` for SPAs or pages where static extraction is incomplete:
35
+ 4. Use `--rendered` for SPAs or pages where static extraction is incomplete:
38
36
 
39
37
  ```bash
40
- bonsai <official-url> --rendered --format detailed
38
+ npx @taurgis/bonsai <official-url> --rendered --format detailed
41
39
  ```
42
40
 
43
- 6. Summarize only what the official sources support. Include source URLs, validation time when available, version notes, and any important limitations.
41
+ 5. Summarize only what the official sources support. Include source URLs, validation time when available, version notes, and any important limitations.
44
42
 
45
- Inside the Bonsai repository, use the development binary instead of an installed global command:
43
+ For structured output:
46
44
 
47
45
  ```bash
48
- node bin/cli.mjs search "<topic or keywords>" --json
49
- node bin/cli.mjs <official-url> --format detailed --json
46
+ npx @taurgis/bonsai <official-url> --format detailed --json
50
47
  ```
51
48
 
52
- For one-shot published usage outside this repo, use the scoped package name:
53
-
54
- ```bash
55
- npx @taurgis/bonsai <official-url> --format detailed
56
- ```
57
-
58
- Do not document or run bare `npx bonsai` unless an unscoped npm shim is actually published.
59
-
60
49
  ## Working with Salesforce Sites
61
50
 
62
51
  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.
63
52
 
64
53
  | Host | Module | Capabilities |
65
54
  | --- | --- | --- |
66
- | `help.salesforce.com` | `salesforce` (Salesforce Help) | Rendered fetch and live `--domain` search (Coveo backend) |
67
- | `developer.salesforce.com` | `salesforce-developer` (Salesforce Developer) | Rendered fetch only — no search |
68
-
69
- - **Search Help live.** For Help topics where you do not yet have a URL, search Salesforce's own backend instead of guessing:
70
-
71
- ```bash
72
- npx @taurgis/bonsai search "single sign-on" --domain help.salesforce.com
73
- ```
55
+ | `help.salesforce.com` | `salesforce` (Salesforce Help) | Rendered fetch |
56
+ | `developer.salesforce.com` | `salesforce-developer` (Salesforce Developer) | Rendered fetch |
74
57
 
75
- 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.
76
58
  - **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.
77
59
  - **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.
78
60
 
@@ -91,13 +73,13 @@ Stale volatile sources must be revalidated before they are trusted. Never overwr
91
73
  If direct web access was unavoidable because Bonsai could not fetch the content, import the synthesized notes back into Bonsai before returning:
92
74
 
93
75
  ```bash
94
- bonsai import <url> --file <path>
76
+ npx @taurgis/bonsai import <url> --file <path>
95
77
  ```
96
78
 
97
79
  For multi-source synthesis:
98
80
 
99
81
  ```bash
100
- bonsai import \
82
+ npx @taurgis/bonsai import \
101
83
  --topic "<descriptive topic>" \
102
84
  --source-url <url1> \
103
85
  --source-url <url2> \
@@ -12,7 +12,7 @@ differs.
12
12
  The hooks deny native URL-fetch tools and return model-visible guidance like:
13
13
 
14
14
  ```bash
15
- bonsai https://example.com/docs --format detailed
15
+ npx @taurgis/bonsai https://example.com/docs --format detailed
16
16
  ```
17
17
 
18
18
  Most hook systems cannot transparently replace a web-fetch tool call with a shell
@@ -48,15 +48,8 @@ that tells the agent to prefer Bonsai for URLs.
48
48
 
49
49
  ## Published Command
50
50
 
51
- The examples use `bonsai` on the assumption that the CLI is installed. For
52
- one-shot usage, tell agents to run:
51
+ Run Bonsai through the published npm package:
53
52
 
54
53
  ```bash
55
54
  npx @taurgis/bonsai <url> --format detailed
56
55
  ```
57
-
58
- Inside the Bonsai repository, use the development binary:
59
-
60
- ```bash
61
- node bin/cli.mjs <url> --format detailed
62
- ```
@@ -9,7 +9,7 @@ const input = JSON.parse(fs.readFileSync(0, "utf8") || "{}");
9
9
  const raw = JSON.stringify(input.tool_input ?? input);
10
10
  const match = raw.match(/https?:\/\/[^\s"'\''<>)}\]]+/);
11
11
  const url = match ? match[0] : "<url>";
12
- const command = `bonsai ${url} --format detailed`;
12
+ const command = `npx @taurgis/bonsai ${url} --format detailed`;
13
13
  const reason =
14
14
  `Use Bonsai instead of the native web fetch so the result is cached and reusable. Run: ${command}`;
15
15
  process.stdout.write(JSON.stringify({
@@ -12,7 +12,7 @@ process.stdout.write(JSON.stringify({
12
12
  hookSpecificOutput: {
13
13
  hookEventName: "UserPromptSubmit",
14
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."
15
+ "When fetching documentation or URL content for this prompt, use Bonsai first: npx @taurgis/bonsai <url> --format detailed. Use --rendered only when static extraction is incomplete."
16
16
  }
17
17
  }) + "\n");
18
18
  ' <<< "$input"
@@ -9,7 +9,7 @@ const input = JSON.parse(fs.readFileSync(0, "utf8") || "{}");
9
9
  const raw = JSON.stringify(input.tool_input ?? input);
10
10
  const match = raw.match(/https?:\/\/[^\s"'\''<>)}\]]+/);
11
11
  const url = match ? match[0] : "<url>";
12
- const command = `bonsai ${url} --format detailed`;
12
+ const command = `npx @taurgis/bonsai ${url} --format detailed`;
13
13
  const reason =
14
14
  `Use Bonsai instead of this URL-fetch tool so the result is cached and reusable. Run: ${command}`;
15
15
  process.stdout.write(JSON.stringify({
@@ -9,7 +9,7 @@ const input = JSON.parse(fs.readFileSync(0, "utf8") || "{}");
9
9
  const raw = JSON.stringify(input.tool_input ?? input.toolArgs ?? input);
10
10
  const match = raw.match(/https?:\/\/[^\s"'\''<>)}\]]+/);
11
11
  const url = match ? match[0] : "<url>";
12
- const command = `bonsai ${url} --format detailed`;
12
+ const command = `npx @taurgis/bonsai ${url} --format detailed`;
13
13
  const message =
14
14
  `Use Bonsai instead of the native URL fetch so the result is cached and reusable. Run: ${command}`;
15
15
  process.stdout.write(JSON.stringify({
@@ -9,7 +9,7 @@ const input = JSON.parse(fs.readFileSync(0, "utf8") || "{}");
9
9
  const raw = JSON.stringify(input.toolArgs ?? input.tool_input ?? input);
10
10
  const match = raw.match(/https?:\/\/[^\s"'\''<>)}\]]+/);
11
11
  const url = match ? match[0] : "<url>";
12
- const command = `bonsai ${url} --format detailed`;
12
+ const command = `npx @taurgis/bonsai ${url} --format detailed`;
13
13
  const reason =
14
14
  `Use Bonsai instead of web_fetch so the result is cached and reusable. Run: ${command}`;
15
15
  process.stdout.write(JSON.stringify({
@@ -4,7 +4,7 @@ applyTo: '**'
4
4
  skills:
5
5
  - web-research
6
6
  metadata:
7
- version: '1.0.1'
7
+ version: '2.0.0'
8
8
  ---
9
9
 
10
10
  # Web Research Requirement (Salesforce)
@@ -24,7 +24,9 @@ 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
+ - **Invocation**: Run Bonsai as `npx @taurgis/bonsai ...`.
28
+ - **URL discovery**: When you do not yet know the official URL, discover it with your native web/search tools, then fetch the page through Bonsai so it is cached for future agents.
29
+ - **Browse cached entries**: Use `npx @taurgis/bonsai list` when you need to see what is already cached by topic, tags, or freshness.
28
30
  - 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.
29
31
  - Re-running on a recent topic is cheap — research the topic rather than skipping it to "save" a fetch.
30
32
 
@@ -32,13 +34,12 @@ metadata:
32
34
 
33
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`.
34
36
 
35
- - **Search Help live** when you do not have a URL yet — this hits Salesforce's own backend, not the local cache:
37
+ - **Help and Developer fetch.** Once you have a URL, capture it through Bonsai:
36
38
 
37
39
  ```bash
38
- npx @taurgis/bonsai search "single sign-on" --domain help.salesforce.com
40
+ npx @taurgis/bonsai <official-url> --format detailed
39
41
  ```
40
42
 
41
- - `developer.salesforce.com` has a rendered fetch but **no** `--domain` search (passing it errors); find Developer URLs another way, then fetch them through Bonsai.
42
43
  - Matching is by exact hostname; prefer canonical `/s/articleView?id=…` Help URLs (Bonsai normalizes legacy `/help_doccontent?id=…` links automatically).
43
44
 
44
45
  ## When Not to Use
@@ -50,7 +51,7 @@ Salesforce Help and Developer docs are JavaScript-rendered (LWR), so Bonsai uses
50
51
  ## Examples
51
52
 
52
53
  - ✅ Confirming one platform's current flag or frontmatter field before a small edit → run the web-research skill inline.
53
- - ✅ Finding a Salesforce Help article by topic → `npx @taurgis/bonsai search "<topic>" --domain help.salesforce.com`, then fetch the chosen URL through Bonsai.
54
+ - ✅ Finding a Salesforce Help article by topic → discover the official URL with native web/search tools, then fetch it through Bonsai.
54
55
  - ✅ Comparing conventions across several platforms, or auditing/refactoring source broadly → delegate to the Salesforce Docs Researcher subagent.
55
56
  - ✅ Before editing instructions, prompts, agents, skills, workflows, or docs — reading source code does not replace checking current platform guidance.
56
57
  - ✅ Include official source URLs when the change references platform behavior or standards.
@@ -4,7 +4,7 @@ applyTo: '**'
4
4
  skills:
5
5
  - web-research
6
6
  metadata:
7
- version: '3.1.1'
7
+ version: '4.0.0'
8
8
  ---
9
9
 
10
10
  # Web Research Requirement
@@ -24,7 +24,8 @@ 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
+ - **Invocation**: Run Bonsai as `npx @taurgis/bonsai ...`.
28
+ - **URL discovery**: When you do not yet know the official URL, discover it with your native web/search tools, then fetch the page through Bonsai so it is cached for future agents.
28
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.
29
30
  - Re-running on a recent topic is cheap — research the topic rather than skipping it to "save" a fetch.
30
31
 
@@ -1,47 +1,42 @@
1
1
  ---
2
2
  name: web-research
3
- description: 'Bonsai-backed official documentation and web research workflow. Use before technical changes that depend on platform behavior, when fetching documentation or web pages, when searching/listing/pruning the local research cache, or when importing manually gathered notes.'
3
+ description: 'Bonsai-backed official documentation and web research workflow. Use before technical changes that depend on platform behavior, when fetching documentation or web pages, when listing/pruning the local research cache, or when importing manually gathered notes.'
4
4
  license: Forward Proprietary
5
5
  compatibility: VS Code 1.x+, GitHub Copilot
6
6
  metadata:
7
- version: '2.1.0'
7
+ version: '3.0.0'
8
8
  ---
9
9
 
10
10
  # Web Research Skill
11
11
 
12
12
  Use Bonsai as the cache-first research path for official documentation and web content. Prefer current official sources, keep research reusable, and avoid direct one-off web fetches when Bonsai can capture the same page.
13
13
 
14
- ## Required Pre-Step
15
-
16
- Before creating, updating, refactoring, scaffolding, or deleting technical content, verify relevant current official documentation in the same task.
14
+ ## Invocation
17
15
 
18
- Search the cache first:
16
+ Always run Bonsai through the published npm package:
19
17
 
20
18
  ```bash
21
- bonsai search "<topic or keywords>"
19
+ npx @taurgis/bonsai <command> [flags]
22
20
  ```
23
21
 
24
- If the cache misses or does not cover the question, fetch the source through Bonsai:
22
+ Add `--json` when you need machine-readable output for agent callers.
25
23
 
26
- ```bash
27
- bonsai <official-url> --format detailed
28
- ```
24
+ ## Required Pre-Step
29
25
 
30
- Inside the Bonsai repository, use the development binary:
26
+ Before creating, updating, refactoring, scaffolding, or deleting technical content, verify relevant current official documentation in the same task.
27
+
28
+ When you do not yet know the official URL, discover it with your native web/search tools first. Once you have a URL, capture it through Bonsai:
31
29
 
32
30
  ```bash
33
- node bin/cli.mjs search "<topic or keywords>" --json
34
- node bin/cli.mjs <official-url> --format detailed --json
31
+ npx @taurgis/bonsai <official-url> --format detailed
35
32
  ```
36
33
 
37
- For one-shot published usage outside this repo, use the scoped package name:
34
+ For agent callers that need structured output:
38
35
 
39
36
  ```bash
40
- npx @taurgis/bonsai <official-url> --format detailed
37
+ npx @taurgis/bonsai <official-url> --format detailed --json
41
38
  ```
42
39
 
43
- Do not document or run bare `npx bonsai` unless an unscoped npm shim is actually published.
44
-
45
40
  ## Source Rules
46
41
 
47
42
  - Prefer official vendor docs, standards, API references, SDK docs, release notes, changelogs, and security advisories.
@@ -57,13 +52,11 @@ Use `--format compressed` for context-budgeted reading and `--format detailed` f
57
52
  Use `--rendered` when static extraction is incomplete or the page is an SPA:
58
53
 
59
54
  ```bash
60
- bonsai <official-url> --rendered --format detailed
55
+ npx @taurgis/bonsai <official-url> --rendered --format detailed
61
56
  ```
62
57
 
63
58
  Never reach for direct `WebFetch` or `WebSearch` to retrieve a specific page when Bonsai can fetch it. Bonsai returns reusable Markdown and keeps it cached for future agents.
64
59
 
65
- Pure discovery searches are allowed when you do not yet know which URL to fetch. Once a URL is selected, capture it with Bonsai.
66
-
67
60
  ## Manual Fallbacks
68
61
 
69
62
  If direct web access was unavoidable because of authentication, browser interaction, or a tool constraint, import the result into Bonsai before returning.
@@ -71,19 +64,19 @@ If direct web access was unavoidable because of authentication, browser interact
71
64
  Single-source import:
72
65
 
73
66
  ```bash
74
- bonsai import <url> --file path/to/notes.md
67
+ npx @taurgis/bonsai import <url> --file path/to/notes.md
75
68
  ```
76
69
 
77
70
  Stdin import:
78
71
 
79
72
  ```bash
80
- echo "# My Synthesis Note" | bonsai import <url> --stdin
73
+ echo "# My Synthesis Note" | npx @taurgis/bonsai import <url> --stdin
81
74
  ```
82
75
 
83
76
  Multi-source synthesis:
84
77
 
85
78
  ```bash
86
- bonsai import \
79
+ npx @taurgis/bonsai import \
87
80
  --topic "<descriptive topic>" \
88
81
  --source-url <url1> \
89
82
  --source-url <url2> \
@@ -95,27 +88,26 @@ bonsai import \
95
88
  Check status without fetching:
96
89
 
97
90
  ```bash
98
- bonsai status <url>
91
+ npx @taurgis/bonsai status <url>
99
92
  ```
100
93
 
101
94
  Inspect stored metadata:
102
95
 
103
96
  ```bash
104
- bonsai inspect <url>
97
+ npx @taurgis/bonsai inspect <url>
105
98
  ```
106
99
 
107
- List or search cached entries:
100
+ List cached entries by metadata:
108
101
 
109
102
  ```bash
110
- bonsai list --tags node
111
- bonsai search "react suspense"
103
+ npx @taurgis/bonsai list --tags node
112
104
  ```
113
105
 
114
106
  Preview pruning before deleting:
115
107
 
116
108
  ```bash
117
- bonsai prune --older-than 90d --dry-run
118
- bonsai prune --older-than 90d --yes
109
+ npx @taurgis/bonsai prune --older-than 90d --dry-run
110
+ npx @taurgis/bonsai prune --older-than 90d --yes
119
111
  ```
120
112
 
121
113
  ## When This Does Not Apply
@@ -123,4 +115,4 @@ bonsai prune --older-than 90d --yes
123
115
  - No technical content or web content is involved.
124
116
  - You already fetched and applied current official docs in the current task.
125
117
  - The request is a trivial typo or formatting fix that does not involve platform behavior.
126
- - Bonsai is not installed and `npx @taurgis/bonsai ...` is not available; use the best available official-source workflow and import notes later.
118
+ - `npx @taurgis/bonsai` is unavailable in the environment; use the best available official-source workflow and import notes later.
package/bin/cli.mjs CHANGED
@@ -3,6 +3,15 @@
3
3
  import { execute } from '@oclif/core';
4
4
  import { dirname } from 'node:path';
5
5
  import { fileURLToPath } from 'node:url';
6
+ import updateNotifier from 'update-notifier';
7
+ import { createRequire } from 'node:module';
8
+
9
+ import { normalizeArgv } from '../dist/lib/argv.js';
10
+ import { tryUnknownHelpOutput } from '../dist/lib/help-preflight.js';
11
+ import { tryJsonMetaOutput } from '../dist/lib/json-meta.js';
12
+
13
+ const req = createRequire(import.meta.url);
14
+ const pkg = req('../package.json');
6
15
 
7
16
  const __dirname = dirname(fileURLToPath(import.meta.url));
8
17
 
@@ -12,21 +21,42 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
12
21
  // trying to resolve the bare URL as a command — which crashes with a stack trace. Rewrite
13
22
  // process.argv itself so both the run path and the help/error path agree.
14
23
  const rawArgv = process.argv.slice(2);
15
- const [firstArg, ...restArgv] = rawArgv;
16
- // Treat any first arg that looks like a URL (carries a scheme) as the `fetch` shorthand.
17
- // Routing wrong-scheme URLs (ftp://, file://) here too means fetch can answer with a clear
18
- // "only http/https" error instead of oclif's cryptic "command not found".
19
- const looksLikeUrl = firstArg?.includes('://') ?? false;
20
- const normalizedArgv =
21
- firstArg === 'help'
22
- ? [...restArgv, '--help']
23
- : looksLikeUrl
24
- ? ['fetch', ...rawArgv]
25
- : rawArgv;
26
-
27
- process.argv = [process.argv[0], process.argv[1], ...normalizedArgv];
24
+ const result = normalizeArgv(rawArgv);
25
+ const root = __dirname + '/../';
26
+
27
+ if (result.exitWithJson) {
28
+ process.exitCode = result.exitWithJson.exitCode;
29
+ console.log(JSON.stringify(result.exitWithJson.envelope, null, 2));
30
+ process.exit();
31
+ }
32
+
33
+ const unknownHelp = await tryUnknownHelpOutput(result.argv, root);
34
+ if (unknownHelp) {
35
+ process.exitCode = unknownHelp.exitCode;
36
+ if (unknownHelp.kind === 'json') {
37
+ console.log(JSON.stringify(unknownHelp.envelope, null, 2));
38
+ } else {
39
+ console.error(` › Error: ${unknownHelp.message.replaceAll('\n', '\n › ')}`);
40
+ }
41
+ process.exit();
42
+ }
43
+
44
+ const jsonMeta = await tryJsonMetaOutput(result.argv, root);
45
+ if (jsonMeta) {
46
+ process.exitCode = jsonMeta.exitCode;
47
+ console.log(JSON.stringify(jsonMeta.envelope, null, 2));
48
+ process.exit();
49
+ }
50
+
51
+ // Only notify after the exitWithJson fast-path so the notifier never fires before
52
+ // a JSON envelope exits. Also skip under --json so agent callers never see stderr noise.
53
+ if (!process.argv.includes('--json')) {
54
+ updateNotifier({ pkg }).notify();
55
+ }
56
+
57
+ process.argv = [process.argv[0], process.argv[1], ...result.argv];
28
58
 
29
59
  await execute({
30
60
  development: false,
31
- dir: __dirname + '/../',
61
+ dir: root,
32
62
  });