Skip to content

Commit 8fc9eb2

Browse files
committed
feat: refined rendering note metadata to markdown
Now include full paths
1 parent 615e4c5 commit 8fc9eb2

4 files changed

Lines changed: 122 additions & 42 deletions

File tree

src/agent-render.test.ts

Lines changed: 70 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,27 +13,30 @@ describe("agent-render", () => {
1313
path: "one/two/Test Note.md",
1414
parentPath: "one/two",
1515
content: "This is the content of the note.",
16-
links: ["Link1", "Link2", "Bidirectional"],
17-
backlinks: ["Backlink1", "Bidirectional"],
16+
links: ["other/Link1", "one/two/Link2", "one/two/Bidirectional"],
17+
backlinks: ["one/two/Backlink1", "one/two/Bidirectional"],
1818
tags: ["#tag1", "#tag2"],
1919
folderSiblings: ["Sibling1"],
2020
};
2121

2222
const result = renderNoteToMarkdown(note);
2323

24-
const expected = `## Note [[Test Note]]
25-
### Note metadata
24+
const expected = `# Test Note
25+
## Metadata
2626
\`\`\`yaml
27-
path: one/two/Test Note.md
27+
path: one/two/Test Note
2828
bidirectional_links:
29-
- [[Bidirectional]]
29+
- one/two/Bidirectional
3030
links:
31-
- [[Link1]]
32-
- [[Link2]]
31+
- other/Link1
32+
- one/two/Link2
3333
backlinks:
34-
- [[Backlink1]]
34+
- one/two/Backlink1
35+
tags:
36+
- #tag1
37+
- #tag2
3538
\`\`\`
36-
### Content
39+
## Content
3740
\`\`\`
3841
This is the content of the note.
3942
\`\`\`
@@ -45,6 +48,7 @@ This is the content of the note.
4548
const note: Note = {
4649
filename: "Structured Note",
4750
path: "one/two/three/Structured Note.md",
51+
parentPath: "one/two/three",
4852
content: null,
4953
structure: `
5054
# Header 1
@@ -57,17 +61,17 @@ This is the content of the note.
5761
};
5862

5963
const result = renderNoteToMarkdown(note);
60-
61-
const expected = `## Note [[Structured Note]]
62-
### Note metadata
64+
const expected = `# Structured Note
65+
## Metadata
6366
\`\`\`yaml
64-
path: one/two/three/Structured Note.md
67+
path: one/two/three/Structured Note
6568
bidirectional_links:
6669
links:
6770
backlinks:
71+
tags:
6872
\`\`\`
6973
70-
### Structure
74+
## Structure
7175
\`\`\`
7276
# Header 1
7377
## Header 2
@@ -80,6 +84,7 @@ backlinks:
8084
const note: Note = {
8185
filename: "Empty Note",
8286
path: "Deep/Path/To/Empty Note.md",
87+
parentPath: "Deep/Path/To",
8388
content: "Empty",
8489
links: [],
8590
backlinks: [],
@@ -88,15 +93,16 @@ backlinks:
8893
};
8994

9095
const result = renderNoteToMarkdown(note);
91-
const expected = `## Note [[Empty Note]]
92-
### Note metadata
96+
const expected = `# Empty Note
97+
## Metadata
9398
\`\`\`yaml
94-
path: Deep/Path/To/Empty Note.md
99+
path: Deep/Path/To/Empty Note
95100
bidirectional_links:
96101
links:
97102
backlinks:
103+
tags:
98104
\`\`\`
99-
### Content
105+
## Content
100106
\`\`\`
101107
Empty
102108
\`\`\`
@@ -108,6 +114,7 @@ Empty
108114
const note: Note = {
109115
filename: "Meta Only Note",
110116
path: "Meta Only Note.md",
117+
parentPath: "/",
111118
content: null,
112119
structure: null,
113120
links: [],
@@ -117,20 +124,57 @@ Empty
117124
};
118125

119126
const result = renderNoteToMarkdown(note);
120-
const expected = `## Note [[Meta Only Note]]
121-
### Note metadata
127+
const expected = `# Meta Only Note
128+
## Metadata
122129
\`\`\`yaml
123-
path: Meta Only Note.md
130+
path: Meta Only Note
124131
bidirectional_links:
125132
links:
126133
backlinks:
134+
tags:
127135
\`\`\`
128136
129137
Only note metadata is available. Use tools to read the note text or note structure.
138+
`;
139+
expect(result).toBe(expected);
140+
});
141+
142+
it("should render frontmatter properties in metadata", () => {
143+
const note: Note = {
144+
filename: "FM Note",
145+
path: "FM Note.md",
146+
parentPath: "/",
147+
content: "Hello",
148+
links: [],
149+
backlinks: [],
150+
tags: ["#test"],
151+
frontmatter: { status: "draft", priority: 1 },
152+
folderSiblings: [],
153+
};
154+
155+
const result = renderNoteToMarkdown(note);
156+
const expected = `# FM Note
157+
## Metadata
158+
\`\`\`yaml
159+
path: FM Note
160+
bidirectional_links:
161+
links:
162+
backlinks:
163+
tags:
164+
- #test
165+
properties:
166+
status: "draft"
167+
priority: 1
168+
\`\`\`
169+
## Content
170+
\`\`\`
171+
Hello
172+
\`\`\`
130173
`;
131174
expect(result).toBe(expected);
132175
});
133176
});
177+
134178
describe("renderDiscoveredStructure", () => {
135179
it("should return a message when no paths are provided", () => {
136180
expect(renderDiscoveredStructure([])).toBe(
@@ -142,12 +186,10 @@ Only note metadata is available. Use tools to read the note text or note structu
142186
const paths = ["folder/sub/note1.md", "folder/sub/note2.md"];
143187
const result = renderDiscoveredStructure(paths);
144188
expect(result).toBe(
145-
`
146-
- 📁 folder
189+
`- 📁 folder
147190
- 📁 sub
148191
- 📄 note1.md
149-
- 📄 note2.md
150-
`.trim(),
192+
- 📄 note2.md`,
151193
);
152194
});
153195

@@ -175,12 +217,10 @@ Only note metadata is available. Use tools to read the note text or note structu
175217
const paths = ["b.md", "a.md", "c/d.md"];
176218
const result = renderDiscoveredStructure(paths);
177219
expect(result).toBe(
178-
`
179-
- 📄 a.md
220+
`- 📄 a.md
180221
- 📄 b.md
181222
- 📁 c
182-
- 📄 d.md
183-
`.trim(),
223+
- 📄 d.md`,
184224
);
185225
});
186226
});

src/agent-render.ts

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,18 +90,18 @@ export function renderDiscoveredStructure(paths: readonly string[]): string {
9090
* (LLM-facing) rather than note manipulation.
9191
*/
9292
export function renderNoteToMarkdown(note: Note): string {
93-
let noteHeader = `[[${note.filename}]]`;
93+
let noteHeader = note.filename;
9494
if (
9595
note.state?.originalFilename &&
9696
note.state.originalFilename !== note.filename
9797
) {
9898
noteHeader = `${note.filename} (renamed from ${note.state.originalFilename})`;
9999
}
100-
let noteMd = `## Note ${noteHeader}\n`;
100+
let noteMd = `# ${noteHeader}\n`;
101101

102-
noteMd += "### Note metadata\n";
102+
noteMd += "## Metadata\n";
103103
noteMd += "```yaml\n";
104-
noteMd += `path: ${note.path}\n`;
104+
noteMd += `path: ${note.path.replace(/\.md$/, "")}\n`;
105105
const links = note.links || [];
106106
const backlinks = note.backlinks || [];
107107

@@ -113,36 +113,50 @@ export function renderNoteToMarkdown(note: Note): string {
113113

114114
noteMd += "bidirectional_links:\n";
115115
for (const l of bidirectionalLinks) {
116-
noteMd += ` - [[${l}]]\n`;
116+
noteMd += ` - ${l}\n`;
117117
}
118118

119119
noteMd += "links:\n";
120120
for (const l of uniqueLinks) {
121-
noteMd += ` - [[${l}]]\n`;
121+
noteMd += ` - ${l}\n`;
122122
}
123123

124124
noteMd += "backlinks:\n";
125125
for (const b of uniqueBacklinks) {
126-
noteMd += ` - [[${b}]]\n`;
126+
noteMd += ` - ${b}\n`;
127127
}
128+
129+
const tags = note.tags || [];
130+
noteMd += "tags:\n";
131+
for (const t of tags) {
132+
noteMd += ` - ${t}\n`;
133+
}
134+
135+
if (note.frontmatter && Object.keys(note.frontmatter).length > 0) {
136+
noteMd += "properties:\n";
137+
for (const [key, value] of Object.entries(note.frontmatter)) {
138+
noteMd += ` ${key}: ${JSON.stringify(value)}\n`;
139+
}
140+
}
141+
128142
noteMd += "```\n";
129143

130144
const highlight = note.state?.highlight;
131145
if (highlight && highlight.trim().length > 0) {
132146
noteMd +=
133-
"### Highlighted text (subset of the note)\n" +
147+
"## Highlighted text (subset of the note)\n" +
134148
"The user highlighted this exact excerpt. Prefer acting on this section; any edits/suggestions should apply within it.\n" +
135149
"```\n";
136150
noteMd += highlight.trim();
137151
noteMd += "\n```\n";
138152
}
139153

140154
if (note.content) {
141-
noteMd += "### Content\n```\n";
155+
noteMd += "## Content\n```\n";
142156
noteMd += note.content.trim();
143157
noteMd += "\n```\n";
144158
} else if (note.structure) {
145-
noteMd += "\n### Structure\n```\n";
159+
noteMd += "\n## Structure\n```\n";
146160
noteMd += note.structure.trim();
147161
noteMd += "\n```\n";
148162
} else {

src/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ export interface Note {
243243
links: string[];
244244
backlinks: string[];
245245
tags: string[];
246+
frontmatter?: Record<string, unknown> | null;
246247
parentPath?: string;
247248
folderSiblings?: string[] | null;
248249
state?: {

src/utils/read-note.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,17 @@ export async function readNote(
1919
const cache = app.metadataCache.getFileCache(file);
2020
if (cache?.links) {
2121
for (const link of cache.links) {
22-
links.push(link.link);
22+
const dest = app.metadataCache.getFirstLinkpathDest(link.link, file.path);
23+
if (dest) {
24+
const parentPath = dest.parent?.path;
25+
const displayPath =
26+
parentPath && parentPath !== "/" && parentPath !== ""
27+
? `${parentPath}/${dest.basename}`
28+
: dest.basename;
29+
links.push(displayPath);
30+
} else {
31+
links.push(link.link);
32+
}
2333
}
2434
}
2535

@@ -51,7 +61,12 @@ export async function readNote(
5161
if (targets[file.path]) {
5262
const sourceFile = app.vault.getAbstractFileByPath(sourcePath);
5363
if (sourceFile instanceof TFile) {
54-
backlinks.push(sourceFile.basename);
64+
const parentPath = sourceFile.parent?.path;
65+
const displayPath =
66+
parentPath && parentPath !== "/" && parentPath !== ""
67+
? `${parentPath}/${sourceFile.basename}`
68+
: sourceFile.basename;
69+
backlinks.push(displayPath);
5570
}
5671
}
5772
}
@@ -88,6 +103,15 @@ export async function readNote(
88103
.map((child) => (child as TFile).basename);
89104
}
90105

106+
// Extract frontmatter properties (excluding internal keys and tags, which are handled separately)
107+
let frontmatter: Record<string, unknown> | null = null;
108+
if (cache?.frontmatter) {
109+
const { position, tags: _tags, ...rest } = cache.frontmatter;
110+
if (Object.keys(rest).length > 0) {
111+
frontmatter = rest;
112+
}
113+
}
114+
91115
const structureOrText = detail === "structure" || detail === "text";
92116
return {
93117
filename: filename,
@@ -96,6 +120,7 @@ export async function readNote(
96120
links: [...new Set(links)],
97121
backlinks: [...new Set(backlinks)],
98122
tags: [...new Set(tags)],
123+
frontmatter,
99124
structure: structureOrText ? structure.join("\n") : null,
100125
parentPath: parentFolder?.path || "/",
101126
folderSiblings: structureOrText ? folderSiblings : null,

0 commit comments

Comments
 (0)