jrnl-mcp
Version:
Model Context Protocol server for jrnl CLI journal application
60 lines (59 loc) • 2.27 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.listTags = listTags;
exports.analyzeTagCooccurrence = analyzeTagCooccurrence;
const commandBuilder_1 = require("../utils/commandBuilder");
async function listTags(journal, executor) {
const command = (0, commandBuilder_1.buildTagCommand)(journal);
const result = await executor.execute(command);
try {
// Parse plain text format: "@tag : count"
const tags = {};
const lines = result.trim().split("\n");
for (const line of lines) {
const match = line.match(/^(@\w+)\s*:\s*(\d+)$/);
if (match) {
const [, tag, count] = match;
tags[tag] = parseInt(count, 10);
}
}
return { tags };
}
catch (error) {
throw new Error(`Failed to parse jrnl tags output: ${error}`);
}
}
async function analyzeTagCooccurrence(tags, journal, executor) {
if (tags.length < 2) {
return { cooccurrences: [] };
}
// For each pair of tags, find entries that contain both
const cooccurrences = [];
for (let i = 0; i < tags.length - 1; i++) {
for (let j = i + 1; j < tags.length; j++) {
const tag1 = tags[i];
const tag2 = tags[j];
// Search for entries with both tags
const command = (0, commandBuilder_1.buildSearchCommand)({ tags: [tag1, tag2] }, journal);
const result = await executor.execute(command);
try {
const data = JSON.parse(result);
const count = data.entries ? data.entries.length : 0;
if (count > 0) {
cooccurrences.push({
tag1: tag1.startsWith("@") ? tag1 : `@${tag1}`,
tag2: tag2.startsWith("@") ? tag2 : `@${tag2}`,
count,
});
}
}
catch (error) {
// Skip this pair if there's an error
// console.error(`Error analyzing cooccurrence for ${tag1} and ${tag2}: ${error}`);
}
}
}
// Sort by count descending
cooccurrences.sort((a, b) => b.count - a.count);
return { cooccurrences };
}