opencode-knowledge 0.5.0 → 0.5.1

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.
Files changed (3) hide show
  1. package/README.md +25 -1
  2. package/dist/index.js +47 -4
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -150,9 +150,33 @@ Your knowledge content here...
150
150
  | `tags` | Yes | Array of searchable tags |
151
151
  | `description` | Yes | Brief summary (used in search results) |
152
152
  | `category` | Yes | Category for organization (e.g., `frontend`, `backend`, `standards`) |
153
- | `required_knowledge` | No | Other packages that should be loaded first |
153
+ | `required_knowledge` | No | Other packages that should be loaded automatically before this one (supports recursive dependencies) |
154
154
  | `file_patterns` | No | File patterns where this knowledge applies (not yet implemented) |
155
155
 
156
+ ### Dependency Loading
157
+
158
+ The `required_knowledge` field enables automatic dependency loading. When you load a package, the plugin automatically loads all its dependencies first, recursively.
159
+
160
+ **Example:**
161
+
162
+ ```markdown
163
+ <!-- vault/personal/blog-writing.md -->
164
+ ---
165
+ tags: [blog, writing]
166
+ description: Blog writing guidelines
167
+ category: personal
168
+ required_knowledge:
169
+ - personal/author-context
170
+ ---
171
+ ```
172
+
173
+ When AI loads `personal/blog-writing.md`, the plugin:
174
+ 1. Detects the `required_knowledge` dependency
175
+ 2. Automatically loads `personal/author-context.md` first
176
+ 3. Then loads `personal/blog-writing.md`
177
+
178
+ This ensures the AI always has complete context without manual tracking. Dependencies can be nested (Package A requires B, B requires C), and the plugin handles circular dependencies gracefully.
179
+
156
180
  ---
157
181
 
158
182
  ## Directory Structure
package/dist/index.js CHANGED
@@ -12713,19 +12713,53 @@ _...and ${results.length - 10} more results_`;
12713
12713
  import { readFileSync as readFileSync3, existsSync as existsSync5 } from "fs";
12714
12714
  import { join as join4 } from "path";
12715
12715
  var VAULT_DIR2 = ".opencode/knowledge/vault";
12716
+ function resolveDependencies(packagePath, vaultDir, loaded = new Set) {
12717
+ if (loaded.has(packagePath)) {
12718
+ return [];
12719
+ }
12720
+ loaded.add(packagePath);
12721
+ const result = [];
12722
+ const normalizedPath = packagePath.endsWith(".md") ? packagePath : `${packagePath}.md`;
12723
+ const fullPath = join4(vaultDir, normalizedPath);
12724
+ if (!existsSync5(fullPath)) {
12725
+ return [];
12726
+ }
12727
+ try {
12728
+ const content = readFileSync3(fullPath, "utf-8");
12729
+ const { frontmatter } = parseFrontmatter(content);
12730
+ if (frontmatter.required_knowledge && Array.isArray(frontmatter.required_knowledge)) {
12731
+ for (const dep of frontmatter.required_knowledge) {
12732
+ const depPath = dep.endsWith(".md") ? dep : `${dep}.md`;
12733
+ const depPackages = resolveDependencies(depPath, vaultDir, loaded);
12734
+ result.push(...depPackages);
12735
+ }
12736
+ }
12737
+ result.push(normalizedPath);
12738
+ } catch {
12739
+ return [];
12740
+ }
12741
+ return result;
12742
+ }
12716
12743
  var knowledgeLoadTool = tool({
12717
12744
  description: "Load one or more knowledge packages from the vault into the current session context. The package content will be available for reference in subsequent responses.",
12718
12745
  args: {
12719
12746
  paths: tool.schema.string().describe("Comma-separated package paths relative to vault (e.g., 'standards/code-conventions.md,frontend/react-patterns.md')")
12720
12747
  },
12721
12748
  async execute(args) {
12722
- const packagePaths = args.paths.split(",").map((p) => p.trim()).filter(Boolean);
12723
- if (packagePaths.length === 0) {
12749
+ const requestedPaths = args.paths.split(",").map((p) => p.trim()).filter(Boolean);
12750
+ if (requestedPaths.length === 0) {
12724
12751
  return "No package paths provided";
12725
12752
  }
12753
+ const allPackagePaths = new Set;
12754
+ const loadedTracker = new Set;
12755
+ for (const path2 of requestedPaths) {
12756
+ const resolved = resolveDependencies(path2, VAULT_DIR2, loadedTracker);
12757
+ resolved.forEach((p) => allPackagePaths.add(p));
12758
+ }
12726
12759
  const loaded = [];
12727
12760
  const failed = [];
12728
- for (const packagePath of packagePaths) {
12761
+ const packageArray = Array.from(allPackagePaths);
12762
+ for (const packagePath of packageArray) {
12729
12763
  const fullPath = join4(VAULT_DIR2, packagePath);
12730
12764
  if (!existsSync5(fullPath)) {
12731
12765
  failed.push(`\u26A0\uFE0F Package not found: ${packagePath}`);
@@ -12742,9 +12776,18 @@ ${content}`);
12742
12776
  }
12743
12777
  let output = "";
12744
12778
  if (loaded.length > 0) {
12745
- output += `\u2705 Loaded ${loaded.length}/${packagePaths.length} packages:
12779
+ const totalCount = packageArray.length;
12780
+ const requestedCount = requestedPaths.length;
12781
+ const depsCount = totalCount - requestedCount;
12782
+ if (depsCount > 0) {
12783
+ output += `\u2705 Loaded ${loaded.length}/${totalCount} packages (${requestedCount} requested + ${depsCount} dependencies):
12746
12784
 
12747
12785
  `;
12786
+ } else {
12787
+ output += `\u2705 Loaded ${loaded.length}/${totalCount} packages:
12788
+
12789
+ `;
12790
+ }
12748
12791
  output += loaded.join(`
12749
12792
 
12750
12793
  ---
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "opencode-knowledge",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "An OpenCode plugin",
5
5
  "author": {
6
6
  "name": "msegoviadev",