@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
@@ -4,7 +4,7 @@
4
4
  "aliases": [],
5
5
  "args": {
6
6
  "url": {
7
- "description": "The full HTTP/HTTPS URL of the web page to research.",
7
+ "description": "the full HTTP/HTTPS URL of the web page to research",
8
8
  "name": "url",
9
9
  "required": true
10
10
  }
@@ -12,11 +12,11 @@
12
12
  "description": "Scrapes the specified URL, strips HTML boilerplate, converts the semantic payload into clean Markdown format, and caches the result locally using dynamic TTL rules.\n\nUsually invoked via the shorthand `bonsai <url>` rather than `bonsai fetch <url>`.",
13
13
  "examples": [
14
14
  {
15
- "description": "Research a URL with detailed output, tagged with topic and tags",
15
+ "description": "research a URL with detailed output, tagged with topic and tags",
16
16
  "command": "<%= config.bin %> https://docs.nestjs.com/ --topic \"Backend Frameworks\" --tags \"Node\" --tags \"NestJS\" --format detailed --ttl 30d"
17
17
  },
18
18
  {
19
- "description": "Research a volatile page with compressed output and short TTL, returned as JSON",
19
+ "description": "research a volatile page with compressed output and short TTL, returned as JSON",
20
20
  "command": "<%= config.bin %> https://news.ycombinator.com/ --format compressed --ttl 2h --json"
21
21
  }
22
22
  ],
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "topic": {
32
32
  "char": "t",
33
- "description": "The main category/topic of the research for metadata tagging.",
33
+ "description": "the main category/topic of the research for metadata tagging",
34
34
  "name": "topic",
35
35
  "hasDynamicHelp": false,
36
36
  "multiple": false,
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "tags": {
40
40
  "char": "g",
41
- "description": "Taxonomic tags for this research (can be repeated).",
41
+ "description": "taxonomic tags for this research (can be repeated)",
42
42
  "name": "tags",
43
43
  "hasDynamicHelp": false,
44
44
  "multiple": true,
@@ -46,7 +46,7 @@
46
46
  },
47
47
  "format": {
48
48
  "char": "f",
49
- "description": "Desired data density.",
49
+ "description": "desired data density",
50
50
  "name": "format",
51
51
  "default": "compressed",
52
52
  "hasDynamicHelp": false,
@@ -58,7 +58,7 @@
58
58
  "type": "option"
59
59
  },
60
60
  "tier": {
61
- "description": "Freshness tier policy.",
61
+ "description": "freshness tier policy",
62
62
  "name": "tier",
63
63
  "default": "standard",
64
64
  "hasDynamicHelp": false,
@@ -72,45 +72,45 @@
72
72
  },
73
73
  "ttl": {
74
74
  "char": "l",
75
- "description": "Predicted lifespan: number + h/d/w/m/y (m = months), e.g. \"2h\", \"7d\", \"6m\".",
75
+ "description": "predicted lifespan: number + h/d/w/m/y (m = months), e.g. \"2h\", \"7d\", \"6m\"",
76
76
  "name": "ttl",
77
77
  "hasDynamicHelp": false,
78
78
  "multiple": false,
79
79
  "type": "option"
80
80
  },
81
81
  "max-age": {
82
- "description": "Maximum age of cache to accept (e.g., \"1d\", \"30d\").",
82
+ "description": "maximum age of cache to accept (e.g., \"1d\", \"30d\")",
83
83
  "name": "max-age",
84
84
  "hasDynamicHelp": false,
85
85
  "multiple": false,
86
86
  "type": "option"
87
87
  },
88
88
  "force": {
89
- "description": "Force a fresh fetch, ignoring any cached entries.",
89
+ "description": "force a fresh fetch, ignoring any cached entries",
90
90
  "name": "force",
91
91
  "allowNo": false,
92
92
  "type": "boolean"
93
93
  },
94
94
  "dry-run": {
95
- "description": "Perform validation and fetch without saving to local cache.",
95
+ "description": "perform validation and fetch without saving to local cache",
96
96
  "name": "dry-run",
97
97
  "allowNo": false,
98
98
  "type": "boolean"
99
99
  },
100
100
  "allow-stale": {
101
- "description": "Allow serving stale cache if the remote server is unreachable.",
101
+ "description": "allow serving stale cache if the remote server is unreachable",
102
102
  "name": "allow-stale",
103
103
  "allowNo": false,
104
104
  "type": "boolean"
105
105
  },
106
106
  "rendered": {
107
- "description": "Force using a browser-rendered scraping path for dynamic pages.",
107
+ "description": "force using a browser-rendered scraping path for dynamic pages",
108
108
  "name": "rendered",
109
109
  "allowNo": false,
110
110
  "type": "boolean"
111
111
  },
112
112
  "storage": {
113
- "description": "Override where this result is cached (overrides configured default). Secret-bearing pages are always stored globally.",
113
+ "description": "override where this result is cached (secrets always stored globally)",
114
114
  "name": "storage",
115
115
  "hasDynamicHelp": false,
116
116
  "multiple": false,
@@ -128,7 +128,7 @@
128
128
  "pluginAlias": "@taurgis/bonsai",
129
129
  "pluginName": "@taurgis/bonsai",
130
130
  "pluginType": "core",
131
- "strict": true,
131
+ "strict": false,
132
132
  "summary": "An advanced, locally cached web research tool optimized for LLM ingestion.",
133
133
  "enableJsonFlag": true,
134
134
  "stdoutIsPrimaryData": true
@@ -137,7 +137,7 @@
137
137
  "aliases": [],
138
138
  "args": {
139
139
  "url": {
140
- "description": "The single source URL of the page (only for single-source import).",
140
+ "description": "the single source URL of the page (only for single-source import)",
141
141
  "name": "url",
142
142
  "required": false
143
143
  }
@@ -145,16 +145,20 @@
145
145
  "description": "Accepts a synthesized Markdown note via stdin and registers it under the single target URL or multiple source URLs.",
146
146
  "examples": [
147
147
  {
148
- "description": "Import detailed research for a single URL via stdin",
148
+ "description": "import detailed research for a single URL via stdin",
149
149
  "command": "echo \"# My Article\" | <%= config.bin %> import https://example.com/docs --stdin"
150
150
  },
151
151
  {
152
- "description": "Import research synthesized from multiple source URLs",
152
+ "description": "import research synthesized from multiple source URLs",
153
153
  "command": "echo \"# Synthesized\" | <%= config.bin %> import --stdin --topic \"React docs\" --source-url https://react.dev/a --source-url https://react.dev/b"
154
154
  },
155
155
  {
156
- "description": "Import research from a local Markdown file",
156
+ "description": "import research from a local Markdown file",
157
157
  "command": "<%= config.bin %> import https://example.com/docs --file path/to/notes.md"
158
+ },
159
+ {
160
+ "description": "import research from stdin using the standard file placeholder",
161
+ "command": "cat notes.md | <%= config.bin %> import https://example.com/docs --file -"
158
162
  }
159
163
  ],
160
164
  "flags": {
@@ -166,20 +170,20 @@
166
170
  "type": "boolean"
167
171
  },
168
172
  "stdin": {
169
- "description": "Read Markdown from stdin.",
173
+ "description": "read Markdown from stdin",
170
174
  "name": "stdin",
171
175
  "allowNo": false,
172
176
  "type": "boolean"
173
177
  },
174
178
  "file": {
175
- "description": "Path to a Markdown file containing research notes to import.",
179
+ "description": "path to a Markdown file containing research notes to import, or \"-\" for stdin",
176
180
  "name": "file",
177
181
  "hasDynamicHelp": false,
178
182
  "multiple": false,
179
183
  "type": "option"
180
184
  },
181
185
  "input-format": {
182
- "description": "Format of the input provided.",
186
+ "description": "format of the input provided",
183
187
  "name": "input-format",
184
188
  "default": "detailed",
185
189
  "hasDynamicHelp": false,
@@ -192,7 +196,7 @@
192
196
  },
193
197
  "topic": {
194
198
  "char": "t",
195
- "description": "The main topic for this research note.",
199
+ "description": "the main topic for this research note",
196
200
  "name": "topic",
197
201
  "hasDynamicHelp": false,
198
202
  "multiple": false,
@@ -200,14 +204,14 @@
200
204
  },
201
205
  "tags": {
202
206
  "char": "g",
203
- "description": "Taxonomic tags (can be repeated).",
207
+ "description": "taxonomic tags (can be repeated)",
204
208
  "name": "tags",
205
209
  "hasDynamicHelp": false,
206
210
  "multiple": true,
207
211
  "type": "option"
208
212
  },
209
213
  "tier": {
210
- "description": "Freshness tier policy.",
214
+ "description": "freshness tier policy",
211
215
  "name": "tier",
212
216
  "default": "standard",
213
217
  "hasDynamicHelp": false,
@@ -220,7 +224,7 @@
220
224
  "type": "option"
221
225
  },
222
226
  "source-url": {
223
- "description": "Repeated source URLs for multi-source import.",
227
+ "description": "repeated source URLs for multi-source import",
224
228
  "name": "source-url",
225
229
  "hasDynamicHelp": false,
226
230
  "multiple": true,
@@ -228,14 +232,14 @@
228
232
  },
229
233
  "ttl": {
230
234
  "char": "l",
231
- "description": "Predicted lifespan of the data (e.g. \"24h\", \"7d\").",
235
+ "description": "predicted lifespan of the data (e.g. \"24h\", \"7d\")",
232
236
  "name": "ttl",
233
237
  "hasDynamicHelp": false,
234
238
  "multiple": false,
235
239
  "type": "option"
236
240
  },
237
241
  "storage": {
238
- "description": "Override where this note is cached (overrides configured default). Secret-bearing notes are always stored globally.",
242
+ "description": "override where this note is cached (secrets always stored globally)",
239
243
  "name": "storage",
240
244
  "hasDynamicHelp": false,
241
245
  "multiple": false,
@@ -261,12 +265,22 @@
261
265
  "aliases": [],
262
266
  "args": {
263
267
  "url": {
264
- "description": "The URL to inspect.",
268
+ "description": "the URL to inspect",
265
269
  "name": "url",
266
270
  "required": true
267
271
  }
268
272
  },
269
273
  "description": "Inspects local storage and displays full frontmatter metadata for the URL (without printing the content body).",
274
+ "examples": [
275
+ {
276
+ "description": "inspect cached research metadata for a specific URL",
277
+ "command": "<%= config.bin %> <%= command.id %> https://example.com/docs"
278
+ },
279
+ {
280
+ "description": "output the full metadata as JSON for use by other tools",
281
+ "command": "<%= config.bin %> <%= command.id %> https://example.com/docs --json"
282
+ }
283
+ ],
270
284
  "flags": {
271
285
  "json": {
272
286
  "description": "Format output as json.",
@@ -282,7 +296,7 @@
282
296
  "pluginAlias": "@taurgis/bonsai",
283
297
  "pluginName": "@taurgis/bonsai",
284
298
  "pluginType": "core",
285
- "strict": true,
299
+ "strict": false,
286
300
  "summary": "Inspect cached research metadata for a URL.",
287
301
  "enableJsonFlag": true,
288
302
  "stdoutIsPrimaryData": true
@@ -293,16 +307,20 @@
293
307
  "description": "Lists cached research artifacts, including metadata details like path, source count, freshness, token estimates, and quality metrics without printing full content.",
294
308
  "examples": [
295
309
  {
296
- "description": "List all cached entries",
310
+ "description": "list all cached entries",
297
311
  "command": "<%= config.bin %> list"
298
312
  },
299
313
  {
300
- "description": "List cached entries for a specific topic with JSON output",
314
+ "description": "list cached entries for a specific topic with JSON output",
301
315
  "command": "<%= config.bin %> list --topic \"React Suspense\" --json"
302
316
  },
303
317
  {
304
- "description": "List only fresh entries filtered by tags",
318
+ "description": "list only fresh entries filtered by tags",
305
319
  "command": "<%= config.bin %> list --freshness fresh --tags node --tags url"
320
+ },
321
+ {
322
+ "description": "list entries matching a specific URL glob",
323
+ "command": "<%= config.bin %> list --url \"https://react.dev/*\""
306
324
  }
307
325
  ],
308
326
  "flags": {
@@ -315,7 +333,7 @@
315
333
  },
316
334
  "topic": {
317
335
  "char": "t",
318
- "description": "Filter by exact topic (case-insensitive).",
336
+ "description": "filter by exact topic (case-insensitive)",
319
337
  "name": "topic",
320
338
  "hasDynamicHelp": false,
321
339
  "multiple": false,
@@ -323,14 +341,21 @@
323
341
  },
324
342
  "tags": {
325
343
  "char": "g",
326
- "description": "Filter by tags (must match all tags specified).",
344
+ "description": "filter by tags (must match all tags specified)",
327
345
  "name": "tags",
328
346
  "hasDynamicHelp": false,
329
347
  "multiple": true,
330
348
  "type": "option"
331
349
  },
350
+ "url": {
351
+ "description": "filter by source URL glob pattern (case-insensitive, supports * wildcard)",
352
+ "name": "url",
353
+ "hasDynamicHelp": false,
354
+ "multiple": false,
355
+ "type": "option"
356
+ },
332
357
  "freshness": {
333
- "description": "Filter by freshness state.",
358
+ "description": "filter by freshness state",
334
359
  "name": "freshness",
335
360
  "hasDynamicHelp": false,
336
361
  "multiple": false,
@@ -342,30 +367,33 @@
342
367
  "type": "option"
343
368
  },
344
369
  "artifact-type": {
345
- "description": "Filter by artifact type.",
370
+ "description": "filter by artifact type",
346
371
  "name": "artifact-type",
347
372
  "hasDynamicHelp": false,
348
373
  "multiple": false,
349
374
  "options": [
350
375
  "source",
351
- "research_note"
376
+ "research_note",
377
+ "index"
352
378
  ],
353
379
  "type": "option"
354
380
  },
355
381
  "capture-method": {
356
- "description": "Filter by capture method.",
382
+ "description": "filter by capture method",
357
383
  "name": "capture-method",
358
384
  "hasDynamicHelp": false,
359
385
  "multiple": false,
360
386
  "options": [
361
387
  "static_fetch",
362
388
  "browser_fallback",
363
- "agent_supplied"
389
+ "agent_supplied",
390
+ "route_markdown",
391
+ "github_source"
364
392
  ],
365
393
  "type": "option"
366
394
  },
367
395
  "limit": {
368
- "description": "Maximum number of results to return (default 50, max 100).",
396
+ "description": "maximum number of results to return (default 50, max 100)",
369
397
  "name": "limit",
370
398
  "default": 50,
371
399
  "hasDynamicHelp": false,
@@ -390,12 +418,16 @@
390
418
  "description": "Prunes cached research entries based on age, inactivity, or artifact type to free up disk space.",
391
419
  "examples": [
392
420
  {
393
- "description": "Perform a dry run of pruning entries older than 90 days",
421
+ "description": "perform a dry run of pruning entries older than 90 days",
394
422
  "command": "<%= config.bin %> prune --older-than 90d --dry-run"
395
423
  },
396
424
  {
397
- "description": "Actually prune entries older than 30 days that are source scrapes",
425
+ "description": "actually prune entries older than 30 days that are source scrapes",
398
426
  "command": "<%= config.bin %> prune --older-than 30d --artifact-type source --yes"
427
+ },
428
+ {
429
+ "description": "prune entries matching a URL glob pattern",
430
+ "command": "<%= config.bin %> prune --url \"https://react.dev/*\" --yes"
399
431
  }
400
432
  ],
401
433
  "flags": {
@@ -407,39 +439,48 @@
407
439
  "type": "boolean"
408
440
  },
409
441
  "older-than": {
410
- "description": "Prune entries older than duration (e.g. \"30d\", \"90d\").",
442
+ "description": "prune entries older than duration (e.g. \"30d\", \"90d\")",
411
443
  "name": "older-than",
412
444
  "hasDynamicHelp": false,
413
445
  "multiple": false,
414
446
  "type": "option"
415
447
  },
416
448
  "inactive": {
417
- "description": "Prune entries inactive (unvalidated/unfetched) for duration (e.g. \"14d\", \"30d\").",
449
+ "description": "prune entries inactive (unvalidated/unfetched) for duration (e.g. \"14d\", \"30d\")",
418
450
  "name": "inactive",
419
451
  "hasDynamicHelp": false,
420
452
  "multiple": false,
421
453
  "type": "option"
422
454
  },
455
+ "url": {
456
+ "description": "filter pruning to source URL glob pattern (case-insensitive, supports * wildcard)",
457
+ "name": "url",
458
+ "hasDynamicHelp": false,
459
+ "multiple": false,
460
+ "type": "option"
461
+ },
423
462
  "artifact-type": {
424
- "description": "Filter pruning to specific artifact type.",
463
+ "description": "filter pruning to specific artifact type",
425
464
  "name": "artifact-type",
426
465
  "hasDynamicHelp": false,
427
466
  "multiple": false,
428
467
  "options": [
429
468
  "source",
430
- "research_note"
469
+ "research_note",
470
+ "index",
471
+ "section"
431
472
  ],
432
473
  "type": "option"
433
474
  },
434
475
  "dry-run": {
435
- "description": "List files that would be deleted without actually deleting them.",
476
+ "description": "list files that would be deleted without actually deleting them",
436
477
  "name": "dry-run",
437
478
  "allowNo": false,
438
479
  "type": "boolean"
439
480
  },
440
481
  "yes": {
441
482
  "char": "y",
442
- "description": "Skip confirmation prompt and prune files.",
483
+ "description": "confirm deletion and prune matched entries (required unless --dry-run)",
443
484
  "name": "yes",
444
485
  "allowNo": false,
445
486
  "type": "boolean"
@@ -456,16 +497,26 @@
456
497
  "enableJsonFlag": true,
457
498
  "stdoutIsPrimaryData": true
458
499
  },
459
- "search": {
500
+ "status": {
460
501
  "aliases": [],
461
502
  "args": {
462
- "query": {
463
- "description": "The search query containing terms to match.",
464
- "name": "query",
503
+ "url": {
504
+ "description": "the URL to check",
505
+ "name": "url",
465
506
  "required": true
466
507
  }
467
508
  },
468
- "description": "Scans the local research cache database and ranks matching entries based on topic, tags, source URLs, summary, and content.",
509
+ "description": "Reports whether the URL is cached, its freshness state, and what action (fetch, revalidate, or cached return) the root fetch command would take.",
510
+ "examples": [
511
+ {
512
+ "description": "check if a URL is already in the cache",
513
+ "command": "<%= config.bin %> <%= command.id %> https://example.com/docs"
514
+ },
515
+ {
516
+ "description": "check status against a specific freshness tier and TTL",
517
+ "command": "<%= config.bin %> <%= command.id %> https://example.com/docs --tier volatile --ttl 2h"
518
+ }
519
+ ],
469
520
  "flags": {
470
521
  "json": {
471
522
  "description": "Format output as json.",
@@ -474,59 +525,30 @@
474
525
  "allowNo": false,
475
526
  "type": "boolean"
476
527
  },
477
- "topic": {
478
- "char": "t",
479
- "description": "Filter results by exact topic (case-insensitive).",
480
- "name": "topic",
481
- "hasDynamicHelp": false,
482
- "multiple": false,
483
- "type": "option"
484
- },
485
- "tags": {
486
- "char": "g",
487
- "description": "Filter results by tags (must match all tags specified).",
488
- "name": "tags",
489
- "hasDynamicHelp": false,
490
- "multiple": true,
491
- "type": "option"
492
- },
493
- "artifact-type": {
494
- "description": "Filter results by artifact type.",
495
- "name": "artifact-type",
528
+ "tier": {
529
+ "description": "freshness tier policy to evaluate against",
530
+ "name": "tier",
531
+ "default": "standard",
496
532
  "hasDynamicHelp": false,
497
533
  "multiple": false,
498
534
  "options": [
499
- "source",
500
- "research_note",
501
- "index",
502
- "section"
535
+ "stable",
536
+ "standard",
537
+ "volatile"
503
538
  ],
504
539
  "type": "option"
505
540
  },
506
- "limit": {
507
- "description": "Maximum number of results to return (default 10, max 50).",
508
- "name": "limit",
509
- "default": 10,
510
- "hasDynamicHelp": false,
511
- "multiple": false,
512
- "type": "option"
513
- },
514
- "include-stale": {
515
- "description": "Include stale expired cache entries in the search results.",
516
- "name": "include-stale",
517
- "allowNo": false,
518
- "type": "boolean"
519
- },
520
- "domain": {
521
- "description": "Search a documentation site directly (e.g. help.salesforce.com) instead of the local cache. Requires a site module that implements search.",
522
- "name": "domain",
541
+ "ttl": {
542
+ "char": "l",
543
+ "description": "custom TTL duration to evaluate against (e.g. \"2h\", \"7d\")",
544
+ "name": "ttl",
523
545
  "hasDynamicHelp": false,
524
546
  "multiple": false,
525
547
  "type": "option"
526
548
  },
527
- "remote": {
528
- "description": "Discover uncached docs via a site’s public search or index (Algolia DocSearch, MkDocs/Sphinx/Just-the-Docs, llms.txt, sitemap.xml). Pass a docs page URL; falls back to local cache search if no connector applies.",
529
- "name": "remote",
549
+ "max-age": {
550
+ "description": "maximum age of cache to accept (e.g. \"1d\", \"30d\")",
551
+ "name": "max-age",
530
552
  "hasDynamicHelp": false,
531
553
  "multiple": false,
532
554
  "type": "option"
@@ -534,25 +556,29 @@
534
556
  },
535
557
  "hasDynamicHelp": false,
536
558
  "hiddenAliases": [],
537
- "id": "search",
559
+ "id": "status",
538
560
  "pluginAlias": "@taurgis/bonsai",
539
561
  "pluginName": "@taurgis/bonsai",
540
562
  "pluginType": "core",
541
- "strict": true,
542
- "summary": "Search locally cached research artifacts by keywords.",
563
+ "strict": false,
564
+ "summary": "Check the cache status of a URL without fetching or writing.",
543
565
  "enableJsonFlag": true,
544
566
  "stdoutIsPrimaryData": true
545
567
  },
546
- "status": {
568
+ "config": {
547
569
  "aliases": [],
548
- "args": {
549
- "url": {
550
- "description": "The URL to check.",
551
- "name": "url",
552
- "required": true
570
+ "args": {},
571
+ "description": "Show config subcommands for reading and writing Bonsai research cache configuration.",
572
+ "examples": [
573
+ {
574
+ "description": "get a configuration value",
575
+ "command": "<%= config.bin %> <%= command.id %> get storage"
576
+ },
577
+ {
578
+ "description": "set a configuration value for the current project",
579
+ "command": "<%= config.bin %> <%= command.id %> set storage project --local"
553
580
  }
554
- },
555
- "description": "Reports whether the URL is cached, its freshness state, and what action (fetch, revalidate, or cached return) the root fetch command would take.",
581
+ ],
556
582
  "flags": {
557
583
  "json": {
558
584
  "description": "Format output as json.",
@@ -560,44 +586,16 @@
560
586
  "name": "json",
561
587
  "allowNo": false,
562
588
  "type": "boolean"
563
- },
564
- "tier": {
565
- "description": "Freshness tier policy to evaluate against.",
566
- "name": "tier",
567
- "default": "standard",
568
- "hasDynamicHelp": false,
569
- "multiple": false,
570
- "options": [
571
- "stable",
572
- "standard",
573
- "volatile"
574
- ],
575
- "type": "option"
576
- },
577
- "ttl": {
578
- "char": "l",
579
- "description": "Custom TTL duration to evaluate against (e.g. \"2h\", \"7d\").",
580
- "name": "ttl",
581
- "hasDynamicHelp": false,
582
- "multiple": false,
583
- "type": "option"
584
- },
585
- "max-age": {
586
- "description": "Maximum age of cache to accept (e.g. \"1d\", \"30d\").",
587
- "name": "max-age",
588
- "hasDynamicHelp": false,
589
- "multiple": false,
590
- "type": "option"
591
589
  }
592
590
  },
593
591
  "hasDynamicHelp": false,
594
592
  "hiddenAliases": [],
595
- "id": "status",
593
+ "id": "config",
596
594
  "pluginAlias": "@taurgis/bonsai",
597
595
  "pluginName": "@taurgis/bonsai",
598
596
  "pluginType": "core",
599
597
  "strict": true,
600
- "summary": "Check the cache status of a URL without fetching or writing.",
598
+ "summary": "Manage research cache storage configuration (global vs project).",
601
599
  "enableJsonFlag": true,
602
600
  "stdoutIsPrimaryData": true
603
601
  },
@@ -605,19 +603,19 @@
605
603
  "aliases": [],
606
604
  "args": {
607
605
  "key": {
608
- "description": "The configuration key to read.",
606
+ "description": "the configuration key to read",
609
607
  "name": "key",
610
- "required": true
608
+ "required": false
611
609
  }
612
610
  },
613
611
  "description": "Print a config value. Without --global/--local, shows the merged effective value (flag > env > project > user > default).\n\nValid keys: storage, summary.",
614
612
  "examples": [
615
613
  {
616
- "description": "Get the effective storage mode",
614
+ "description": "get the effective storage mode",
617
615
  "command": "<%= config.bin %> config get storage"
618
616
  },
619
617
  {
620
- "description": "Read only the project-level value",
618
+ "description": "read only the project-level value",
621
619
  "command": "<%= config.bin %> config get storage --local"
622
620
  }
623
621
  ],
@@ -665,11 +663,11 @@
665
663
  "description": "Show every configuration key with its current value. Use --global/--local to show a single scope.\n\nValid keys: storage, summary.",
666
664
  "examples": [
667
665
  {
668
- "description": "Show all effective config values",
666
+ "description": "show all effective config values",
669
667
  "command": "<%= config.bin %> config list"
670
668
  },
671
669
  {
672
- "description": "Show only project-level config",
670
+ "description": "show only project-level config",
673
671
  "command": "<%= config.bin %> config list --local"
674
672
  }
675
673
  ],
@@ -715,12 +713,12 @@
715
713
  "aliases": [],
716
714
  "args": {
717
715
  "key": {
718
- "description": "The configuration key to set.",
716
+ "description": "the configuration key to set",
719
717
  "name": "key",
720
718
  "required": false
721
719
  },
722
720
  "value": {
723
- "description": "The value to assign.",
721
+ "description": "the value to assign",
724
722
  "name": "value",
725
723
  "required": false
726
724
  }
@@ -728,11 +726,11 @@
728
726
  "description": "Persist a configuration value. Writes user-level config by default; pass --local to write the project-level config (.bonsai.json in cwd).\n\nValid keys: storage, summary. The inline form `<key>=<value>` is also accepted.",
729
727
  "examples": [
730
728
  {
731
- "description": "Store research cache inside the current project",
729
+ "description": "store research cache inside the current project",
732
730
  "command": "<%= config.bin %> config set storage project --local"
733
731
  },
734
732
  {
735
- "description": "Set the user-level default using the inline key=value form",
733
+ "description": "set the user-level default using the inline key=value form",
736
734
  "command": "<%= config.bin %> config set storage=global"
737
735
  }
738
736
  ],
@@ -764,7 +762,7 @@
764
762
  "type": "boolean"
765
763
  },
766
764
  "dry-run": {
767
- "description": "Show what would be written without saving.",
765
+ "description": "show what would be written without saving",
768
766
  "name": "dry-run",
769
767
  "allowNo": false,
770
768
  "type": "boolean"
@@ -784,19 +782,19 @@
784
782
  "aliases": [],
785
783
  "args": {
786
784
  "key": {
787
- "description": "The configuration key to remove.",
785
+ "description": "the configuration key to remove",
788
786
  "name": "key",
789
- "required": true
787
+ "required": false
790
788
  }
791
789
  },
792
790
  "description": "Delete a key from user-level config (default) or project-level config (--local), restoring the built-in default.\n\nValid keys: storage, summary.",
793
791
  "examples": [
794
792
  {
795
- "description": "Remove the user-level storage setting",
793
+ "description": "remove the user-level storage setting",
796
794
  "command": "<%= config.bin %> config unset storage"
797
795
  },
798
796
  {
799
- "description": "Remove the project-level storage setting",
797
+ "description": "remove the project-level storage setting",
800
798
  "command": "<%= config.bin %> config unset storage --local"
801
799
  }
802
800
  ],
@@ -828,7 +826,7 @@
828
826
  "type": "boolean"
829
827
  },
830
828
  "dry-run": {
831
- "description": "Show what would be removed without saving.",
829
+ "description": "show what would be removed without saving",
832
830
  "name": "dry-run",
833
831
  "allowNo": false,
834
832
  "type": "boolean"
@@ -845,5 +843,5 @@
845
843
  "stdoutIsPrimaryData": true
846
844
  }
847
845
  },
848
- "version": "1.0.5"
846
+ "version": "3.0.0"
849
847
  }