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.
- package/README.md +25 -1
- package/dist/index.js +47 -4
- 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
|
|
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
|
|
12723
|
-
if (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
---
|