@taurgis/bonsai 1.0.2 → 1.0.3

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.
@@ -1,19 +1,31 @@
1
1
  ---
2
- description: 'Require the Official Docs Researcher subagent before technical repo changes.'
2
+ description: 'Verify current official docs before technical repo changes — inline via the web-research skill for minor research, via the Official Docs Researcher subagent for extensive research.'
3
3
  applyTo: '**'
4
4
  skills:
5
5
  - web-research
6
6
  metadata:
7
- version: '3.0.0'
7
+ version: '3.1.0'
8
8
  ---
9
9
 
10
10
  # Web Research Requirement
11
11
 
12
12
  ## Mandatory Pre-Step
13
13
 
14
- - Run the **Official Docs Researcher** subagent before creating, updating, refactoring, scaffolding, or deleting technical content.
15
- - Use its findings to apply current official documentation and references in the change.
16
- - The researcher keeps a freshness-tiered Bonsai cache (its data directory or project-local `.bonsai/research/`): it reuses fresh notes, cheaply revalidates stale ones, and re-fetches only on a miss. Re-running on a recent topic is cheap — invoke it rather than skipping research to "save" a fetch.
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 **Official 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
+ - 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.
28
+ - Re-running on a recent topic is cheap — research the topic rather than skipping it to "save" a fetch.
17
29
 
18
30
  ## When Not to Use
19
31
 
@@ -23,7 +35,8 @@ metadata:
23
35
 
24
36
  ## Examples
25
37
 
26
- - ✅ Before editing instructions, prompts, agents, skills, workflows, or docs.
27
- - ✅ Before auditing or refactoring source — reading source code does not replace checking current platform guidance.
38
+ - ✅ Confirming one platform's current flag or frontmatter field before a small edit → run the web-research skill inline.
39
+ - ✅ Comparing conventions across several platforms, or auditing/refactoring source broadly → delegate to the Official Docs Researcher subagent.
40
+ - ✅ Before editing instructions, prompts, agents, skills, workflows, or docs — reading source code does not replace checking current platform guidance.
28
41
  - ✅ Include official source URLs when the change references platform behavior or standards.
29
- - ❌ Don't modify technical content without running the subagent first, or treat cached/training knowledge as equivalent — official guidance evolves and must be verified per task.
42
+ - ❌ 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.
@@ -6,6 +6,9 @@ const ERROR_PAGE_PATTERNS = [
6
6
  /\bnot\s*found\b/i,
7
7
  /there\s*isn'?t\s*a\s*github\s*pages\s*site\s*here/i,
8
8
  /site\s*not\s*found/i,
9
+ // Client-rendered (SPA) failure shells that return HTTP 200 but render only an error notice.
10
+ /something\s+went\s+wrong/i,
11
+ /an?\s+error\s+occurred/i,
9
12
  ];
10
13
  /** True when short text reads like an error/soft-404 page rather than real content. */
11
14
  export function looksLikeErrorPage(text) {
@@ -7,6 +7,7 @@ import { evaluateFreshness, getPolicy } from './freshness.js';
7
7
  import { compressMarkdown } from './compress.js';
8
8
  import { estimateTokens } from './token-estimate.js';
9
9
  import { fetchRenderedHtml } from './browser.js';
10
+ import { looksLikeErrorPage } from './docs/validate.js';
10
11
  function buildMetadata(url, normalizedUrl, cacheKey, fetchResult, extraction, tier, ttl, currentTime, compressed) {
11
12
  const contentHash = createHash('sha256').update(extraction.detailedMarkdown).digest('hex');
12
13
  const staleAfterTime = new Date(currentTime);
@@ -51,10 +52,39 @@ function buildMetadata(url, normalizedUrl, cacheKey, fetchResult, extraction, ti
51
52
  section_heading_path: null,
52
53
  };
53
54
  }
55
+ // Builds a compact error marker instead of caching a full error page. Subsequent lookups serve this
56
+ // tiny marker (a handful of tokens) instead of re-fetching, and revalidation re-checks it when stale
57
+ // so a transient failure recovers into a real artifact.
58
+ function buildErrorArtifact(url, normalizedUrl, cacheKey, fetchResult, tier, ttl, currentTime, reason) {
59
+ const marker = `Error: ${url} could not be cached — ${reason}. ` +
60
+ 'The page returned an error, so its content was not stored; it will be re-fetched when this entry goes stale.';
61
+ const extraction = {
62
+ title: `Error: ${reason}`,
63
+ detailedMarkdown: marker,
64
+ confidence: 'low',
65
+ qualityNotes: [`error: ${reason}`],
66
+ };
67
+ const metadata = buildMetadata(url, normalizedUrl, cacheKey, fetchResult, extraction, tier, ttl, currentTime, marker);
68
+ metadata.extraction_status = 'failed';
69
+ metadata.extraction_confidence = null;
70
+ return {
71
+ metadata,
72
+ summary: extraction.title,
73
+ compressed: marker,
74
+ detailed: marker,
75
+ provenance: `Fetched from ${url} on ${currentTime.toISOString()} (error page; content not cached)`,
76
+ };
77
+ }
54
78
  /**
55
79
  * Helper to construct a ResearchArtifact from a fresh HTML fetch.
56
80
  */
57
81
  export function createArtifactFromFetch(url, normalizedUrl, cacheKey, fetchResult, extraction, tier, ttl, currentTime) {
82
+ // A managed platform / SPA can return HTTP 200 but render only a "not found" / "something went
83
+ // wrong" shell. Cache a compact marker for those instead of the full error markdown, so repeat
84
+ // lookups cost a few tokens and revalidation still re-checks the page when the entry goes stale.
85
+ if (looksLikeErrorPage(extraction.detailedMarkdown)) {
86
+ return buildErrorArtifact(url, normalizedUrl, cacheKey, fetchResult, tier, ttl, currentTime, 'page reported an error or was not found');
87
+ }
58
88
  const compressed = compressMarkdown(extraction.detailedMarkdown);
59
89
  const metadata = buildMetadata(url, normalizedUrl, cacheKey, fetchResult, extraction, tier, ttl, currentTime, compressed);
60
90
  return {
@@ -845,5 +845,5 @@
845
845
  "stdoutIsPrimaryData": true
846
846
  }
847
847
  },
848
- "version": "1.0.2"
848
+ "version": "1.0.3"
849
849
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@taurgis/bonsai",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "Bonsai is a standalone local research cache CLI for AI agents",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -26,6 +26,7 @@
26
26
  "regression:suite": "tsc -b && node testing/regression/run-suite.mjs",
27
27
  "regression:promote": "tsc -b && node testing/regression/run-suite.mjs --promote",
28
28
  "regression:check": "tsc -b && node testing/regression/run-suite.mjs --strict",
29
+ "nexus:sync": "npx forward-nexus update && npx forward-nexus sync",
29
30
  "test": "vitest",
30
31
  "test:coverage": "vitest run --coverage",
31
32
  "type-check": "tsc --noEmit"