bluera-knowledge 0.11.8 → 0.11.10
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/.claude-plugin/plugin.json +1 -1
- package/.github/workflows/auto-release.yml +5 -0
- package/.github/workflows/ci.yml +14 -1
- package/.github/workflows/release.yml +6 -0
- package/CHANGELOG.md +29 -0
- package/dist/index.js +126 -110
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/plugin/commands.test.ts +2 -1
- package/src/plugin/commands.ts +194 -164
|
@@ -40,6 +40,11 @@ jobs:
|
|
|
40
40
|
echo "exists=false" >> $GITHUB_OUTPUT
|
|
41
41
|
fi
|
|
42
42
|
|
|
43
|
+
# CRITICAL: This is the quality gate for releases.
|
|
44
|
+
# CI workflow does NOT run on tags (to avoid redundant ~3 min test runs).
|
|
45
|
+
# This step ensures all CI checks pass on main BEFORE creating a tag.
|
|
46
|
+
# The Release workflow trusts this guarantee and publishes immediately.
|
|
47
|
+
# See ci.yml header comment for the full quality guarantee chain.
|
|
43
48
|
- name: Wait for CI to complete
|
|
44
49
|
if: steps.check_tag.outputs.exists == 'false'
|
|
45
50
|
uses: lewagon/wait-on-check-action@v1.3.4
|
package/.github/workflows/ci.yml
CHANGED
|
@@ -1,9 +1,22 @@
|
|
|
1
1
|
name: CI
|
|
2
2
|
|
|
3
|
+
# CI runs on branch pushes and PRs, but NOT on tags.
|
|
4
|
+
#
|
|
5
|
+
# Why no tag trigger?
|
|
6
|
+
# - Auto Release workflow (auto-release.yml) waits for CI to pass on main
|
|
7
|
+
# before creating a tag (uses wait-on-check-action with lint-and-typecheck,
|
|
8
|
+
# test, build checks)
|
|
9
|
+
# - The tag contains the exact same code that just passed CI on main
|
|
10
|
+
# - Running CI again on the tag is redundant and wastes ~3 minutes per release
|
|
11
|
+
# - Release workflow (release.yml) trusts this guarantee and publishes immediately
|
|
12
|
+
#
|
|
13
|
+
# Quality guarantee chain:
|
|
14
|
+
# push to main → CI passes → Auto Release creates tag → Release publishes
|
|
15
|
+
#
|
|
3
16
|
on:
|
|
4
17
|
push:
|
|
5
18
|
branches: ['**']
|
|
6
|
-
|
|
19
|
+
# Note: tags intentionally excluded - see comment above
|
|
7
20
|
pull_request:
|
|
8
21
|
branches: [main]
|
|
9
22
|
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
name: Release
|
|
2
2
|
|
|
3
|
+
# Publishes to npm when a tag is pushed.
|
|
4
|
+
#
|
|
5
|
+
# Quality assumption: Tags are only created by Auto Release workflow AFTER
|
|
6
|
+
# CI passes on main. This workflow trusts that guarantee and does not re-run
|
|
7
|
+
# tests. See ci.yml and auto-release.yml for the full quality chain.
|
|
8
|
+
#
|
|
3
9
|
on:
|
|
4
10
|
push:
|
|
5
11
|
tags:
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,35 @@
|
|
|
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.11.10](https://github.com/blueraai/bluera-knowledge/compare/v0.11.6...v0.11.10) (2026-01-10)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Features
|
|
9
|
+
|
|
10
|
+
* **scripts:** add post-release npm validation script ([e4c29a0](https://github.com/blueraai/bluera-knowledge/commit/e4c29a0c83907de4bc293a69a58412629457fb22))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
### Bug Fixes
|
|
14
|
+
|
|
15
|
+
* **cli:** plugin-api commands now respect global options ([d3cca02](https://github.com/blueraai/bluera-knowledge/commit/d3cca02ffc679ffc187b76c7682f3cc177eabdea))
|
|
16
|
+
* **plugin:** properly close services after command execution ([eeaf743](https://github.com/blueraai/bluera-knowledge/commit/eeaf743750be73fd9c7a9e72440b2fd0fb5a53fa))
|
|
17
|
+
* **scripts:** show real-time output in validation script ([8a4bdec](https://github.com/blueraai/bluera-knowledge/commit/8a4bdec8b63c504d34ba35bfe19da795f7f7fd07))
|
|
18
|
+
* **scripts:** use mktemp for temp directories in validation script ([3107861](https://github.com/blueraai/bluera-knowledge/commit/3107861bd7a966016fde2a121469dd84756f39be))
|
|
19
|
+
|
|
20
|
+
## [0.11.9](https://github.com/blueraai/bluera-knowledge/compare/v0.11.6...v0.11.9) (2026-01-10)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
### Features
|
|
24
|
+
|
|
25
|
+
* **scripts:** add post-release npm validation script ([e4c29a0](https://github.com/blueraai/bluera-knowledge/commit/e4c29a0c83907de4bc293a69a58412629457fb22))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* **cli:** plugin-api commands now respect global options ([d3cca02](https://github.com/blueraai/bluera-knowledge/commit/d3cca02ffc679ffc187b76c7682f3cc177eabdea))
|
|
31
|
+
* **scripts:** show real-time output in validation script ([8a4bdec](https://github.com/blueraai/bluera-knowledge/commit/8a4bdec8b63c504d34ba35bfe19da795f7f7fd07))
|
|
32
|
+
* **scripts:** use mktemp for temp directories in validation script ([3107861](https://github.com/blueraai/bluera-knowledge/commit/3107861bd7a966016fde2a121469dd84756f39be))
|
|
33
|
+
|
|
5
34
|
## [0.11.8](https://github.com/blueraai/bluera-knowledge/compare/v0.11.6...v0.11.8) (2026-01-10)
|
|
6
35
|
|
|
7
36
|
|
package/dist/index.js
CHANGED
|
@@ -779,28 +779,32 @@ async function handleAddRepo(args, options = {}) {
|
|
|
779
779
|
options.dataDir,
|
|
780
780
|
options.projectRoot ?? process.env["PWD"]
|
|
781
781
|
);
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
782
|
+
try {
|
|
783
|
+
const storeName = args.name ?? extractRepoName(args.url);
|
|
784
|
+
console.log(`Cloning ${args.url}...`);
|
|
785
|
+
const result = await services.store.create({
|
|
786
|
+
name: storeName,
|
|
787
|
+
type: "repo",
|
|
788
|
+
url: args.url,
|
|
789
|
+
...args.branch !== void 0 ? { branch: args.branch } : {}
|
|
790
|
+
});
|
|
791
|
+
if (!result.success) {
|
|
792
|
+
console.error(`Error: ${result.error.message}`);
|
|
793
|
+
process.exit(1);
|
|
794
|
+
}
|
|
795
|
+
console.log(`Created store: ${storeName} (${result.data.id})`);
|
|
796
|
+
if ("path" in result.data) {
|
|
797
|
+
console.log(`Location: ${result.data.path}`);
|
|
798
|
+
}
|
|
799
|
+
console.log("\nIndexing...");
|
|
800
|
+
const indexResult = await services.index.indexStore(result.data);
|
|
801
|
+
if (indexResult.success) {
|
|
802
|
+
console.log(`Indexed ${String(indexResult.data.documentsIndexed)} files`);
|
|
803
|
+
} else {
|
|
804
|
+
console.error(`Indexing failed: ${indexResult.error.message}`);
|
|
805
|
+
}
|
|
806
|
+
} finally {
|
|
807
|
+
await destroyServices(services);
|
|
804
808
|
}
|
|
805
809
|
}
|
|
806
810
|
async function handleAddFolder(args, options = {}) {
|
|
@@ -809,28 +813,32 @@ async function handleAddFolder(args, options = {}) {
|
|
|
809
813
|
options.dataDir,
|
|
810
814
|
options.projectRoot ?? process.env["PWD"]
|
|
811
815
|
);
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
816
|
+
try {
|
|
817
|
+
const { basename } = await import("path");
|
|
818
|
+
const storeName = args.name ?? basename(args.path);
|
|
819
|
+
console.log(`Adding folder: ${args.path}...`);
|
|
820
|
+
const result = await services.store.create({
|
|
821
|
+
name: storeName,
|
|
822
|
+
type: "file",
|
|
823
|
+
path: args.path
|
|
824
|
+
});
|
|
825
|
+
if (!result.success) {
|
|
826
|
+
console.error(`Error: ${result.error.message}`);
|
|
827
|
+
process.exit(1);
|
|
828
|
+
}
|
|
829
|
+
console.log(`Created store: ${storeName} (${result.data.id})`);
|
|
830
|
+
if ("path" in result.data) {
|
|
831
|
+
console.log(`Location: ${result.data.path}`);
|
|
832
|
+
}
|
|
833
|
+
console.log("\nIndexing...");
|
|
834
|
+
const indexResult = await services.index.indexStore(result.data);
|
|
835
|
+
if (indexResult.success) {
|
|
836
|
+
console.log(`Indexed ${String(indexResult.data.documentsIndexed)} files`);
|
|
837
|
+
} else {
|
|
838
|
+
console.error(`Indexing failed: ${indexResult.error.message}`);
|
|
839
|
+
}
|
|
840
|
+
} finally {
|
|
841
|
+
await destroyServices(services);
|
|
834
842
|
}
|
|
835
843
|
}
|
|
836
844
|
async function handleStores(options = {}) {
|
|
@@ -839,86 +847,94 @@ async function handleStores(options = {}) {
|
|
|
839
847
|
options.dataDir,
|
|
840
848
|
options.projectRoot ?? process.env["PWD"]
|
|
841
849
|
);
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
const
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
850
|
+
try {
|
|
851
|
+
const stores = await services.store.list();
|
|
852
|
+
if (stores.length === 0) {
|
|
853
|
+
console.log("No stores found.");
|
|
854
|
+
console.log("\nCreate a store with:");
|
|
855
|
+
console.log(" /bluera-knowledge:add-repo <url> --name=<name>");
|
|
856
|
+
console.log(" /bluera-knowledge:add-folder <path> --name=<name>");
|
|
857
|
+
return;
|
|
858
|
+
}
|
|
859
|
+
console.log("| Name | Type | ID | Source |");
|
|
860
|
+
console.log("|------|------|----|--------------------|");
|
|
861
|
+
for (const store of stores) {
|
|
862
|
+
const name = store.name;
|
|
863
|
+
const type = store.type;
|
|
864
|
+
const id = store.id;
|
|
865
|
+
let source = "";
|
|
866
|
+
if ("url" in store && store.url !== void 0) {
|
|
867
|
+
source = store.url;
|
|
868
|
+
} else if ("path" in store) {
|
|
869
|
+
source = store.path;
|
|
870
|
+
}
|
|
871
|
+
console.log(`| ${name} | ${type} | ${id.substring(0, 8)}... | ${source} |`);
|
|
872
|
+
}
|
|
873
|
+
} finally {
|
|
874
|
+
await destroyServices(services);
|
|
863
875
|
}
|
|
864
876
|
}
|
|
865
877
|
async function handleSuggest(options = {}) {
|
|
866
878
|
const projectRoot = options.projectRoot ?? process.env["PWD"] ?? process.cwd();
|
|
867
879
|
console.log("Analyzing project dependencies...\n");
|
|
868
880
|
const services = await createServices(options.config, options.dataDir, projectRoot);
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
`\u2714 Scanned ${String(totalFilesScanned)} files${skippedFiles > 0 ? ` (skipped ${String(skippedFiles)})` : ""}
|
|
883
|
-
`
|
|
884
|
-
);
|
|
885
|
-
if (usages.length === 0) {
|
|
886
|
-
console.log("No external dependencies found in this project.");
|
|
887
|
-
console.log("\nMake sure you have a package.json or requirements.txt file.");
|
|
888
|
-
return;
|
|
889
|
-
}
|
|
890
|
-
const existingStores = await services.store.list();
|
|
891
|
-
const existingRepoNames = new Set(existingStores.map((s) => s.name));
|
|
892
|
-
const newUsages = usages.filter((u) => !existingRepoNames.has(u.packageName));
|
|
893
|
-
if (newUsages.length === 0) {
|
|
894
|
-
console.log("\u2714 All dependencies are already in knowledge stores!");
|
|
895
|
-
return;
|
|
896
|
-
}
|
|
897
|
-
const topSuggestions = newUsages.slice(0, 5);
|
|
898
|
-
console.log("Top dependencies by usage in this project:\n");
|
|
899
|
-
topSuggestions.forEach((usage, i) => {
|
|
900
|
-
console.log(`${String(i + 1)}. ${usage.packageName}`);
|
|
881
|
+
try {
|
|
882
|
+
const analyzer = new DependencyUsageAnalyzer();
|
|
883
|
+
const resolver = new RepoUrlResolver();
|
|
884
|
+
const spinner = ora3("Scanning source files...").start();
|
|
885
|
+
const result = await analyzer.analyze(projectRoot, (current, total, message) => {
|
|
886
|
+
spinner.text = `${message} (${String(current)}/${String(total)})`;
|
|
887
|
+
});
|
|
888
|
+
spinner.stop();
|
|
889
|
+
if (!result.success) {
|
|
890
|
+
console.error(`Error: ${result.error.message}`);
|
|
891
|
+
process.exit(1);
|
|
892
|
+
}
|
|
893
|
+
const { usages, totalFilesScanned, skippedFiles } = result.data;
|
|
901
894
|
console.log(
|
|
902
|
-
|
|
895
|
+
`\u2714 Scanned ${String(totalFilesScanned)} files${skippedFiles > 0 ? ` (skipped ${String(skippedFiles)})` : ""}
|
|
903
896
|
`
|
|
904
897
|
);
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
console.log(
|
|
898
|
+
if (usages.length === 0) {
|
|
899
|
+
console.log("No external dependencies found in this project.");
|
|
900
|
+
console.log("\nMake sure you have a package.json or requirements.txt file.");
|
|
901
|
+
return;
|
|
902
|
+
}
|
|
903
|
+
const existingStores = await services.store.list();
|
|
904
|
+
const existingRepoNames = new Set(existingStores.map((s) => s.name));
|
|
905
|
+
const newUsages = usages.filter((u) => !existingRepoNames.has(u.packageName));
|
|
906
|
+
if (newUsages.length === 0) {
|
|
907
|
+
console.log("\u2714 All dependencies are already in knowledge stores!");
|
|
908
|
+
return;
|
|
909
|
+
}
|
|
910
|
+
const topSuggestions = newUsages.slice(0, 5);
|
|
911
|
+
console.log("Top dependencies by usage in this project:\n");
|
|
912
|
+
topSuggestions.forEach((usage, i) => {
|
|
913
|
+
console.log(`${String(i + 1)}. ${usage.packageName}`);
|
|
915
914
|
console.log(
|
|
916
|
-
`
|
|
915
|
+
` ${String(usage.importCount)} imports across ${String(usage.fileCount)} files
|
|
917
916
|
`
|
|
918
917
|
);
|
|
918
|
+
});
|
|
919
|
+
console.log("Searching for repository URLs...\n");
|
|
920
|
+
for (const usage of topSuggestions) {
|
|
921
|
+
const repoResult = await resolver.findRepoUrl(usage.packageName, usage.language);
|
|
922
|
+
if (repoResult.url !== null) {
|
|
923
|
+
console.log(`\u2714 ${usage.packageName}: ${repoResult.url}`);
|
|
924
|
+
console.log(` /bluera-knowledge:add-repo ${repoResult.url} --name=${usage.packageName}
|
|
925
|
+
`);
|
|
926
|
+
} else {
|
|
927
|
+
console.log(`\u2717 ${usage.packageName}: Could not find repository URL`);
|
|
928
|
+
console.log(
|
|
929
|
+
` You can manually add it: /bluera-knowledge:add-repo <url> --name=${usage.packageName}
|
|
930
|
+
`
|
|
931
|
+
);
|
|
932
|
+
}
|
|
919
933
|
}
|
|
934
|
+
console.log("Use the commands above to add repositories to your knowledge stores.");
|
|
935
|
+
} finally {
|
|
936
|
+
await destroyServices(services);
|
|
920
937
|
}
|
|
921
|
-
console.log("Use the commands above to add repositories to your knowledge stores.");
|
|
922
938
|
}
|
|
923
939
|
|
|
924
940
|
// src/cli/commands/plugin-api.ts
|