bluera-knowledge 0.35.0 → 0.36.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.
package/hooks/hooks.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "description": "bluera-knowledge plugin hooks - auto-setup, readiness checks, job monitoring, and BK suggestions",
2
+ "description": "bluera-knowledge plugin hooks - auto-setup, readiness checks, job monitoring, activation nudges, and BK suggestions",
3
3
  "hooks": {
4
4
  "SessionStart": [
5
5
  {
@@ -72,6 +72,22 @@
72
72
  "command": "${CLAUDE_PLUGIN_ROOT:-.}/hooks/job-status-hook.sh",
73
73
  "timeout": 2,
74
74
  "async": true
75
+ },
76
+ {
77
+ "type": "command",
78
+ "command": "python3 ${CLAUDE_PLUGIN_ROOT:-.}/hooks/userpromptsubmit-bk-nudge.py",
79
+ "timeout": 2
80
+ }
81
+ ]
82
+ }
83
+ ],
84
+ "Stop": [
85
+ {
86
+ "hooks": [
87
+ {
88
+ "type": "command",
89
+ "command": "python3 ${CLAUDE_PLUGIN_ROOT:-.}/hooks/stop-bk-check.py",
90
+ "timeout": 2
75
91
  }
76
92
  ]
77
93
  }
@@ -0,0 +1,86 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Stop hook for bluera-knowledge plugin.
4
+
5
+ Fires when Claude is about to stop responding. If the conversation
6
+ involved dependency-related work but BK was never consulted, blocks
7
+ once to suggest checking BK.
8
+
9
+ Uses stop_hook_active for loop protection — only blocks the first time.
10
+ """
11
+
12
+ import json
13
+ import sys
14
+
15
+
16
+ def main() -> None:
17
+ try:
18
+ stdin_data = sys.stdin.read()
19
+ if not stdin_data.strip():
20
+ return
21
+
22
+ data = json.loads(stdin_data)
23
+
24
+ # Loop protection: if stop hook already fired, allow stop
25
+ stop_hook_active = data.get("stop_hook_active", False)
26
+ if stop_hook_active:
27
+ return
28
+
29
+ # Check if BK tools were used in this conversation
30
+ # The tool_uses field contains tools used so far in the session
31
+ tool_uses = data.get("tool_uses", [])
32
+
33
+ bk_was_used = False
34
+ has_dependency_context = False
35
+
36
+ for tool_use in tool_uses:
37
+ tool_name = ""
38
+ if isinstance(tool_use, dict):
39
+ tool_name = tool_use.get("tool_name", tool_use.get("name", ""))
40
+ elif isinstance(tool_use, str):
41
+ tool_name = tool_use
42
+
43
+ # Check if BK search was used
44
+ if "bluera-knowledge" in tool_name and (
45
+ "search" in tool_name or "get_full_context" in tool_name
46
+ ):
47
+ bk_was_used = True
48
+ break
49
+
50
+ # Check if dependency dirs were accessed (Read/Grep in node_modules etc.)
51
+ tool_input = (
52
+ tool_use.get("tool_input", {}) if isinstance(tool_use, dict) else {}
53
+ )
54
+ path = tool_input.get("path", tool_input.get("file_path", ""))
55
+ if isinstance(path, str):
56
+ dep_markers = (
57
+ "/node_modules/",
58
+ "/vendor/",
59
+ "/site-packages/",
60
+ "/.venv/",
61
+ )
62
+ if any(marker in path for marker in dep_markers):
63
+ has_dependency_context = True
64
+
65
+ # If BK was used or no dependency context detected, allow stop
66
+ if bk_was_used or not has_dependency_context:
67
+ return
68
+
69
+ # Block stop once — suggest checking BK
70
+ output = {
71
+ "decision": "block",
72
+ "reason": (
73
+ "You accessed dependency directories but haven't consulted Bluera Knowledge. "
74
+ "Consider using mcp__bluera-knowledge__search to verify your answer "
75
+ "against authoritative source code before completing."
76
+ ),
77
+ }
78
+ print(json.dumps(output))
79
+
80
+ except Exception:
81
+ # Hooks must never crash — silent failure allows stop
82
+ pass
83
+
84
+
85
+ if __name__ == "__main__":
86
+ main()
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ UserPromptSubmit hook for bluera-knowledge plugin.
4
+
5
+ Detects dependency-related prompts and injects a gentle BK reminder
6
+ into context, reinforcing the directive skill description.
7
+
8
+ Fires when:
9
+ - Prompt mentions dependency errors (Cannot find module, ModuleNotFoundError, etc.)
10
+ - Prompt involves planning/implementing with external packages
11
+ - Prompt mentions debugging + library/package keywords
12
+ - Prompt contains import/require statements with package names
13
+
14
+ Does NOT fire when:
15
+ - Prompt already mentions bluera-knowledge, /search, or mcp__bluera-knowledge
16
+ - No dependency-related content detected
17
+ """
18
+
19
+ import json
20
+ import re
21
+ import sys
22
+
23
+
24
+ # Patterns that indicate dependency-related work
25
+ DEPENDENCY_ERROR_PATTERNS = [
26
+ r"cannot find module",
27
+ r"module not found",
28
+ r"modulenotfounderror",
29
+ r"importerror",
30
+ r"no module named",
31
+ r"package .+ not found",
32
+ r"could not resolve",
33
+ r"cannot resolve",
34
+ r"peer dep",
35
+ r"unresolved import",
36
+ ]
37
+
38
+ LIBRARY_KEYWORDS = [
39
+ r"\b(?:dependency|dependencies|package|library|framework|sdk|api)\b",
40
+ r"\b(?:npm|pip|cargo|gem|maven|gradle|composer|nuget)\b",
41
+ r"\b(?:node_modules|vendor|site-packages|\.venv)\b",
42
+ r"\b(?:import|require|from .+ import)\b.*\b(?:express|react|vue|angular|fastapi|django|flask|hono|zod|pydantic|axios|lodash|prisma|drizzle|next|svelte|tailwind)\b",
43
+ ]
44
+
45
+ PLANNING_PATTERNS = [
46
+ r"\b(?:implement|integrate|set up|configure|use|add)\b.{1,40}\b(?:with|using)\b",
47
+ r"\bhow (?:does|do|to)\b.{1,30}\b(?:work|handle|process)\b",
48
+ r"\bwhat (?:is|are|does)\b.{1,30}\b(?:api|method|function|class|option|parameter)\b",
49
+ ]
50
+
51
+ DEBUG_PATTERNS = [
52
+ r"\b(?:error|bug|issue|crash|fail|broken|stuck|debug)\b.{1,60}\b(?:package|library|dependency|module|import)\b",
53
+ r"\b(?:package|library|dependency|module|import)\b.{1,60}\b(?:error|bug|issue|crash|fail|broken|stuck|debug)\b",
54
+ ]
55
+
56
+ # Patterns indicating the user is already using BK
57
+ ALREADY_USING_BK = [
58
+ r"bluera.knowledge",
59
+ r"/search",
60
+ r"/bluera-knowledge",
61
+ r"mcp__bluera.knowledge",
62
+ r"mcp__.*bluera.*knowledge",
63
+ ]
64
+
65
+
66
+ def prompt_involves_dependencies(prompt: str) -> bool:
67
+ """Check if the prompt involves dependency/library work."""
68
+ lower = prompt.lower()
69
+
70
+ for pattern in DEPENDENCY_ERROR_PATTERNS:
71
+ if re.search(pattern, lower):
72
+ return True
73
+
74
+ for pattern in LIBRARY_KEYWORDS:
75
+ if re.search(pattern, lower, re.IGNORECASE):
76
+ return True
77
+
78
+ for pattern in PLANNING_PATTERNS:
79
+ if re.search(pattern, lower, re.IGNORECASE):
80
+ return True
81
+
82
+ for pattern in DEBUG_PATTERNS:
83
+ if re.search(pattern, lower, re.IGNORECASE):
84
+ return True
85
+
86
+ return False
87
+
88
+
89
+ def already_using_bk(prompt: str) -> bool:
90
+ """Check if the prompt already references BK."""
91
+ lower = prompt.lower()
92
+ for pattern in ALREADY_USING_BK:
93
+ if re.search(pattern, lower):
94
+ return True
95
+ return False
96
+
97
+
98
+ def main() -> None:
99
+ try:
100
+ stdin_data = sys.stdin.read()
101
+ if not stdin_data.strip():
102
+ return
103
+
104
+ data = json.loads(stdin_data)
105
+ prompt = data.get("prompt", "")
106
+
107
+ if not prompt:
108
+ return
109
+
110
+ # Don't fire if user is already using BK
111
+ if already_using_bk(prompt):
112
+ return
113
+
114
+ # Don't fire if prompt doesn't involve dependencies
115
+ if not prompt_involves_dependencies(prompt):
116
+ return
117
+
118
+ output = {
119
+ "hookSpecificOutput": {
120
+ "hookEventName": "UserPromptSubmit",
121
+ "additionalContext": (
122
+ "You have indexed library sources available via Bluera Knowledge. "
123
+ "Use mcp__bluera-knowledge__search to look up library APIs, "
124
+ "implementation details, and usage patterns before relying on training data."
125
+ ),
126
+ }
127
+ }
128
+ print(json.dumps(output))
129
+
130
+ except Exception:
131
+ # Hooks must never crash — silent failure is safer than blocking
132
+ pass
133
+
134
+
135
+ if __name__ == "__main__":
136
+ main()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bluera-knowledge",
3
- "version": "0.35.0",
3
+ "version": "0.36.0",
4
4
  "description": "CLI tool for managing knowledge stores with semantic search",
5
5
  "type": "module",
6
6
  "bin": {
@@ -30,11 +30,18 @@ log_debug() {
30
30
 
31
31
  log_debug "Auto-setup starting, PLUGIN_ROOT=$PLUGIN_ROOT"
32
32
 
33
- # Fast exit if already set up
33
+ # Fast exit if already set up AND version hasn't changed
34
34
  WRAPPER_PATH="$HOME/.local/bin/bluera-knowledge-mcp"
35
+ VERSION_FILE="$PLUGIN_ROOT/.installed-version"
36
+ CURRENT_VERSION=$(cat "$PLUGIN_ROOT/package.json" 2>/dev/null | grep '"version"' | head -1 | sed 's/.*"\([0-9][0-9.]*\)".*/\1/')
37
+ INSTALLED_VERSION=$(cat "$VERSION_FILE" 2>/dev/null || echo "none")
38
+
35
39
  if [ -d "$PLUGIN_ROOT/node_modules" ] && [ -f "$WRAPPER_PATH" ]; then
36
- log_debug "Already set up (node_modules and wrapper exist), exiting"
37
- exit 0
40
+ if [ "$CURRENT_VERSION" = "$INSTALLED_VERSION" ]; then
41
+ log_debug "Already set up (v$INSTALLED_VERSION), exiting"
42
+ exit 0
43
+ fi
44
+ log_debug "Version changed ($INSTALLED_VERSION -> $CURRENT_VERSION), re-running setup"
38
45
  fi
39
46
 
40
47
  log_debug "Setup needed - node_modules: $([ -d "$PLUGIN_ROOT/node_modules" ] && echo 'exists' || echo 'missing'), wrapper: $([ -f "$WRAPPER_PATH" ] && echo 'exists' || echo 'missing')"
@@ -60,6 +67,7 @@ echo -e "${YELLOW}[bluera-knowledge] Running first-time setup (this may take a m
60
67
  export NONINTERACTIVE=1
61
68
  if "$PLUGIN_ROOT/scripts/setup.sh"; then
62
69
  log_debug "Setup completed successfully"
70
+ echo "$CURRENT_VERSION" > "$VERSION_FILE" 2>/dev/null || true
63
71
  echo -e "${GREEN}[bluera-knowledge] Setup complete ✓${NC}"
64
72
  echo -e "${GREEN}[bluera-knowledge] Restart Claude Code to enable MCP server.${NC}"
65
73
  else
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: knowledge-search
3
- description: Use when the user asks about libraries, frameworks, dependencies, API references, implementation details, or needs code examples from third-party packages. Activates for library API questions, dependency errors, framework configuration, or code generation involving external packages.
3
+ description: Library and dependency expert. ALWAYS invoke this skill when working with third-party libraries, frameworks, or dependencies including debugging dependency errors, planning code that uses external packages, checking API signatures, or understanding library internals. Do not grep node_modules, vendor directories, or rely on training data for library questions directly — use this skill first.
4
4
  ---
5
5
 
6
6
  # Using Bluera Knowledge (BK)
@@ -28,16 +28,23 @@ Analyze project dependencies and suggest important libraries to add to knowledge
28
28
  - Count imports/requires for each dependency
29
29
  - Rank dependencies by frequency of use
30
30
 
31
- 4. **Get existing stores** using mcp__bluera-knowledge__execute with command "stores":
31
+ 4. **Select the IMPORTANT dependencies** not all of them. Apply these criteria:
32
+ - Prioritize core frameworks and libraries the project builds ON (e.g., React, Express, FastAPI)
33
+ - Include libraries with complex APIs where understanding internals helps (e.g., Prisma, Drizzle, Zod)
34
+ - Include deps likely to cause debugging issues or have non-obvious behavior
35
+ - **Skip**: test runners (jest, vitest, pytest), linters (eslint, ruff), formatters (prettier, black), build tools (webpack, vite, esbuild), @types packages, trivial utilities
36
+ - Aim for 5-10 most impactful dependencies, not every dependency
37
+
38
+ 5. **Get existing stores** using mcp__bluera-knowledge__execute with command "stores":
32
39
  - Filter out dependencies already in stores
33
40
  - Focus on new suggestions
34
41
 
35
- 5. **Find repository URLs** using WebSearch:
36
- - For top 5 most-used dependencies
42
+ 6. **Find repository URLs** using WebSearch:
43
+ - For the selected important dependencies
37
44
  - Search for official GitHub/GitLab repositories
38
45
  - Prefer official repos over forks
39
46
 
40
- 6. **Present selectable list** using AskUserQuestion:
47
+ 7. **Present selectable list** using AskUserQuestion:
41
48
 
42
49
  First, show a summary of what was found:
43
50
  ```
@@ -79,7 +86,7 @@ Then use AskUserQuestion with multiSelect to let the user choose which to add:
79
86
 
80
87
  **Note:** Maximum 4 options per question (AskUserQuestion limit). If more than 4 dependencies, show top 4 and mention others in summary.
81
88
 
82
- 7. **Execute selected add-repo commands**:
89
+ 8. **Execute selected add-repo commands**:
83
90
 
84
91
  For each selected dependency, invoke the Skill tool:
85
92
  ```
@@ -91,7 +98,7 @@ Example for react selection:
91
98
  Skill(skill="bluera-knowledge:add-repo", args="https://github.com/facebook/react --name=react")
92
99
  ```
93
100
 
94
- 8. **Show completion summary**:
101
+ 9. **Show completion summary**:
95
102
  ```
96
103
  ## Added to Knowledge Stores
97
104