feat(vault): add VaultStore for managing Obsidian-compatible markdown notes
This commit is contained in:
parent
c7366cf57f
commit
27aaa5e7d1
2 changed files with 90 additions and 0 deletions
28
pkg/vault/store.go
Normal file
28
pkg/vault/store.go
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
package vault
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
type VaultStore struct {
|
||||
rootPath string
|
||||
}
|
||||
|
||||
func NewVaultStore(rootPath string) *VaultStore {
|
||||
return &VaultStore{rootPath: rootPath}
|
||||
}
|
||||
|
||||
func (vs *VaultStore) CreateNote(name string, frontmatter map[string]interface{}, content string) error {
|
||||
if err := os.MkdirAll(vs.rootPath, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
note := "---\n"
|
||||
if fm, err := yaml.Marshal(frontmatter); err == nil {
|
||||
note += string(fm)
|
||||
}
|
||||
note += "---\n\n" + content
|
||||
notePath := filepath.Join(vs.rootPath, name+".md")
|
||||
return os.WriteFile(notePath, []byte(note), 0644)
|
||||
}
|
||||
62
pkg/vault/store_test.go
Normal file
62
pkg/vault/store_test.go
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
package vault
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"path/filepath"
|
||||
"os"
|
||||
)
|
||||
|
||||
func TestCreateNote(t *testing.T) {
|
||||
tmpDir, _ := os.MkdirTemp("", "test-vault")
|
||||
defer os.RemoveAll(tmpDir)
|
||||
|
||||
store := NewVaultStore(tmpDir)
|
||||
|
||||
err := store.CreateNote("test-note", map[string]interface{}{
|
||||
"title": "Test Note",
|
||||
"tags": []string{"memory", "test"},
|
||||
}, "## Content here")
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
notePath := filepath.Join(tmpDir, "test-note.md")
|
||||
if _, err := os.Stat(notePath); os.IsNotExist(err) {
|
||||
t.Errorf("expected note file to be created at %s", notePath)
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadNoteWithFrontmatter(t *testing.T) {
|
||||
store := NewVaultStore("/tmp/test-vault")
|
||||
|
||||
// Create note with frontmatter
|
||||
store.CreateNote("MEMORY", map[string]interface{}{
|
||||
"title": "Agent Memory",
|
||||
"tags": []string{"memory"},
|
||||
}, "# Content")
|
||||
|
||||
fm, body, err := store.ReadNote("MEMORY")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if fm["title"] != "Agent Memory" {
|
||||
t.Errorf("expected title in frontmatter")
|
||||
}
|
||||
if !contains(body, "# Content") {
|
||||
t.Errorf("expected body to contain content")
|
||||
}
|
||||
}
|
||||
|
||||
func contains(s, substr string) bool {
|
||||
return len(s) >= len(substr) && (s == substr || len(s) > 0 && containsHelper(s, substr))
|
||||
}
|
||||
|
||||
func containsHelper(s, substr string) bool {
|
||||
for i := 0; i <= len(s)-len(substr); i++ {
|
||||
if s[i:i+len(substr)] == substr {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue