Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 1 addition & 36 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ crates/
├── notes/
├── cache/
├── index/
└── workspace.yml
└── workspace.json
```

Notes are stored separately from source files. FrilVault does not modify the source code it annotates.
Expand Down
2 changes: 1 addition & 1 deletion crates/frilvault-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ serde = { workspace = true, features = ["derive"] }
uuid = { workspace = true, features = ["v4", "serde"] }
thiserror.workspace = true

serde_yml = "0.0.13"
serde_json= "1.0.150"
4 changes: 2 additions & 2 deletions crates/frilvault-core/src/app/frilvault.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use crate::{
FrilVaultResult,
note::NoteService,
runtime::VaultContext,
storage::YamlNoteRepository,
storage::NoteRepository,
workspace::{PathResolver, WorkspaceIndexRepository, WorkspaceRepository, WorkspaceService},
};

Expand All @@ -28,7 +28,7 @@ impl FrilVault {
let index_repository = WorkspaceIndexRepository::new(resolver.clone());
index_repository.create_if_missing()?;

let note_repository = YamlNoteRepository::new(resolver.clone());
let note_repository = NoteRepository::new(resolver.clone());

let vault_context = VaultContext::new(note_repository, index_repository.clone());

Expand Down
4 changes: 2 additions & 2 deletions crates/frilvault-core/src/constants.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
pub const VAULT_DIR_NAME: &str = ".vault";
pub const NOTE_FILE_EXTENSION: &str = "yml";
pub const NOTE_FILE_EXTENSION: &str = "json";

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Add a backward-compatible read path for legacy YAML vault data.

Changing both constants to JSON-only makes existing *.yml notes and workspace.yml undiscoverable unless migration/fallback is guaranteed. That is a persisted storage contract break for existing vaults.

Minimal compatibility bridge
 pub const NOTE_FILE_EXTENSION: &str = "json";
+pub const LEGACY_NOTE_FILE_EXTENSION: &str = "yml";
 ...
 pub const WORKSPACE_FILE_NAME: &str = "workspace.json";
+pub const LEGACY_WORKSPACE_FILE_NAME: &str = "workspace.yml";

Then load-path logic should: try JSON first, fallback to legacy YAML once, then rewrite JSON.

Also applies to: 7-7

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/frilvault-core/src/constants.rs` at line 2, The change to
NOTE_FILE_EXTENSION breaks backward compatibility with existing vaults using
YAML files. Keep both the JSON extension constant and add a legacy YAML
extension constant in the constants.rs file, then update the file loading logic
throughout the codebase to first attempt reading from the JSON file path, fall
back to reading from the YAML file path if JSON is not found, and automatically
rewrite the loaded data back to JSON format to migrate the vault forward. This
ensures existing YAML vaults remain discoverable and functional while new data
is stored in JSON.

// pub const SCHEMA_VERSION: u32 = 1;
pub const NOTES_DIR_NAME: &str = "notes";
pub const CACHE_DIR_NAME: &str = "cache";
pub const INDEX_DIR_NAME: &str = "index";
pub const WORKSPACE_FILE_NAME: &str = "workspace.yml";
pub const WORKSPACE_FILE_NAME: &str = "workspace.json";
4 changes: 2 additions & 2 deletions crates/frilvault-core/src/error/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ pub enum FrilVaultError {
#[error("io error: {0}")]
Io(#[from] std::io::Error),

#[error("yaml error: {0}")]
Yaml(#[from] serde_yml::Error),
#[error("json error: {0}")]
JSON(#[from] serde_json::Error),

#[error("source path is outside workspace")]
SourcePathOutsideWorkspace,
Expand Down
34 changes: 34 additions & 0 deletions crates/frilvault-core/src/note/entity/anchor.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use serde::{Deserialize, Serialize};

// TODO: Regex parser
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(tag = "type")]
pub enum NoteAnchor {
Line(LineAnchor),
Symbol(SymbolAnchor),
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct LineAnchor {
pub line: u32,
pub column: u32,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SymbolAnchor {
pub name: String,
pub kind: SymbolKind,
pub signature: Option<String>,
pub line_hint: Option<u32>,
}

#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum SymbolKind {
Function,
Struct,
Enum,
Trait,
Impl,
Method,
Unknown,
}
7 changes: 0 additions & 7 deletions crates/frilvault-core/src/note/entity/line_anchor.rs

This file was deleted.

10 changes: 2 additions & 8 deletions crates/frilvault-core/src/note/entity/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
mod line_anchor;
mod anchor;
mod note;
mod note_anchor;
mod note_file;
mod symbol_anchor;
mod symbol_kind;

pub use line_anchor::*;
pub use anchor::*;
pub use note::*;
pub use note_anchor::*;
pub use note_file::*;
pub use symbol_anchor::*;
pub use symbol_kind::*;
11 changes: 0 additions & 11 deletions crates/frilvault-core/src/note/entity/note_anchor.rs

This file was deleted.

8 changes: 8 additions & 0 deletions crates/frilvault-core/src/note/entity/note_file.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
use std::path::PathBuf;

use serde::{Deserialize, Serialize};

use crate::note::Note;

#[derive(Debug, Clone)]
pub struct NoteFileRecord {
pub source_file: PathBuf,
pub note_file: NoteFile,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize, PartialEq, Eq)]
pub struct NoteFile {
pub notes: Vec<Note>,
Expand Down
11 changes: 0 additions & 11 deletions crates/frilvault-core/src/note/entity/symbol_anchor.rs

This file was deleted.

12 changes: 0 additions & 12 deletions crates/frilvault-core/src/note/entity/symbol_kind.rs

This file was deleted.

15 changes: 15 additions & 0 deletions crates/frilvault-core/src/parser/json_parser.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use crate::FrilVaultResult;
use crate::note::NoteFile;

#[derive(Debug, Default, Clone)]
pub struct JsonParser;

impl JsonParser {
pub fn serialize(&self, note_file: &NoteFile) -> FrilVaultResult<String> {
Ok(serde_json::to_string(note_file)?)
}

pub fn deserialize(&self, content: &str) -> FrilVaultResult<NoteFile> {
Ok(serde_json::from_str(content)?)
}
}
6 changes: 2 additions & 4 deletions crates/frilvault-core/src/parser/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
mod note_parser;
mod yaml_parser;
mod json_parser;

pub use note_parser::*;
pub use yaml_parser::*;
pub use json_parser::*;
14 changes: 0 additions & 14 deletions crates/frilvault-core/src/parser/note_parser.rs

This file was deleted.

16 changes: 0 additions & 16 deletions crates/frilvault-core/src/parser/yaml_parser.rs

This file was deleted.

8 changes: 4 additions & 4 deletions crates/frilvault-core/src/runtime/vault_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ use std::path::{Path, PathBuf};

use crate::{
FrilVaultResult,
note::NoteFile,
note::{NoteFile, NoteFileRecord},
runtime::NoteCache,
storage::{NoteFileRecord, YamlNoteRepository},
storage::NoteRepository,
workspace::{WorkspaceIndex, WorkspaceIndexRepository},
};

Expand All @@ -20,14 +20,14 @@ use crate::{
/// accessing repositories directly.
#[derive(Clone)]
pub struct VaultContext {
pub note_repository: YamlNoteRepository,
pub note_repository: NoteRepository,
pub workspace_index_repository: WorkspaceIndexRepository,
pub note_cache: NoteCache,
}

impl VaultContext {
pub fn new(
note_repository: YamlNoteRepository,
note_repository: NoteRepository,
workspace_index_repository: WorkspaceIndexRepository,
) -> Self {
Self {
Expand Down
6 changes: 2 additions & 4 deletions crates/frilvault-core/src/storage/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
mod note_file_record;
mod yaml_repository;
mod repository;

pub use note_file_record::*;
pub use yaml_repository::*;
pub use repository::*;
9 changes: 0 additions & 9 deletions crates/frilvault-core/src/storage/note_file_record.rs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
//! YAML-backed note repository.
//! JSON-backed note repository.
//!
//! Notes are persisted as YAML files
//! Notes are persisted as JSON files
//! inside the `.vault/notes` directory.

use std::fs;
use std::path::{Path, PathBuf};

use crate::note::NoteFile;
use crate::parser::{NoteParser, YamlParser};
use crate::storage::NoteFileRecord;
use crate::note::{NoteFile, NoteFileRecord};
use crate::parser::JsonParser;
use crate::workspace::PathResolver;
use crate::{FrilVaultResult, Note};

#[derive(Debug, Clone)]
pub struct YamlNoteRepository {
pub struct NoteRepository {
path_resolver: PathResolver,
parser: YamlParser,
parser: JsonParser,
}

impl YamlNoteRepository {
impl NoteRepository {
pub fn new(path_resolver: PathResolver) -> Self {
Self {
path_resolver,
parser: YamlParser,
parser: JsonParser,
}
}

Expand Down Expand Up @@ -53,9 +52,9 @@ impl YamlNoteRepository {
fs::create_dir_all(parent)?;
}

let yaml = self.parser.serialize(note_file)?;
let json = self.parser.serialize(note_file)?;

fs::write(note_path, yaml)?;
fs::write(note_path, json)?;
Comment on lines +56 to +58

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Add a legacy-note migration/fallback path before fully switching writes to JSON.

On Line 56 and Line 58, writes are JSON-only. Combined with JSON path resolution/loading, existing .yml note files become unreadable after upgrade (reads resolve missing .json and fall back to empty/default), which effectively hides previously persisted notes.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/frilvault-core/src/storage/repository.rs` around lines 56 - 58, The
current implementation only writes to JSON format without handling the migration
of existing legacy .yml note files, causing them to become inaccessible after
upgrade. Before the write operation in the serialize and fs::write calls,
implement a migration or fallback mechanism that detects existing .yml files and
converts them to the new JSON format. Alternatively, ensure the read path checks
for and loads from existing .yml files if the corresponding .json file doesn't
exist, preserving backward compatibility during the transition period before
fully switching to JSON-only storage.


Ok(())
}
Expand Down
Loading