bluera-knowledge 0.17.0 → 0.17.2

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/CHANGELOG.md CHANGED
@@ -2,6 +2,21 @@
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.17.2](https://github.com/blueraai/bluera-knowledge/compare/v0.17.0...v0.17.2) (2026-01-18)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * **config:** use per-repo paths instead of global directories ([d642fec](https://github.com/blueraai/bluera-knowledge/commit/d642fec3510ef546dd5dc94f91410a38e8aea0e4))
11
+ * **logging:** use per-repo log directory instead of global ([d30000d](https://github.com/blueraai/bluera-knowledge/commit/d30000dd01bb1e8ac810a6fc086543c1368e5449))
12
+
13
+ ## [0.17.1](https://github.com/blueraai/bluera-knowledge/compare/v0.17.0...v0.17.1) (2026-01-18)
14
+
15
+
16
+ ### Bug Fixes
17
+
18
+ * **config:** use per-repo paths instead of global directories ([d642fec](https://github.com/blueraai/bluera-knowledge/commit/d642fec3510ef546dd5dc94f91410a38e8aea0e4))
19
+
5
20
  ## [0.17.0](https://github.com/blueraai/bluera-knowledge/compare/v0.16.6...v0.17.0) (2026-01-18)
6
21
 
7
22
 
@@ -3,7 +3,7 @@ import {
3
3
  createLogger,
4
4
  summarizePayload,
5
5
  truncateForLog
6
- } from "./chunk-WYZQUKUD.js";
6
+ } from "./chunk-WMALVLFW.js";
7
7
 
8
8
  // src/crawl/intelligent-crawler.ts
9
9
  import { EventEmitter } from "events";
@@ -833,4 +833,4 @@ export {
833
833
  getCrawlStrategy,
834
834
  IntelligentCrawler
835
835
  };
836
- //# sourceMappingURL=chunk-OMC3RAZT.js.map
836
+ //# sourceMappingURL=chunk-PFHK5Q22.js.map
@@ -109,18 +109,94 @@ var AdapterRegistry = class _AdapterRegistry {
109
109
  };
110
110
 
111
111
  // src/logging/logger.ts
112
- import { mkdirSync, existsSync } from "fs";
113
- import { homedir } from "os";
114
- import { join } from "path";
112
+ import { mkdirSync, existsSync as existsSync2 } from "fs";
113
+ import { join as join2 } from "path";
115
114
  import pino from "pino";
115
+
116
+ // src/services/project-root.service.ts
117
+ import { existsSync, statSync, realpathSync } from "fs";
118
+ import { dirname, join, normalize, sep } from "path";
119
+ var ProjectRootService = class {
120
+ /**
121
+ * Resolve project root directory using hierarchical detection.
122
+ */
123
+ static resolve(options) {
124
+ if (options?.projectRoot !== void 0 && options.projectRoot !== "") {
125
+ return this.normalize(options.projectRoot);
126
+ }
127
+ const projectRootEnv = process.env["PROJECT_ROOT"];
128
+ if (projectRootEnv !== void 0 && projectRootEnv !== "") {
129
+ return this.normalize(projectRootEnv);
130
+ }
131
+ const pwdEnv = process.env["PWD"];
132
+ if (pwdEnv !== void 0 && pwdEnv !== "") {
133
+ return this.normalize(pwdEnv);
134
+ }
135
+ const gitRoot = this.findGitRoot(process.cwd());
136
+ if (gitRoot !== null) {
137
+ return gitRoot;
138
+ }
139
+ return process.cwd();
140
+ }
141
+ /**
142
+ * Find git repository root by walking up the directory tree looking for .git
143
+ */
144
+ static findGitRoot(startPath) {
145
+ let currentPath = normalize(startPath);
146
+ const root = normalize(sep);
147
+ while (currentPath !== root) {
148
+ const gitPath = join(currentPath, ".git");
149
+ if (existsSync(gitPath)) {
150
+ try {
151
+ const stats = statSync(gitPath);
152
+ if (stats.isDirectory() || stats.isFile()) {
153
+ return currentPath;
154
+ }
155
+ } catch {
156
+ }
157
+ }
158
+ const parentPath = dirname(currentPath);
159
+ if (parentPath === currentPath) {
160
+ break;
161
+ }
162
+ currentPath = parentPath;
163
+ }
164
+ return null;
165
+ }
166
+ /**
167
+ * Normalize path by resolving symlinks and normalizing separators
168
+ */
169
+ static normalize(path4) {
170
+ try {
171
+ const realPath = realpathSync(path4);
172
+ return normalize(realPath);
173
+ } catch {
174
+ return normalize(path4);
175
+ }
176
+ }
177
+ /**
178
+ * Validate that a path exists and is a directory
179
+ */
180
+ static validate(path4) {
181
+ try {
182
+ const stats = statSync(path4);
183
+ return stats.isDirectory();
184
+ } catch {
185
+ return false;
186
+ }
187
+ }
188
+ };
189
+
190
+ // src/logging/logger.ts
116
191
  var VALID_LEVELS = ["trace", "debug", "info", "warn", "error", "fatal"];
117
192
  var VALID_LEVELS_SET = new Set(VALID_LEVELS);
118
193
  function getLogDir() {
119
- return join(homedir(), ".bluera", "bluera-knowledge", "logs");
194
+ const projectRoot = ProjectRootService.resolve();
195
+ return join2(projectRoot, ".bluera", "bluera-knowledge", "logs");
120
196
  }
121
197
  function ensureLogDir() {
122
198
  const logDir = getLogDir();
123
- if (!existsSync(logDir)) {
199
+ if (!existsSync2(logDir)) {
124
200
  mkdirSync(logDir, { recursive: true });
125
201
  }
126
202
  return logDir;
@@ -144,7 +220,7 @@ function initializeLogger() {
144
220
  return rootLogger;
145
221
  }
146
222
  const logDir = ensureLogDir();
147
- const logFile = join(logDir, "app.log");
223
+ const logFile = join2(logDir, "app.log");
148
224
  const level = getLogLevel();
149
225
  const options = {
150
226
  level,
@@ -196,13 +272,13 @@ function shutdownLogger() {
196
272
 
197
273
  // src/logging/payload.ts
198
274
  import { createHash } from "crypto";
199
- import { writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync2 } from "fs";
200
- import { join as join2 } from "path";
275
+ import { writeFileSync, mkdirSync as mkdirSync2, existsSync as existsSync3 } from "fs";
276
+ import { join as join3 } from "path";
201
277
  var MAX_PREVIEW_LENGTH = 500;
202
278
  var PAYLOAD_DUMP_THRESHOLD = 1e4;
203
279
  function getPayloadDir() {
204
- const dir = join2(getLogDirectory(), "payload");
205
- if (!existsSync2(dir)) {
280
+ const dir = join3(getLogDirectory(), "payload");
281
+ if (!existsSync3(dir)) {
206
282
  mkdirSync2(dir, { recursive: true });
207
283
  }
208
284
  return dir;
@@ -219,7 +295,7 @@ function summarizePayload(content, type, identifier, dumpFull = isLevelEnabled("
219
295
  const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
220
296
  const safeId = safeFilename(identifier);
221
297
  const filename = `${timestamp}-${type}-${safeId}-${hash}.json`;
222
- const filepath = join2(getPayloadDir(), filename);
298
+ const filepath = join3(getPayloadDir(), filename);
223
299
  writeFileSync(
224
300
  filepath,
225
301
  JSON.stringify(
@@ -526,7 +602,7 @@ var JobService = class {
526
602
 
527
603
  // src/services/code-graph.service.ts
528
604
  import { readFile, writeFile, mkdir, rm } from "fs/promises";
529
- import { join as join3, dirname } from "path";
605
+ import { join as join4, dirname as dirname2 } from "path";
530
606
 
531
607
  // src/analysis/ast-parser.ts
532
608
  import { parse } from "@babel/parser";
@@ -1743,7 +1819,7 @@ var CodeGraphService = class {
1743
1819
  */
1744
1820
  async saveGraph(storeId, graph) {
1745
1821
  const graphPath = this.getGraphPath(storeId);
1746
- await mkdir(dirname(graphPath), { recursive: true });
1822
+ await mkdir(dirname2(graphPath), { recursive: true });
1747
1823
  const serialized = graph.toJSON();
1748
1824
  await writeFile(graphPath, JSON.stringify(serialized, null, 2));
1749
1825
  }
@@ -1856,7 +1932,7 @@ var CodeGraphService = class {
1856
1932
  this.graphCache.clear();
1857
1933
  }
1858
1934
  getGraphPath(storeId) {
1859
- return join3(this.dataDir, "graphs", `${storeId}.json`);
1935
+ return join4(this.dataDir, "graphs", `${storeId}.json`);
1860
1936
  }
1861
1937
  /**
1862
1938
  * Type guard for SerializedGraph structure.
@@ -1901,82 +1977,8 @@ var CodeGraphService = class {
1901
1977
 
1902
1978
  // src/services/config.service.ts
1903
1979
  import { readFile as readFile2, writeFile as writeFile2, mkdir as mkdir2, access } from "fs/promises";
1904
- import { homedir as homedir2 } from "os";
1905
- import { dirname as dirname3, resolve } from "path";
1906
-
1907
- // src/services/project-root.service.ts
1908
- import { existsSync as existsSync3, statSync, realpathSync } from "fs";
1909
- import { dirname as dirname2, join as join4, normalize, sep } from "path";
1910
- var ProjectRootService = class {
1911
- /**
1912
- * Resolve project root directory using hierarchical detection.
1913
- */
1914
- static resolve(options) {
1915
- if (options?.projectRoot !== void 0 && options.projectRoot !== "") {
1916
- return this.normalize(options.projectRoot);
1917
- }
1918
- const projectRootEnv = process.env["PROJECT_ROOT"];
1919
- if (projectRootEnv !== void 0 && projectRootEnv !== "") {
1920
- return this.normalize(projectRootEnv);
1921
- }
1922
- const pwdEnv = process.env["PWD"];
1923
- if (pwdEnv !== void 0 && pwdEnv !== "") {
1924
- return this.normalize(pwdEnv);
1925
- }
1926
- const gitRoot = this.findGitRoot(process.cwd());
1927
- if (gitRoot !== null) {
1928
- return gitRoot;
1929
- }
1930
- return process.cwd();
1931
- }
1932
- /**
1933
- * Find git repository root by walking up the directory tree looking for .git
1934
- */
1935
- static findGitRoot(startPath) {
1936
- let currentPath = normalize(startPath);
1937
- const root = normalize(sep);
1938
- while (currentPath !== root) {
1939
- const gitPath = join4(currentPath, ".git");
1940
- if (existsSync3(gitPath)) {
1941
- try {
1942
- const stats = statSync(gitPath);
1943
- if (stats.isDirectory() || stats.isFile()) {
1944
- return currentPath;
1945
- }
1946
- } catch {
1947
- }
1948
- }
1949
- const parentPath = dirname2(currentPath);
1950
- if (parentPath === currentPath) {
1951
- break;
1952
- }
1953
- currentPath = parentPath;
1954
- }
1955
- return null;
1956
- }
1957
- /**
1958
- * Normalize path by resolving symlinks and normalizing separators
1959
- */
1960
- static normalize(path4) {
1961
- try {
1962
- const realPath = realpathSync(path4);
1963
- return normalize(realPath);
1964
- } catch {
1965
- return normalize(path4);
1966
- }
1967
- }
1968
- /**
1969
- * Validate that a path exists and is a directory
1970
- */
1971
- static validate(path4) {
1972
- try {
1973
- const stats = statSync(path4);
1974
- return stats.isDirectory();
1975
- } catch {
1976
- return false;
1977
- }
1978
- }
1979
- };
1980
+ import { homedir } from "os";
1981
+ import { dirname as dirname3, join as join5, resolve } from "path";
1980
1982
 
1981
1983
  // src/types/config.ts
1982
1984
  var DEFAULT_CONFIG = {
@@ -2015,6 +2017,7 @@ var DEFAULT_CONFIG = {
2015
2017
  };
2016
2018
 
2017
2019
  // src/services/config.service.ts
2020
+ var DEFAULT_CONFIG_PATH = ".bluera/bluera-knowledge/config.json";
2018
2021
  async function fileExists(path4) {
2019
2022
  try {
2020
2023
  await access(path4);
@@ -2027,12 +2030,16 @@ var ConfigService = class {
2027
2030
  configPath;
2028
2031
  dataDir;
2029
2032
  config = null;
2030
- constructor(configPath = `${homedir2()}/.bluera/bluera-knowledge/config.json`, dataDir, projectRoot) {
2031
- this.configPath = configPath;
2033
+ constructor(configPath, dataDir, projectRoot) {
2034
+ const root = projectRoot ?? ProjectRootService.resolve();
2035
+ if (configPath !== void 0 && configPath !== "") {
2036
+ this.configPath = configPath;
2037
+ } else {
2038
+ this.configPath = join5(root, DEFAULT_CONFIG_PATH);
2039
+ }
2032
2040
  if (dataDir !== void 0 && dataDir !== "") {
2033
2041
  this.dataDir = dataDir;
2034
2042
  } else {
2035
- const root = projectRoot ?? ProjectRootService.resolve();
2036
2043
  this.dataDir = this.expandPath(DEFAULT_CONFIG.dataDir, root);
2037
2044
  }
2038
2045
  }
@@ -2064,9 +2071,12 @@ var ConfigService = class {
2064
2071
  resolveDataDir() {
2065
2072
  return this.dataDir;
2066
2073
  }
2074
+ resolveConfigPath() {
2075
+ return this.configPath;
2076
+ }
2067
2077
  expandPath(path4, baseDir) {
2068
2078
  if (path4.startsWith("~")) {
2069
- return path4.replace("~", homedir2());
2079
+ return path4.replace("~", homedir());
2070
2080
  }
2071
2081
  if (!path4.startsWith("/")) {
2072
2082
  return resolve(baseDir, path4);
@@ -2077,17 +2087,19 @@ var ConfigService = class {
2077
2087
 
2078
2088
  // src/services/gitignore.service.ts
2079
2089
  import { readFile as readFile3, writeFile as writeFile3, access as access2 } from "fs/promises";
2080
- import { join as join5 } from "path";
2090
+ import { join as join6 } from "path";
2081
2091
  var REQUIRED_PATTERNS = [
2082
2092
  ".bluera/",
2083
2093
  "!.bluera/",
2084
2094
  "!.bluera/bluera-knowledge/",
2085
2095
  "!.bluera/bluera-knowledge/stores.config.json",
2096
+ "!.bluera/bluera-knowledge/config.json",
2097
+ "!.bluera/bluera-knowledge/skill-activation.json",
2086
2098
  ".bluera/bluera-knowledge/data/"
2087
2099
  ];
2088
2100
  var SECTION_HEADER = `
2089
2101
  # Bluera Knowledge
2090
- # Store definitions (stores.config.json) are committed for team sharing
2102
+ # Config files (stores.config.json, config.json, skill-activation.json) can be committed
2091
2103
  # Data directory (vector DB, cloned repos) is not committed
2092
2104
  `;
2093
2105
  async function fileExists2(path4) {
@@ -2101,7 +2113,7 @@ async function fileExists2(path4) {
2101
2113
  var GitignoreService = class {
2102
2114
  gitignorePath;
2103
2115
  constructor(projectRoot) {
2104
- this.gitignorePath = join5(projectRoot, ".gitignore");
2116
+ this.gitignorePath = join6(projectRoot, ".gitignore");
2105
2117
  }
2106
2118
  /**
2107
2119
  * Check if all required patterns are present in .gitignore
@@ -2174,7 +2186,7 @@ ${REQUIRED_PATTERNS.join("\n")}
2174
2186
  // src/services/index.service.ts
2175
2187
  import { createHash as createHash2 } from "crypto";
2176
2188
  import { readFile as readFile4, readdir } from "fs/promises";
2177
- import { join as join6, extname, basename } from "path";
2189
+ import { join as join7, extname, basename } from "path";
2178
2190
 
2179
2191
  // src/services/chunking.service.ts
2180
2192
  var CHUNK_PRESETS = {
@@ -2677,7 +2689,7 @@ var IndexService = class {
2677
2689
  const files = [];
2678
2690
  const entries = await readdir(dir, { withFileTypes: true });
2679
2691
  for (const entry of entries) {
2680
- const fullPath = join6(dir, entry.name);
2692
+ const fullPath = join7(dir, entry.name);
2681
2693
  if (entry.isDirectory()) {
2682
2694
  if (!["node_modules", ".git", "dist", "build"].includes(entry.name)) {
2683
2695
  files.push(...await this.scanDirectory(fullPath));
@@ -3878,7 +3890,7 @@ var SearchService = class {
3878
3890
 
3879
3891
  // src/services/store-definition.service.ts
3880
3892
  import { readFile as readFile5, writeFile as writeFile4, mkdir as mkdir3, access as access3 } from "fs/promises";
3881
- import { dirname as dirname4, resolve as resolve2, isAbsolute, join as join7 } from "path";
3893
+ import { dirname as dirname4, resolve as resolve2, isAbsolute, join as join8 } from "path";
3882
3894
 
3883
3895
  // src/types/store-definition.ts
3884
3896
  import { z as z2 } from "zod";
@@ -3943,7 +3955,7 @@ var StoreDefinitionService = class {
3943
3955
  config = null;
3944
3956
  constructor(projectRoot) {
3945
3957
  this.projectRoot = projectRoot ?? ProjectRootService.resolve();
3946
- this.configPath = join7(this.projectRoot, ".bluera/bluera-knowledge/stores.config.json");
3958
+ this.configPath = join8(this.projectRoot, ".bluera/bluera-knowledge/stores.config.json");
3947
3959
  }
3948
3960
  /**
3949
3961
  * Load store definitions from config file.
@@ -4083,7 +4095,7 @@ var StoreDefinitionService = class {
4083
4095
  // src/services/store.service.ts
4084
4096
  import { randomUUID as randomUUID2 } from "crypto";
4085
4097
  import { readFile as readFile6, writeFile as writeFile5, mkdir as mkdir5, stat, access as access4 } from "fs/promises";
4086
- import { join as join8, resolve as resolve3 } from "path";
4098
+ import { join as join9, resolve as resolve3 } from "path";
4087
4099
 
4088
4100
  // src/plugin/git-clone.ts
4089
4101
  import { spawn } from "child_process";
@@ -4231,7 +4243,7 @@ var StoreService = class {
4231
4243
  case "repo": {
4232
4244
  let repoPath = input.path;
4233
4245
  if (input.url !== void 0) {
4234
- const cloneDir = join8(this.dataDir, "repos", id);
4246
+ const cloneDir = join9(this.dataDir, "repos", id);
4235
4247
  const result = await cloneRepository({
4236
4248
  url: input.url,
4237
4249
  targetDir: cloneDir,
@@ -4358,7 +4370,7 @@ var StoreService = class {
4358
4370
  return ok(void 0);
4359
4371
  }
4360
4372
  async loadRegistry() {
4361
- const registryPath = join8(this.dataDir, "stores.json");
4373
+ const registryPath = join9(this.dataDir, "stores.json");
4362
4374
  const exists = await fileExists4(registryPath);
4363
4375
  if (!exists) {
4364
4376
  this.registry = { stores: [] };
@@ -4383,7 +4395,7 @@ var StoreService = class {
4383
4395
  }
4384
4396
  }
4385
4397
  async saveRegistry() {
4386
- const registryPath = join8(this.dataDir, "stores.json");
4398
+ const registryPath = join9(this.dataDir, "stores.json");
4387
4399
  await writeFile5(registryPath, JSON.stringify(this.registry, null, 2));
4388
4400
  }
4389
4401
  };
@@ -4724,10 +4736,10 @@ var PythonBridge = class {
4724
4736
  };
4725
4737
 
4726
4738
  // src/db/embeddings.ts
4727
- import { homedir as homedir3 } from "os";
4728
- import { join as join9 } from "path";
4739
+ import { homedir as homedir2 } from "os";
4740
+ import { join as join10 } from "path";
4729
4741
  import { pipeline, env } from "@huggingface/transformers";
4730
- env.cacheDir = join9(homedir3(), ".cache", "huggingface-transformers");
4742
+ env.cacheDir = join10(homedir2(), ".cache", "huggingface-transformers");
4731
4743
  var EmbeddingEngine = class {
4732
4744
  extractor = null;
4733
4745
  modelName;
@@ -5114,4 +5126,4 @@ export {
5114
5126
  createServices,
5115
5127
  destroyServices
5116
5128
  };
5117
- //# sourceMappingURL=chunk-WYZQUKUD.js.map
5129
+ //# sourceMappingURL=chunk-WMALVLFW.js.map