bluera-knowledge 0.13.2 → 0.14.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.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "bluera-knowledge",
3
- "version": "0.13.2",
3
+ "version": "0.14.0",
4
4
  "description": "Clone repos, crawl docs, search locally. Fast, authoritative answers for AI coding agents."
5
5
  }
package/CHANGELOG.md CHANGED
@@ -2,6 +2,20 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [0.14.0](https://github.com/blueraai/bluera-knowledge/compare/v0.13.3...v0.14.0) (2026-01-16)
6
+
7
+
8
+ ### Features
9
+
10
+ * add uninstall command and use venv for Python dependencies ([e632618](https://github.com/blueraai/bluera-knowledge/commit/e632618cc1b0925dbdc90a2eabb0863ae3e939fa))
11
+
12
+ ## [0.13.3](https://github.com/blueraai/bluera-knowledge/compare/v0.13.2...v0.13.3) (2026-01-16)
13
+
14
+
15
+ ### Bug Fixes
16
+
17
+ * **crawl:** use absolute path for Python worker in PythonBridge ([f9a45cd](https://github.com/blueraai/bluera-knowledge/commit/f9a45cdcdcee3be1090843fcb17ed3251b5c5a4a))
18
+
5
19
  ## [0.13.2](https://github.com/blueraai/bluera-knowledge/compare/v0.13.1...v0.13.2) (2026-01-16)
6
20
 
7
21
 
@@ -0,0 +1,65 @@
1
+ ---
2
+ description: Remove Bluera Knowledge data from this project
3
+ allowed-tools: ["mcp__bluera-knowledge__execute"]
4
+ ---
5
+
6
+ # Uninstall Bluera Knowledge
7
+
8
+ Remove Bluera Knowledge data from this project.
9
+
10
+ ## Steps
11
+
12
+ 1. Use mcp__bluera-knowledge__execute tool with command "uninstall":
13
+ - Optional args.global: true to also remove global data
14
+ - Optional args.keepDefinitions: false to also remove stores.config.json
15
+
16
+ 2. Display the result showing what was deleted and cleanup instructions.
17
+
18
+ ## Options
19
+
20
+ | Flag | Description |
21
+ |------|-------------|
22
+ | `global` | Also delete global data (~/.local/share/bluera-knowledge/) |
23
+ | `keepDefinitions` | Keep stores.config.json for team sharing (default: true) |
24
+
25
+ ## Examples
26
+
27
+ **Clean project data (preserves stores.config.json):**
28
+ ```
29
+ /bluera-knowledge:uninstall
30
+ ```
31
+
32
+ **Full cleanup including store definitions:**
33
+ ```
34
+ Use uninstall with keepDefinitions: false
35
+ ```
36
+
37
+ **Full cleanup including global data:**
38
+ ```
39
+ Use uninstall with global: true
40
+ ```
41
+
42
+ ## What Gets Deleted
43
+
44
+ **Project data** (`.bluera/bluera-knowledge/`):
45
+ - `data/` - Vector indices, cloned repos, stores.json
46
+ - `config.json` - Plugin configuration
47
+ - `stores.config.json` - Only if keepDefinitions: false
48
+
49
+ **Global data** (with --global flag):
50
+ - `~/.local/share/bluera-knowledge/` - Job history, skill settings
51
+
52
+ ## What Is NOT Deleted
53
+
54
+ - **Plugin cache** - Managed by Claude Code, instructions provided
55
+ - **Python venv** - Inside plugin cache, cleaned when cache is cleared
56
+
57
+ ## Testing Fresh Plugin Installs
58
+
59
+ After running uninstall, to test a completely fresh plugin install:
60
+
61
+ 1. Exit Claude Code
62
+ 2. Clear plugin cache: `rm -rf ~/.claude/plugins/cache/bluera-knowledge-*`
63
+ 3. Restart Claude Code and reinstall the plugin
64
+
65
+ _Clearing the plugin cache removes everything: plugin code, Python venv, and all dependencies._
@@ -3,7 +3,7 @@ import {
3
3
  createLogger,
4
4
  summarizePayload,
5
5
  truncateForLog
6
- } from "./chunk-6ZVW2P2F.js";
6
+ } from "./chunk-Y24ZJRZP.js";
7
7
 
8
8
  // src/crawl/intelligent-crawler.ts
9
9
  import { EventEmitter } from "events";
@@ -753,4 +753,4 @@ var IntelligentCrawler = class extends EventEmitter {
753
753
  export {
754
754
  IntelligentCrawler
755
755
  };
756
- //# sourceMappingURL=chunk-GCUKVV33.js.map
756
+ //# sourceMappingURL=chunk-AIS5S77C.js.map
@@ -7,7 +7,7 @@ import {
7
7
  createStoreId,
8
8
  destroyServices,
9
9
  summarizePayload
10
- } from "./chunk-6ZVW2P2F.js";
10
+ } from "./chunk-Y24ZJRZP.js";
11
11
 
12
12
  // src/mcp/server.ts
13
13
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";
@@ -1626,11 +1626,130 @@ var syncCommands = [
1626
1626
  }
1627
1627
  ];
1628
1628
 
1629
+ // src/mcp/commands/uninstall.commands.ts
1630
+ import { z as z8 } from "zod";
1631
+
1632
+ // src/mcp/handlers/uninstall.handler.ts
1633
+ import { existsSync } from "fs";
1634
+ import { readdir, rm as rm2 } from "fs/promises";
1635
+ import { homedir } from "os";
1636
+ import { join as join3 } from "path";
1637
+ var logger2 = createLogger("uninstall-handler");
1638
+ var handleUninstall = async (args, context) => {
1639
+ const { global: includeGlobal = false, keepDefinitions = true } = args;
1640
+ const deleted = [];
1641
+ const kept = [];
1642
+ const errors = [];
1643
+ const projectRoot = context.options.projectRoot ?? process.cwd();
1644
+ const projectDataDir = join3(projectRoot, ".bluera", "bluera-knowledge");
1645
+ logger2.info({ projectDataDir, includeGlobal, keepDefinitions }, "Starting uninstall");
1646
+ if (existsSync(projectDataDir)) {
1647
+ if (keepDefinitions) {
1648
+ try {
1649
+ const entries = await readdir(projectDataDir, { withFileTypes: true });
1650
+ for (const entry of entries) {
1651
+ const entryPath = join3(projectDataDir, entry.name);
1652
+ if (entry.name === "stores.config.json") {
1653
+ kept.push(entryPath);
1654
+ continue;
1655
+ }
1656
+ try {
1657
+ await rm2(entryPath, { recursive: true, force: true });
1658
+ deleted.push(entryPath);
1659
+ } catch (err) {
1660
+ const msg = err instanceof Error ? err.message : String(err);
1661
+ errors.push(`Failed to delete ${entryPath}: ${msg}`);
1662
+ logger2.error({ error: msg, path: entryPath }, "Failed to delete");
1663
+ }
1664
+ }
1665
+ } catch (err) {
1666
+ const msg = err instanceof Error ? err.message : String(err);
1667
+ errors.push(`Failed to read ${projectDataDir}: ${msg}`);
1668
+ logger2.error({ error: msg, path: projectDataDir }, "Failed to read directory");
1669
+ }
1670
+ } else {
1671
+ try {
1672
+ await rm2(projectDataDir, { recursive: true, force: true });
1673
+ deleted.push(projectDataDir);
1674
+ } catch (err) {
1675
+ const msg = err instanceof Error ? err.message : String(err);
1676
+ errors.push(`Failed to delete ${projectDataDir}: ${msg}`);
1677
+ logger2.error({ error: msg, path: projectDataDir }, "Failed to delete");
1678
+ }
1679
+ }
1680
+ }
1681
+ if (includeGlobal) {
1682
+ const globalDir = join3(homedir(), ".local", "share", "bluera-knowledge");
1683
+ if (existsSync(globalDir)) {
1684
+ try {
1685
+ await rm2(globalDir, { recursive: true, force: true });
1686
+ deleted.push(globalDir);
1687
+ } catch (err) {
1688
+ const msg = err instanceof Error ? err.message : String(err);
1689
+ errors.push(`Failed to delete ${globalDir}: ${msg}`);
1690
+ logger2.error({ error: msg, path: globalDir }, "Failed to delete global data");
1691
+ }
1692
+ }
1693
+ }
1694
+ logger2.info({ deleted, kept, errors }, "Uninstall complete");
1695
+ const lines = [];
1696
+ if (deleted.length > 0) {
1697
+ lines.push("## Deleted:");
1698
+ for (const path2 of deleted) {
1699
+ lines.push(`- ${path2}`);
1700
+ }
1701
+ } else {
1702
+ lines.push("No data found to delete.");
1703
+ }
1704
+ if (kept.length > 0) {
1705
+ lines.push("");
1706
+ lines.push("## Preserved:");
1707
+ for (const path2 of kept) {
1708
+ lines.push(`- ${path2}`);
1709
+ }
1710
+ lines.push("");
1711
+ lines.push("_Use `keepDefinitions: false` to also remove stores.config.json_");
1712
+ }
1713
+ if (errors.length > 0) {
1714
+ lines.push("");
1715
+ lines.push("## Errors:");
1716
+ for (const error of errors) {
1717
+ lines.push(`- ${error}`);
1718
+ }
1719
+ }
1720
+ lines.push("");
1721
+ lines.push("---");
1722
+ lines.push("");
1723
+ lines.push("## To fully uninstall (clear plugin cache):");
1724
+ lines.push("1. Exit Claude Code");
1725
+ lines.push("2. Run: `rm -rf ~/.claude/plugins/cache/bluera-knowledge-*`");
1726
+ lines.push("3. Restart Claude Code");
1727
+ lines.push("");
1728
+ lines.push("_This removes the plugin, Python venv, and all dependencies._");
1729
+ return {
1730
+ content: [{ type: "text", text: lines.join("\n") }]
1731
+ };
1732
+ };
1733
+
1734
+ // src/mcp/commands/uninstall.commands.ts
1735
+ var uninstallCommands = [
1736
+ {
1737
+ name: "uninstall",
1738
+ description: "Remove Bluera Knowledge data from project (and optionally global data)",
1739
+ argsSchema: z8.object({
1740
+ global: z8.boolean().optional().describe("Also remove global data (~/.local/share/bluera-knowledge)"),
1741
+ keepDefinitions: z8.boolean().optional().describe("Keep stores.config.json for team sharing (default: true)")
1742
+ }),
1743
+ handler: (args, context) => handleUninstall(args, context)
1744
+ }
1745
+ ];
1746
+
1629
1747
  // src/mcp/commands/index.ts
1630
1748
  commandRegistry.registerAll(storeCommands);
1631
1749
  commandRegistry.registerAll(jobCommands);
1632
1750
  commandRegistry.registerAll(metaCommands);
1633
1751
  commandRegistry.registerAll(syncCommands);
1752
+ commandRegistry.registerAll(uninstallCommands);
1634
1753
 
1635
1754
  // src/mcp/handlers/execute.handler.ts
1636
1755
  var handleExecute = async (args, context) => {
@@ -1734,11 +1853,11 @@ var LRUCache = class {
1734
1853
  };
1735
1854
 
1736
1855
  // src/mcp/handlers/search.handler.ts
1737
- var logger2 = createLogger("mcp-search");
1856
+ var logger3 = createLogger("mcp-search");
1738
1857
  var resultCache = new LRUCache(1e3);
1739
1858
  var handleSearch = async (args, context) => {
1740
1859
  const validated = SearchArgsSchema.parse(args);
1741
- logger2.info(
1860
+ logger3.info(
1742
1861
  {
1743
1862
  query: validated.query,
1744
1863
  stores: validated.stores,
@@ -1815,7 +1934,7 @@ var handleSearch = async (args, context) => {
1815
1934
  const header = `Search: "${validated.query}" | Results: ${String(results.totalResults)} | ${formatTokenCount(responseTokens)} tokens | ${String(results.timeMs)}ms${confidenceInfo}
1816
1935
 
1817
1936
  `;
1818
- logger2.info(
1937
+ logger3.info(
1819
1938
  {
1820
1939
  query: validated.query,
1821
1940
  totalResults: results.totalResults,
@@ -1836,7 +1955,7 @@ var handleSearch = async (args, context) => {
1836
1955
  };
1837
1956
  var handleGetFullContext = async (args, context) => {
1838
1957
  const validated = GetFullContextArgsSchema.parse(args);
1839
- logger2.info({ resultId: validated.resultId }, "Get full context requested");
1958
+ logger3.info({ resultId: validated.resultId }, "Get full context requested");
1840
1959
  const resultId = validated.resultId;
1841
1960
  const cachedResult = resultCache.get(resultId);
1842
1961
  if (!cachedResult) {
@@ -1854,7 +1973,7 @@ var handleGetFullContext = async (args, context) => {
1854
1973
  null,
1855
1974
  2
1856
1975
  );
1857
- logger2.info(
1976
+ logger3.info(
1858
1977
  {
1859
1978
  resultId,
1860
1979
  cached: true,
@@ -1920,7 +2039,7 @@ var handleGetFullContext = async (args, context) => {
1920
2039
  null,
1921
2040
  2
1922
2041
  );
1923
- logger2.info(
2042
+ logger3.info(
1924
2043
  {
1925
2044
  resultId,
1926
2045
  cached: false,
@@ -1956,7 +2075,7 @@ var tools = [
1956
2075
  ];
1957
2076
 
1958
2077
  // src/mcp/server.ts
1959
- var logger3 = createLogger("mcp-server");
2078
+ var logger4 = createLogger("mcp-server");
1960
2079
  var registry = AdapterRegistry.getInstance();
1961
2080
  if (!registry.hasExtension(".zil")) {
1962
2081
  registry.register(new ZilAdapter());
@@ -2072,7 +2191,7 @@ function createMCPServer(options) {
2072
2191
  server.setRequestHandler(CallToolRequestSchema, async (request) => {
2073
2192
  const { name, arguments: args } = request.params;
2074
2193
  const startTime = Date.now();
2075
- logger3.info({ tool: name, args: JSON.stringify(args) }, "Tool invoked");
2194
+ logger4.info({ tool: name, args: JSON.stringify(args) }, "Tool invoked");
2076
2195
  const services = await createServices(options.config, options.dataDir, options.projectRoot);
2077
2196
  const context = { services, options };
2078
2197
  try {
@@ -2089,11 +2208,11 @@ function createMCPServer(options) {
2089
2208
  result = await tool.handler(validated, context);
2090
2209
  }
2091
2210
  const durationMs = Date.now() - startTime;
2092
- logger3.info({ tool: name, durationMs }, "Tool completed");
2211
+ logger4.info({ tool: name, durationMs }, "Tool completed");
2093
2212
  return result;
2094
2213
  } catch (error) {
2095
2214
  const durationMs = Date.now() - startTime;
2096
- logger3.error(
2215
+ logger4.error(
2097
2216
  {
2098
2217
  tool: name,
2099
2218
  durationMs,
@@ -2109,7 +2228,7 @@ function createMCPServer(options) {
2109
2228
  return server;
2110
2229
  }
2111
2230
  async function runMCPServer(options) {
2112
- logger3.info(
2231
+ logger4.info(
2113
2232
  {
2114
2233
  dataDir: options.dataDir,
2115
2234
  projectRoot: options.projectRoot
@@ -2119,7 +2238,7 @@ async function runMCPServer(options) {
2119
2238
  const server = createMCPServer(options);
2120
2239
  const transport = new StdioServerTransport();
2121
2240
  await server.connect(transport);
2122
- logger3.info("MCP server connected to stdio transport");
2241
+ logger4.info("MCP server connected to stdio transport");
2123
2242
  }
2124
2243
  var scriptPath = process.argv[1] ?? "";
2125
2244
  var isMCPServerEntry = scriptPath.endsWith("mcp/server.js") || scriptPath.endsWith("mcp/server");
@@ -2133,7 +2252,7 @@ if (isMCPServerEntry) {
2133
2252
  config: process.env["CONFIG_PATH"],
2134
2253
  projectRoot
2135
2254
  }).catch((error) => {
2136
- logger3.error(
2255
+ logger4.error(
2137
2256
  { error: error instanceof Error ? error.message : String(error) },
2138
2257
  "Failed to start MCP server"
2139
2258
  );
@@ -2151,4 +2270,4 @@ export {
2151
2270
  createMCPServer,
2152
2271
  runMCPServer
2153
2272
  };
2154
- //# sourceMappingURL=chunk-H5AKKHY7.js.map
2273
+ //# sourceMappingURL=chunk-UAWKTJWN.js.map