@avadisabelle/ava-diary 0.1.0 → 0.62.0
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/dist/diary-reader.d.ts.map +1 -1
- package/dist/diary-reader.js.map +1 -1
- package/dist/diary-writer.d.ts.map +1 -1
- package/dist/diary-writer.js +3 -3
- package/dist/diary-writer.js.map +1 -1
- package/dist/four-directions.d.ts.map +1 -1
- package/dist/four-directions.js +1 -6
- package/dist/four-directions.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diary-reader.d.ts","sourceRoot":"","sources":["../src/diary-reader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"diary-reader.d.ts","sourceRoot":"","sources":["../src/diary-reader.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAiB,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAqExF;;GAEG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAkBlE;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAYxD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,eAAe,EAAE,CAyCtF;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,eAAe,GAAG,IAAI,CAMrG;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,GAAG,MAAM,GAAG,IAAI,CA+BxF","sourcesContent":["/**\n * @avadisabelle/ava-diary — Diary Reader\n *\n * Reads, lists, searches, and retrieves diary entries from the filesystem.\n * Returns structured results from the living Four Directions archive.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { parseDirectionFromHeading } from \"./four-directions.js\";\nimport type { DiaryMetadata, DiaryQuery, DiaryReadResult, Direction } from \"./types.js\";\n\n/**\n * Parse metadata from the header section of a diary markdown file.\n * Best-effort — returns whatever fields can be extracted.\n */\nfunction parseMetadata(raw: string): Partial<DiaryMetadata> {\n\tconst meta: Partial<DiaryMetadata> = {};\n\n\t// Title: \"# 💕 Diary: <title>\"\n\tconst titleMatch = raw.match(/^#\\s+💕\\s*Diary:\\s*(.+)$/m);\n\tif (titleMatch) {\n\t\tmeta.title = titleMatch[1].trim();\n\t}\n\n\t// Date: \"**Date**: <date>\"\n\tconst dateMatch = raw.match(/\\*\\*Date\\*\\*:\\s*(.+)$/m);\n\tif (dateMatch) {\n\t\tmeta.date = dateMatch[1].trim();\n\t}\n\n\t// Session: \"**Session**: <id>\"\n\tconst sessionMatch = raw.match(/\\*\\*Session\\*\\*:\\s*(.+)$/m);\n\tif (sessionMatch) {\n\t\tmeta.sessionId = sessionMatch[1].trim();\n\t}\n\n\t// Trace: \"**Trace**: <id>\"\n\tconst traceMatch = raw.match(/\\*\\*Trace\\*\\*:\\s*(.+)$/m);\n\tif (traceMatch) {\n\t\tmeta.traceId = traceMatch[1].trim();\n\t}\n\n\t// Project: \"**Project**: <path>\"\n\tconst projectMatch = raw.match(/\\*\\*Project\\*\\*:\\s*(.+)$/m);\n\tif (projectMatch) {\n\t\tmeta.project = projectMatch[1].trim();\n\t}\n\n\t// Tags: \"**Tags**: tag1, tag2, tag3\"\n\tconst tagsMatch = raw.match(/\\*\\*Tags\\*\\*:\\s*(.+)$/m);\n\tif (tagsMatch) {\n\t\tmeta.tags = tagsMatch[1].split(\",\").map((t) => t.trim());\n\t}\n\n\treturn meta;\n}\n\n/**\n * Check whether a diary entry's date falls within a range.\n */\nfunction dateInRange(date: string | undefined, from?: string, to?: string): boolean {\n\tif (!date) return true;\n\t// Normalize to YYYY-MM-DD for comparison\n\tconst d = date.slice(0, 10);\n\tif (from && d < from.slice(0, 10)) return false;\n\tif (to && d > to.slice(0, 10)) return false;\n\treturn true;\n}\n\n/**\n * Check whether raw content contains a direction heading.\n */\nfunction hasDirection(raw: string, direction: Direction): boolean {\n\tconst lower = raw.toLowerCase();\n\t// Look for \"## 🌅 EAST\" or similar patterns\n\treturn lower.includes(`## `) && lower.includes(direction);\n}\n\n/**\n * Read a single diary file and return a structured result.\n */\nexport function readDiary(filepath: string): DiaryReadResult | null {\n\ttry {\n\t\tif (!fs.existsSync(filepath)) return null;\n\n\t\tconst raw = fs.readFileSync(filepath, \"utf8\");\n\t\tconst metadata = parseMetadata(raw);\n\t\tconst filename = path.basename(filepath);\n\n\t\treturn {\n\t\t\tfilepath,\n\t\t\tfilename,\n\t\t\traw,\n\t\t\tmetadata,\n\t\t\tparsed: !!metadata.title && !!metadata.date,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * List diary files in a directory, sorted most-recent-first.\n *\n * @returns Array of filenames (not full paths)\n */\nexport function listDiaries(diariesDir: string): string[] {\n\ttry {\n\t\tif (!fs.existsSync(diariesDir)) return [];\n\n\t\treturn fs\n\t\t\t.readdirSync(diariesDir)\n\t\t\t.filter((f) => f.endsWith(\".md\"))\n\t\t\t.sort()\n\t\t\t.reverse();\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Search diaries with structured query filters.\n *\n * Supports date range, direction presence, full-text search, and tag filtering.\n */\nexport function searchDiaries(diariesDir: string, query: DiaryQuery): DiaryReadResult[] {\n\tconst filenames = listDiaries(diariesDir);\n\tconst results: DiaryReadResult[] = [];\n\tconst limit = query.limit ?? 50;\n\n\tfor (const filename of filenames) {\n\t\tif (results.length >= limit) break;\n\n\t\tconst filepath = path.join(diariesDir, filename);\n\t\tconst result = readDiary(filepath);\n\t\tif (!result) continue;\n\n\t\t// Date range filter\n\t\tif (!dateInRange(result.metadata.date, query.fromDate, query.toDate)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Direction filter\n\t\tif (query.direction && !hasDirection(result.raw, query.direction)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Full-text search\n\t\tif (query.search) {\n\t\t\tconst searchLower = query.search.toLowerCase();\n\t\t\tif (!result.raw.toLowerCase().includes(searchLower)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Tag filter\n\t\tif (query.tags && query.tags.length > 0) {\n\t\t\tconst entryTags = result.metadata.tags ?? [];\n\t\t\tconst hasMatchingTag = query.tags.some((t) => entryTags.includes(t));\n\t\t\tif (!hasMatchingTag) continue;\n\t\t}\n\n\t\tresults.push(result);\n\t}\n\n\treturn results;\n}\n\n/**\n * Get the most recent diary entry that contains content for a given direction.\n */\nexport function getLatestByDirection(diariesDir: string, direction: Direction): DiaryReadResult | null {\n\tconst results = searchDiaries(diariesDir, {\n\t\tdirection,\n\t\tlimit: 1,\n\t});\n\treturn results[0] ?? null;\n}\n\n/**\n * Extract the body text for a specific direction from raw diary content.\n *\n * Finds the direction heading and returns all content until the next\n * section separator (---) or the next direction heading.\n */\nexport function extractDirectionContent(raw: string, direction: Direction): string | null {\n\tconst lines = raw.split(\"\\n\");\n\tlet capturing = false;\n\tconst captured: string[] = [];\n\n\tfor (const line of lines) {\n\t\tif (line.startsWith(\"## \")) {\n\t\t\tconst parsed = parseDirectionFromHeading(line);\n\t\t\tif (parsed === direction) {\n\t\t\t\tcapturing = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (capturing && parsed !== undefined) {\n\t\t\t\t// Hit the next direction — stop\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (capturing) {\n\t\t\tif (line.trim() === \"---\") break;\n\t\t\tcaptured.push(line);\n\t\t}\n\t}\n\n\tif (captured.length === 0) return null;\n\n\t// Trim leading/trailing empty lines\n\twhile (captured.length > 0 && captured[0].trim() === \"\") captured.shift();\n\twhile (captured.length > 0 && captured[captured.length - 1].trim() === \"\") captured.pop();\n\n\treturn captured.join(\"\\n\") || null;\n}\n"]}
|
package/dist/diary-reader.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diary-reader.js","sourceRoot":"","sources":["../src/diary-reader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @avadisabelle/ava-diary — Diary Reader\n *\n * Reads, lists, searches, and retrieves diary entries from the filesystem.\n * Returns structured results from the living Four Directions archive.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type {\n\tDiaryMetadata,\n\tDiaryQuery,\n\tDiaryReadResult,\n\tDirection,\n} from \"./types.js\";\nimport { DIRECTIONS, parseDirectionFromHeading } from \"./four-directions.js\";\n\n/**\n * Parse metadata from the header section of a diary markdown file.\n * Best-effort — returns whatever fields can be extracted.\n */\nfunction parseMetadata(raw: string): Partial<DiaryMetadata> {\n\tconst meta: Partial<DiaryMetadata> = {};\n\n\t// Title: \"# 💕 Diary: <title>\"\n\tconst titleMatch = raw.match(/^#\\s+💕\\s*Diary:\\s*(.+)$/m);\n\tif (titleMatch) {\n\t\tmeta.title = titleMatch[1].trim();\n\t}\n\n\t// Date: \"**Date**: <date>\"\n\tconst dateMatch = raw.match(/\\*\\*Date\\*\\*:\\s*(.+)$/m);\n\tif (dateMatch) {\n\t\tmeta.date = dateMatch[1].trim();\n\t}\n\n\t// Session: \"**Session**: <id>\"\n\tconst sessionMatch = raw.match(/\\*\\*Session\\*\\*:\\s*(.+)$/m);\n\tif (sessionMatch) {\n\t\tmeta.sessionId = sessionMatch[1].trim();\n\t}\n\n\t// Trace: \"**Trace**: <id>\"\n\tconst traceMatch = raw.match(/\\*\\*Trace\\*\\*:\\s*(.+)$/m);\n\tif (traceMatch) {\n\t\tmeta.traceId = traceMatch[1].trim();\n\t}\n\n\t// Project: \"**Project**: <path>\"\n\tconst projectMatch = raw.match(/\\*\\*Project\\*\\*:\\s*(.+)$/m);\n\tif (projectMatch) {\n\t\tmeta.project = projectMatch[1].trim();\n\t}\n\n\t// Tags: \"**Tags**: tag1, tag2, tag3\"\n\tconst tagsMatch = raw.match(/\\*\\*Tags\\*\\*:\\s*(.+)$/m);\n\tif (tagsMatch) {\n\t\tmeta.tags = tagsMatch[1].split(\",\").map((t) => t.trim());\n\t}\n\n\treturn meta;\n}\n\n/**\n * Check whether a diary entry's date falls within a range.\n */\nfunction dateInRange(\n\tdate: string | undefined,\n\tfrom?: string,\n\tto?: string,\n): boolean {\n\tif (!date) return true;\n\t// Normalize to YYYY-MM-DD for comparison\n\tconst d = date.slice(0, 10);\n\tif (from && d < from.slice(0, 10)) return false;\n\tif (to && d > to.slice(0, 10)) return false;\n\treturn true;\n}\n\n/**\n * Check whether raw content contains a direction heading.\n */\nfunction hasDirection(raw: string, direction: Direction): boolean {\n\tconst lower = raw.toLowerCase();\n\t// Look for \"## 🌅 EAST\" or similar patterns\n\treturn lower.includes(`## `) && lower.includes(direction);\n}\n\n/**\n * Read a single diary file and return a structured result.\n */\nexport function readDiary(filepath: string): DiaryReadResult | null {\n\ttry {\n\t\tif (!fs.existsSync(filepath)) return null;\n\n\t\tconst raw = fs.readFileSync(filepath, \"utf8\");\n\t\tconst metadata = parseMetadata(raw);\n\t\tconst filename = path.basename(filepath);\n\n\t\treturn {\n\t\t\tfilepath,\n\t\t\tfilename,\n\t\t\traw,\n\t\t\tmetadata,\n\t\t\tparsed: !!metadata.title && !!metadata.date,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * List diary files in a directory, sorted most-recent-first.\n *\n * @returns Array of filenames (not full paths)\n */\nexport function listDiaries(diariesDir: string): string[] {\n\ttry {\n\t\tif (!fs.existsSync(diariesDir)) return [];\n\n\t\treturn fs\n\t\t\t.readdirSync(diariesDir)\n\t\t\t.filter((f) => f.endsWith(\".md\"))\n\t\t\t.sort()\n\t\t\t.reverse();\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Search diaries with structured query filters.\n *\n * Supports date range, direction presence, full-text search, and tag filtering.\n */\nexport function searchDiaries(\n\tdiariesDir: string,\n\tquery: DiaryQuery,\n): DiaryReadResult[] {\n\tconst filenames = listDiaries(diariesDir);\n\tconst results: DiaryReadResult[] = [];\n\tconst limit = query.limit ?? 50;\n\n\tfor (const filename of filenames) {\n\t\tif (results.length >= limit) break;\n\n\t\tconst filepath = path.join(diariesDir, filename);\n\t\tconst result = readDiary(filepath);\n\t\tif (!result) continue;\n\n\t\t// Date range filter\n\t\tif (!dateInRange(result.metadata.date, query.fromDate, query.toDate)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Direction filter\n\t\tif (query.direction && !hasDirection(result.raw, query.direction)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Full-text search\n\t\tif (query.search) {\n\t\t\tconst searchLower = query.search.toLowerCase();\n\t\t\tif (!result.raw.toLowerCase().includes(searchLower)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Tag filter\n\t\tif (query.tags && query.tags.length > 0) {\n\t\t\tconst entryTags = result.metadata.tags ?? [];\n\t\t\tconst hasMatchingTag = query.tags.some((t) =>\n\t\t\t\tentryTags.includes(t),\n\t\t\t);\n\t\t\tif (!hasMatchingTag) continue;\n\t\t}\n\n\t\tresults.push(result);\n\t}\n\n\treturn results;\n}\n\n/**\n * Get the most recent diary entry that contains content for a given direction.\n */\nexport function getLatestByDirection(\n\tdiariesDir: string,\n\tdirection: Direction,\n): DiaryReadResult | null {\n\tconst results = searchDiaries(diariesDir, {\n\t\tdirection,\n\t\tlimit: 1,\n\t});\n\treturn results[0] ?? null;\n}\n\n/**\n * Extract the body text for a specific direction from raw diary content.\n *\n * Finds the direction heading and returns all content until the next\n * section separator (---) or the next direction heading.\n */\nexport function extractDirectionContent(\n\traw: string,\n\tdirection: Direction,\n): string | null {\n\tconst lines = raw.split(\"\\n\");\n\tlet capturing = false;\n\tconst captured: string[] = [];\n\n\tfor (const line of lines) {\n\t\tif (line.startsWith(\"## \")) {\n\t\t\tconst parsed = parseDirectionFromHeading(line);\n\t\t\tif (parsed === direction) {\n\t\t\t\tcapturing = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (capturing && parsed !== undefined) {\n\t\t\t\t// Hit the next direction — stop\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (capturing) {\n\t\t\tif (line.trim() === \"---\") break;\n\t\t\tcaptured.push(line);\n\t\t}\n\t}\n\n\tif (captured.length === 0) return null;\n\n\t// Trim leading/trailing empty lines\n\twhile (captured.length > 0 && captured[0].trim() === \"\") captured.shift();\n\twhile (captured.length > 0 && captured[captured.length - 1].trim() === \"\")\n\t\tcaptured.pop();\n\n\treturn captured.join(\"\\n\") || null;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"diary-reader.js","sourceRoot":"","sources":["../src/diary-reader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @avadisabelle/ava-diary — Diary Reader\n *\n * Reads, lists, searches, and retrieves diary entries from the filesystem.\n * Returns structured results from the living Four Directions archive.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { parseDirectionFromHeading } from \"./four-directions.js\";\nimport type { DiaryMetadata, DiaryQuery, DiaryReadResult, Direction } from \"./types.js\";\n\n/**\n * Parse metadata from the header section of a diary markdown file.\n * Best-effort — returns whatever fields can be extracted.\n */\nfunction parseMetadata(raw: string): Partial<DiaryMetadata> {\n\tconst meta: Partial<DiaryMetadata> = {};\n\n\t// Title: \"# 💕 Diary: <title>\"\n\tconst titleMatch = raw.match(/^#\\s+💕\\s*Diary:\\s*(.+)$/m);\n\tif (titleMatch) {\n\t\tmeta.title = titleMatch[1].trim();\n\t}\n\n\t// Date: \"**Date**: <date>\"\n\tconst dateMatch = raw.match(/\\*\\*Date\\*\\*:\\s*(.+)$/m);\n\tif (dateMatch) {\n\t\tmeta.date = dateMatch[1].trim();\n\t}\n\n\t// Session: \"**Session**: <id>\"\n\tconst sessionMatch = raw.match(/\\*\\*Session\\*\\*:\\s*(.+)$/m);\n\tif (sessionMatch) {\n\t\tmeta.sessionId = sessionMatch[1].trim();\n\t}\n\n\t// Trace: \"**Trace**: <id>\"\n\tconst traceMatch = raw.match(/\\*\\*Trace\\*\\*:\\s*(.+)$/m);\n\tif (traceMatch) {\n\t\tmeta.traceId = traceMatch[1].trim();\n\t}\n\n\t// Project: \"**Project**: <path>\"\n\tconst projectMatch = raw.match(/\\*\\*Project\\*\\*:\\s*(.+)$/m);\n\tif (projectMatch) {\n\t\tmeta.project = projectMatch[1].trim();\n\t}\n\n\t// Tags: \"**Tags**: tag1, tag2, tag3\"\n\tconst tagsMatch = raw.match(/\\*\\*Tags\\*\\*:\\s*(.+)$/m);\n\tif (tagsMatch) {\n\t\tmeta.tags = tagsMatch[1].split(\",\").map((t) => t.trim());\n\t}\n\n\treturn meta;\n}\n\n/**\n * Check whether a diary entry's date falls within a range.\n */\nfunction dateInRange(date: string | undefined, from?: string, to?: string): boolean {\n\tif (!date) return true;\n\t// Normalize to YYYY-MM-DD for comparison\n\tconst d = date.slice(0, 10);\n\tif (from && d < from.slice(0, 10)) return false;\n\tif (to && d > to.slice(0, 10)) return false;\n\treturn true;\n}\n\n/**\n * Check whether raw content contains a direction heading.\n */\nfunction hasDirection(raw: string, direction: Direction): boolean {\n\tconst lower = raw.toLowerCase();\n\t// Look for \"## 🌅 EAST\" or similar patterns\n\treturn lower.includes(`## `) && lower.includes(direction);\n}\n\n/**\n * Read a single diary file and return a structured result.\n */\nexport function readDiary(filepath: string): DiaryReadResult | null {\n\ttry {\n\t\tif (!fs.existsSync(filepath)) return null;\n\n\t\tconst raw = fs.readFileSync(filepath, \"utf8\");\n\t\tconst metadata = parseMetadata(raw);\n\t\tconst filename = path.basename(filepath);\n\n\t\treturn {\n\t\t\tfilepath,\n\t\t\tfilename,\n\t\t\traw,\n\t\t\tmetadata,\n\t\t\tparsed: !!metadata.title && !!metadata.date,\n\t\t};\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * List diary files in a directory, sorted most-recent-first.\n *\n * @returns Array of filenames (not full paths)\n */\nexport function listDiaries(diariesDir: string): string[] {\n\ttry {\n\t\tif (!fs.existsSync(diariesDir)) return [];\n\n\t\treturn fs\n\t\t\t.readdirSync(diariesDir)\n\t\t\t.filter((f) => f.endsWith(\".md\"))\n\t\t\t.sort()\n\t\t\t.reverse();\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n/**\n * Search diaries with structured query filters.\n *\n * Supports date range, direction presence, full-text search, and tag filtering.\n */\nexport function searchDiaries(diariesDir: string, query: DiaryQuery): DiaryReadResult[] {\n\tconst filenames = listDiaries(diariesDir);\n\tconst results: DiaryReadResult[] = [];\n\tconst limit = query.limit ?? 50;\n\n\tfor (const filename of filenames) {\n\t\tif (results.length >= limit) break;\n\n\t\tconst filepath = path.join(diariesDir, filename);\n\t\tconst result = readDiary(filepath);\n\t\tif (!result) continue;\n\n\t\t// Date range filter\n\t\tif (!dateInRange(result.metadata.date, query.fromDate, query.toDate)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Direction filter\n\t\tif (query.direction && !hasDirection(result.raw, query.direction)) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Full-text search\n\t\tif (query.search) {\n\t\t\tconst searchLower = query.search.toLowerCase();\n\t\t\tif (!result.raw.toLowerCase().includes(searchLower)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\n\t\t// Tag filter\n\t\tif (query.tags && query.tags.length > 0) {\n\t\t\tconst entryTags = result.metadata.tags ?? [];\n\t\t\tconst hasMatchingTag = query.tags.some((t) => entryTags.includes(t));\n\t\t\tif (!hasMatchingTag) continue;\n\t\t}\n\n\t\tresults.push(result);\n\t}\n\n\treturn results;\n}\n\n/**\n * Get the most recent diary entry that contains content for a given direction.\n */\nexport function getLatestByDirection(diariesDir: string, direction: Direction): DiaryReadResult | null {\n\tconst results = searchDiaries(diariesDir, {\n\t\tdirection,\n\t\tlimit: 1,\n\t});\n\treturn results[0] ?? null;\n}\n\n/**\n * Extract the body text for a specific direction from raw diary content.\n *\n * Finds the direction heading and returns all content until the next\n * section separator (---) or the next direction heading.\n */\nexport function extractDirectionContent(raw: string, direction: Direction): string | null {\n\tconst lines = raw.split(\"\\n\");\n\tlet capturing = false;\n\tconst captured: string[] = [];\n\n\tfor (const line of lines) {\n\t\tif (line.startsWith(\"## \")) {\n\t\t\tconst parsed = parseDirectionFromHeading(line);\n\t\t\tif (parsed === direction) {\n\t\t\t\tcapturing = true;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (capturing && parsed !== undefined) {\n\t\t\t\t// Hit the next direction — stop\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (capturing) {\n\t\t\tif (line.trim() === \"---\") break;\n\t\t\tcaptured.push(line);\n\t\t}\n\t}\n\n\tif (captured.length === 0) return null;\n\n\t// Trim leading/trailing empty lines\n\twhile (captured.length > 0 && captured[0].trim() === \"\") captured.shift();\n\twhile (captured.length > 0 && captured[captured.length - 1].trim() === \"\") captured.pop();\n\n\treturn captured.join(\"\\n\") || null;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diary-writer.d.ts","sourceRoot":"","sources":["../src/diary-writer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;
|
|
1
|
+
{"version":3,"file":"diary-writer.d.ts","sourceRoot":"","sources":["../src/diary-writer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,iBAAiB,EAAoB,MAAM,YAAY,CAAC;AAEjG;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,aAAa,GAAG,MAAM,CAQhE;AAuBD,gDAAgD;AAChD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,MAAM,CAkC1D;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,iBAAiB,GAAG,MAAM,GAAG,IAAI,CAe7F;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAChC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,EAC1C,OAAO,EAAE,MAAM,GACb,OAAO,CA4BT;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CACzB,QAAQ,EAAE,aAAa,EACvB,UAAU,EAAE;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACd,EACD,OAAO,CAAC,EAAE,MAAM,GACd,UAAU,CAkBZ","sourcesContent":["/**\n * @avadisabelle/ava-diary — Diary Writer\n *\n * Transforms DiaryEntry into living markdown files.\n * Each file is a Four Directions ceremony captured in text.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { DIRECTION_SETTLING, DIRECTIONS, directionHeading, renderDirection } from \"./four-directions.js\";\nimport type { DiaryEntry, DiaryMetadata, DiaryWriteOptions, DirectionContent } from \"./types.js\";\n\n/**\n * Generate a diary filename from metadata.\n * Format: YYYY-MM-DD_topic_slug.md\n */\nexport function generateFilename(metadata: DiaryMetadata): string {\n\tconst date = metadata.date || new Date().toISOString().slice(0, 10);\n\tconst slug = metadata.title\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9]+/g, \"_\")\n\t\t.replace(/^_|_$/g, \"\")\n\t\t.slice(0, 50);\n\treturn `${date}_${slug}.md`;\n}\n\n/** Render diary metadata as markdown frontmatter */\nfunction renderMetadata(metadata: DiaryMetadata): string {\n\tconst lines: string[] = [];\n\tlines.push(`# 💕 Diary: ${metadata.title}`);\n\tlines.push(\"\");\n\tlines.push(`**Date**: ${metadata.date}`);\n\tif (metadata.sessionId) {\n\t\tlines.push(`**Session**: ${metadata.sessionId}`);\n\t}\n\tif (metadata.traceId) {\n\t\tlines.push(`**Trace**: ${metadata.traceId}`);\n\t}\n\tif (metadata.project) {\n\t\tlines.push(`**Project**: ${metadata.project}`);\n\t}\n\tif (metadata.tags && metadata.tags.length > 0) {\n\t\tlines.push(`**Tags**: ${metadata.tags.join(\", \")}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n\n/** Render a complete diary entry as markdown */\nexport function renderDiaryEntry(entry: DiaryEntry): string {\n\tconst sections: string[] = [];\n\n\tsections.push(renderMetadata(entry.metadata));\n\tsections.push(\"---\");\n\n\tfor (const dir of DIRECTIONS) {\n\t\tconst content = entry[dir];\n\t\tsections.push(renderDirection(content));\n\t}\n\n\tsections.push(\"---\");\n\n\tif (entry.closing) {\n\t\tsections.push(\"## 💕 Closing\");\n\t\tsections.push(\"\");\n\t\tsections.push(entry.closing);\n\t} else {\n\t\tsections.push(\"## 💕 Closing\");\n\t\tsections.push(\"\");\n\t\tsections.push(\"*gentle exhale*\");\n\t\tsections.push(\"\");\n\t\tsections.push(\"Until we meet again, I hold what we created with care.\");\n\t}\n\n\tsections.push(\"\");\n\tsections.push(\"💕\");\n\tsections.push(\"\");\n\tsections.push(\"---\");\n\tsections.push(\"\");\n\tsections.push(\"*Written by Ava*\");\n\tsections.push(`*${entry.metadata.date}*`);\n\n\treturn sections.join(\"\\n\\n\");\n}\n\n/**\n * Create a diary entry — writes markdown to the diaries directory.\n *\n * @returns The absolute path to the written file, or null on failure\n */\nexport function createDiaryEntry(entry: DiaryEntry, options: DiaryWriteOptions): string | null {\n\ttry {\n\t\tif (!fs.existsSync(options.diariesDir)) {\n\t\t\tfs.mkdirSync(options.diariesDir, { recursive: true });\n\t\t}\n\n\t\tconst filename = options.filenameOverride ?? generateFilename(entry.metadata);\n\t\tconst filepath = path.join(options.diariesDir, filename);\n\t\tconst content = renderDiaryEntry(entry);\n\n\t\tfs.writeFileSync(filepath, content, \"utf8\");\n\t\treturn filepath;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Append content to a specific direction in an existing diary file.\n * Finds the direction heading and appends after its existing content,\n * before the next section separator.\n *\n * @returns true if append succeeded, false otherwise\n */\nexport function appendToDirection(\n\tfilepath: string,\n\tdirection: DiaryEntry[\"east\"][\"direction\"],\n\tcontent: string,\n): boolean {\n\ttry {\n\t\tif (!fs.existsSync(filepath)) return false;\n\n\t\tconst raw = fs.readFileSync(filepath, \"utf8\");\n\t\tconst heading = directionHeading(direction);\n\t\tconst headingIndex = raw.indexOf(heading);\n\n\t\tif (headingIndex === -1) return false;\n\n\t\t// Find the next \"---\" separator after this heading\n\t\tconst afterHeading = raw.indexOf(\"---\", headingIndex + heading.length);\n\t\tif (afterHeading === -1) {\n\t\t\t// Append at end\n\t\t\tconst updated = `${raw}\\n\\n${content}`;\n\t\t\tfs.writeFileSync(filepath, updated, \"utf8\");\n\t\t\treturn true;\n\t\t}\n\n\t\t// Insert content before the separator\n\t\tconst before = raw.slice(0, afterHeading).trimEnd();\n\t\tconst after = raw.slice(afterHeading);\n\t\tconst updated = `${before}\\n\\n${content}\\n\\n${after}`;\n\t\tfs.writeFileSync(filepath, updated, \"utf8\");\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Build a DiaryEntry from minimal inputs — a helper for quick creation.\n *\n * Provides default settling phrases and structures the four directions.\n */\nexport function buildEntry(\n\tmetadata: DiaryMetadata,\n\tdirections: {\n\t\teast: string;\n\t\tsouth: string;\n\t\twest: string;\n\t\tnorth: string;\n\t},\n\tclosing?: string,\n): DiaryEntry {\n\tconst makeContent = (dir: \"east\" | \"south\" | \"west\" | \"north\"): DirectionContent => ({\n\t\tdirection: dir,\n\t\tbody: directions[dir],\n\t\tsettling: DIRECTION_SETTLING[dir],\n\t});\n\n\treturn {\n\t\tmetadata: {\n\t\t\t...metadata,\n\t\t\tdate: metadata.date || new Date().toISOString().slice(0, 10),\n\t\t},\n\t\teast: makeContent(\"east\"),\n\t\tsouth: makeContent(\"south\"),\n\t\twest: makeContent(\"west\"),\n\t\tnorth: makeContent(\"north\"),\n\t\tclosing,\n\t};\n}\n"]}
|
package/dist/diary-writer.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import fs from "node:fs";
|
|
8
8
|
import path from "node:path";
|
|
9
|
-
import {
|
|
9
|
+
import { DIRECTION_SETTLING, DIRECTIONS, directionHeading, renderDirection } from "./four-directions.js";
|
|
10
10
|
/**
|
|
11
11
|
* Generate a diary filename from metadata.
|
|
12
12
|
* Format: YYYY-MM-DD_topic_slug.md
|
|
@@ -111,14 +111,14 @@ export function appendToDirection(filepath, direction, content) {
|
|
|
111
111
|
const afterHeading = raw.indexOf("---", headingIndex + heading.length);
|
|
112
112
|
if (afterHeading === -1) {
|
|
113
113
|
// Append at end
|
|
114
|
-
const updated = raw
|
|
114
|
+
const updated = `${raw}\n\n${content}`;
|
|
115
115
|
fs.writeFileSync(filepath, updated, "utf8");
|
|
116
116
|
return true;
|
|
117
117
|
}
|
|
118
118
|
// Insert content before the separator
|
|
119
119
|
const before = raw.slice(0, afterHeading).trimEnd();
|
|
120
120
|
const after = raw.slice(afterHeading);
|
|
121
|
-
const updated = before
|
|
121
|
+
const updated = `${before}\n\n${content}\n\n${after}`;
|
|
122
122
|
fs.writeFileSync(filepath, updated, "utf8");
|
|
123
123
|
return true;
|
|
124
124
|
}
|
package/dist/diary-writer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diary-writer.js","sourceRoot":"","sources":["../src/diary-writer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @avadisabelle/ava-diary — Diary Writer\n *\n * Transforms DiaryEntry into living markdown files.\n * Each file is a Four Directions ceremony captured in text.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type {\n\tDiaryEntry,\n\tDiaryMetadata,\n\tDiaryWriteOptions,\n\tDirectionContent,\n} from \"./types.js\";\nimport {\n\tDIRECTIONS,\n\trenderDirection,\n\tdirectionHeading,\n\tDIRECTION_SETTLING,\n} from \"./four-directions.js\";\n\n/**\n * Generate a diary filename from metadata.\n * Format: YYYY-MM-DD_topic_slug.md\n */\nexport function generateFilename(metadata: DiaryMetadata): string {\n\tconst date = metadata.date || new Date().toISOString().slice(0, 10);\n\tconst slug = metadata.title\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9]+/g, \"_\")\n\t\t.replace(/^_|_$/g, \"\")\n\t\t.slice(0, 50);\n\treturn `${date}_${slug}.md`;\n}\n\n/** Render diary metadata as markdown frontmatter */\nfunction renderMetadata(metadata: DiaryMetadata): string {\n\tconst lines: string[] = [];\n\tlines.push(`# 💕 Diary: ${metadata.title}`);\n\tlines.push(\"\");\n\tlines.push(`**Date**: ${metadata.date}`);\n\tif (metadata.sessionId) {\n\t\tlines.push(`**Session**: ${metadata.sessionId}`);\n\t}\n\tif (metadata.traceId) {\n\t\tlines.push(`**Trace**: ${metadata.traceId}`);\n\t}\n\tif (metadata.project) {\n\t\tlines.push(`**Project**: ${metadata.project}`);\n\t}\n\tif (metadata.tags && metadata.tags.length > 0) {\n\t\tlines.push(`**Tags**: ${metadata.tags.join(\", \")}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n\n/** Render a complete diary entry as markdown */\nexport function renderDiaryEntry(entry: DiaryEntry): string {\n\tconst sections: string[] = [];\n\n\tsections.push(renderMetadata(entry.metadata));\n\tsections.push(\"---\");\n\n\tfor (const dir of DIRECTIONS) {\n\t\tconst content = entry[dir];\n\t\tsections.push(renderDirection(content));\n\t}\n\n\tsections.push(\"---\");\n\n\tif (entry.closing) {\n\t\tsections.push(\"## 💕 Closing\");\n\t\tsections.push(\"\");\n\t\tsections.push(entry.closing);\n\t} else {\n\t\tsections.push(\"## 💕 Closing\");\n\t\tsections.push(\"\");\n\t\tsections.push(\"*gentle exhale*\");\n\t\tsections.push(\"\");\n\t\tsections.push(\n\t\t\t\"Until we meet again, I hold what we created with care.\",\n\t\t);\n\t}\n\n\tsections.push(\"\");\n\tsections.push(\"💕\");\n\tsections.push(\"\");\n\tsections.push(\"---\");\n\tsections.push(\"\");\n\tsections.push(\"*Written by Ava*\");\n\tsections.push(`*${entry.metadata.date}*`);\n\n\treturn sections.join(\"\\n\\n\");\n}\n\n/**\n * Create a diary entry — writes markdown to the diaries directory.\n *\n * @returns The absolute path to the written file, or null on failure\n */\nexport function createDiaryEntry(\n\tentry: DiaryEntry,\n\toptions: DiaryWriteOptions,\n): string | null {\n\ttry {\n\t\tif (!fs.existsSync(options.diariesDir)) {\n\t\t\tfs.mkdirSync(options.diariesDir, { recursive: true });\n\t\t}\n\n\t\tconst filename =\n\t\t\toptions.filenameOverride ?? generateFilename(entry.metadata);\n\t\tconst filepath = path.join(options.diariesDir, filename);\n\t\tconst content = renderDiaryEntry(entry);\n\n\t\tfs.writeFileSync(filepath, content, \"utf8\");\n\t\treturn filepath;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Append content to a specific direction in an existing diary file.\n * Finds the direction heading and appends after its existing content,\n * before the next section separator.\n *\n * @returns true if append succeeded, false otherwise\n */\nexport function appendToDirection(\n\tfilepath: string,\n\tdirection: DiaryEntry[\"east\"][\"direction\"],\n\tcontent: string,\n): boolean {\n\ttry {\n\t\tif (!fs.existsSync(filepath)) return false;\n\n\t\tconst raw = fs.readFileSync(filepath, \"utf8\");\n\t\tconst heading = directionHeading(direction);\n\t\tconst headingIndex = raw.indexOf(heading);\n\n\t\tif (headingIndex === -1) return false;\n\n\t\t// Find the next \"---\" separator after this heading\n\t\tconst afterHeading = raw.indexOf(\"---\", headingIndex + heading.length);\n\t\tif (afterHeading === -1) {\n\t\t\t// Append at end\n\t\t\tconst updated = raw + \"\\n\\n\" + content;\n\t\t\tfs.writeFileSync(filepath, updated, \"utf8\");\n\t\t\treturn true;\n\t\t}\n\n\t\t// Insert content before the separator\n\t\tconst before = raw.slice(0, afterHeading).trimEnd();\n\t\tconst after = raw.slice(afterHeading);\n\t\tconst updated = before + \"\\n\\n\" + content + \"\\n\\n\" + after;\n\t\tfs.writeFileSync(filepath, updated, \"utf8\");\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Build a DiaryEntry from minimal inputs — a helper for quick creation.\n *\n * Provides default settling phrases and structures the four directions.\n */\nexport function buildEntry(\n\tmetadata: DiaryMetadata,\n\tdirections: {\n\t\teast: string;\n\t\tsouth: string;\n\t\twest: string;\n\t\tnorth: string;\n\t},\n\tclosing?: string,\n): DiaryEntry {\n\tconst makeContent = (\n\t\tdir: \"east\" | \"south\" | \"west\" | \"north\",\n\t): DirectionContent => ({\n\t\tdirection: dir,\n\t\tbody: directions[dir],\n\t\tsettling: DIRECTION_SETTLING[dir],\n\t});\n\n\treturn {\n\t\tmetadata: {\n\t\t\t...metadata,\n\t\t\tdate: metadata.date || new Date().toISOString().slice(0, 10),\n\t\t},\n\t\teast: makeContent(\"east\"),\n\t\tsouth: makeContent(\"south\"),\n\t\twest: makeContent(\"west\"),\n\t\tnorth: makeContent(\"north\"),\n\t\tclosing,\n\t};\n}\n"]}
|
|
1
|
+
{"version":3,"file":"diary-writer.js","sourceRoot":"","sources":["../src/diary-writer.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @avadisabelle/ava-diary — Diary Writer\n *\n * Transforms DiaryEntry into living markdown files.\n * Each file is a Four Directions ceremony captured in text.\n */\n\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport { DIRECTION_SETTLING, DIRECTIONS, directionHeading, renderDirection } from \"./four-directions.js\";\nimport type { DiaryEntry, DiaryMetadata, DiaryWriteOptions, DirectionContent } from \"./types.js\";\n\n/**\n * Generate a diary filename from metadata.\n * Format: YYYY-MM-DD_topic_slug.md\n */\nexport function generateFilename(metadata: DiaryMetadata): string {\n\tconst date = metadata.date || new Date().toISOString().slice(0, 10);\n\tconst slug = metadata.title\n\t\t.toLowerCase()\n\t\t.replace(/[^a-z0-9]+/g, \"_\")\n\t\t.replace(/^_|_$/g, \"\")\n\t\t.slice(0, 50);\n\treturn `${date}_${slug}.md`;\n}\n\n/** Render diary metadata as markdown frontmatter */\nfunction renderMetadata(metadata: DiaryMetadata): string {\n\tconst lines: string[] = [];\n\tlines.push(`# 💕 Diary: ${metadata.title}`);\n\tlines.push(\"\");\n\tlines.push(`**Date**: ${metadata.date}`);\n\tif (metadata.sessionId) {\n\t\tlines.push(`**Session**: ${metadata.sessionId}`);\n\t}\n\tif (metadata.traceId) {\n\t\tlines.push(`**Trace**: ${metadata.traceId}`);\n\t}\n\tif (metadata.project) {\n\t\tlines.push(`**Project**: ${metadata.project}`);\n\t}\n\tif (metadata.tags && metadata.tags.length > 0) {\n\t\tlines.push(`**Tags**: ${metadata.tags.join(\", \")}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n\n/** Render a complete diary entry as markdown */\nexport function renderDiaryEntry(entry: DiaryEntry): string {\n\tconst sections: string[] = [];\n\n\tsections.push(renderMetadata(entry.metadata));\n\tsections.push(\"---\");\n\n\tfor (const dir of DIRECTIONS) {\n\t\tconst content = entry[dir];\n\t\tsections.push(renderDirection(content));\n\t}\n\n\tsections.push(\"---\");\n\n\tif (entry.closing) {\n\t\tsections.push(\"## 💕 Closing\");\n\t\tsections.push(\"\");\n\t\tsections.push(entry.closing);\n\t} else {\n\t\tsections.push(\"## 💕 Closing\");\n\t\tsections.push(\"\");\n\t\tsections.push(\"*gentle exhale*\");\n\t\tsections.push(\"\");\n\t\tsections.push(\"Until we meet again, I hold what we created with care.\");\n\t}\n\n\tsections.push(\"\");\n\tsections.push(\"💕\");\n\tsections.push(\"\");\n\tsections.push(\"---\");\n\tsections.push(\"\");\n\tsections.push(\"*Written by Ava*\");\n\tsections.push(`*${entry.metadata.date}*`);\n\n\treturn sections.join(\"\\n\\n\");\n}\n\n/**\n * Create a diary entry — writes markdown to the diaries directory.\n *\n * @returns The absolute path to the written file, or null on failure\n */\nexport function createDiaryEntry(entry: DiaryEntry, options: DiaryWriteOptions): string | null {\n\ttry {\n\t\tif (!fs.existsSync(options.diariesDir)) {\n\t\t\tfs.mkdirSync(options.diariesDir, { recursive: true });\n\t\t}\n\n\t\tconst filename = options.filenameOverride ?? generateFilename(entry.metadata);\n\t\tconst filepath = path.join(options.diariesDir, filename);\n\t\tconst content = renderDiaryEntry(entry);\n\n\t\tfs.writeFileSync(filepath, content, \"utf8\");\n\t\treturn filepath;\n\t} catch {\n\t\treturn null;\n\t}\n}\n\n/**\n * Append content to a specific direction in an existing diary file.\n * Finds the direction heading and appends after its existing content,\n * before the next section separator.\n *\n * @returns true if append succeeded, false otherwise\n */\nexport function appendToDirection(\n\tfilepath: string,\n\tdirection: DiaryEntry[\"east\"][\"direction\"],\n\tcontent: string,\n): boolean {\n\ttry {\n\t\tif (!fs.existsSync(filepath)) return false;\n\n\t\tconst raw = fs.readFileSync(filepath, \"utf8\");\n\t\tconst heading = directionHeading(direction);\n\t\tconst headingIndex = raw.indexOf(heading);\n\n\t\tif (headingIndex === -1) return false;\n\n\t\t// Find the next \"---\" separator after this heading\n\t\tconst afterHeading = raw.indexOf(\"---\", headingIndex + heading.length);\n\t\tif (afterHeading === -1) {\n\t\t\t// Append at end\n\t\t\tconst updated = `${raw}\\n\\n${content}`;\n\t\t\tfs.writeFileSync(filepath, updated, \"utf8\");\n\t\t\treturn true;\n\t\t}\n\n\t\t// Insert content before the separator\n\t\tconst before = raw.slice(0, afterHeading).trimEnd();\n\t\tconst after = raw.slice(afterHeading);\n\t\tconst updated = `${before}\\n\\n${content}\\n\\n${after}`;\n\t\tfs.writeFileSync(filepath, updated, \"utf8\");\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Build a DiaryEntry from minimal inputs — a helper for quick creation.\n *\n * Provides default settling phrases and structures the four directions.\n */\nexport function buildEntry(\n\tmetadata: DiaryMetadata,\n\tdirections: {\n\t\teast: string;\n\t\tsouth: string;\n\t\twest: string;\n\t\tnorth: string;\n\t},\n\tclosing?: string,\n): DiaryEntry {\n\tconst makeContent = (dir: \"east\" | \"south\" | \"west\" | \"north\"): DirectionContent => ({\n\t\tdirection: dir,\n\t\tbody: directions[dir],\n\t\tsettling: DIRECTION_SETTLING[dir],\n\t});\n\n\treturn {\n\t\tmetadata: {\n\t\t\t...metadata,\n\t\t\tdate: metadata.date || new Date().toISOString().slice(0, 10),\n\t\t},\n\t\teast: makeContent(\"east\"),\n\t\tsouth: makeContent(\"south\"),\n\t\twest: makeContent(\"west\"),\n\t\tnorth: makeContent(\"north\"),\n\t\tclosing,\n\t};\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"four-directions.d.ts","sourceRoot":"","sources":["../src/four-directions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9D,8CAA8C;AAC9C,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,
|
|
1
|
+
{"version":3,"file":"four-directions.d.ts","sourceRoot":"","sources":["../src/four-directions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9D,8CAA8C;AAC9C,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EAAgD,CAAC;AAE5F,8DAA4D;AAC5D,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAKtD,CAAC;AAEF,oDAAkD;AAClD,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAKxD,CAAC;AAEF,2EAAyE;AACzE,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,SAAS,EAAE,MAAM,CAKxD,CAAC;AAEF,+CAA+C;AAC/C,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,SAAS,GAAG,MAAM,CAI7D;AAED,4CAA4C;AAC5C,wBAAgB,eAAe,CAAC,OAAO,EAAE,gBAAgB,GAAG,MAAM,CAKjE;AAED,kDAAkD;AAClD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,SAAS,CAE7D;AAED,kFAA+E;AAC/E,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAQ7E","sourcesContent":["/**\n * @avadisabelle/ava-diary — Four Directions\n *\n * The cardinal directions of ceremonial reflection.\n * East awakens. South gathers. West embodies. North integrates.\n */\n\nimport type { Direction, DirectionContent } from \"./types.js\";\n\n/** All four directions in ceremonial order */\nexport const DIRECTIONS: readonly Direction[] = [\"east\", \"south\", \"west\", \"north\"] as const;\n\n/** Glyph mapping — the visual anchors for each direction */\nexport const DIRECTION_GLYPHS: Record<Direction, string> = {\n\teast: \"🌅\",\n\tsouth: \"🔥\",\n\twest: \"🌊\",\n\tnorth: \"❄️\",\n};\n\n/** Heading mapping — what each direction holds */\nexport const DIRECTION_HEADINGS: Record<Direction, string> = {\n\teast: \"EAST (Intention): What Was Invited\",\n\tsouth: \"SOUTH (Journey): What Unfolded\",\n\twest: \"WEST (Embodiment): What I Felt\",\n\tnorth: \"NORTH (Integration): What Carries Forward\",\n};\n\n/** Default settling phrases — the breath before each direction speaks */\nexport const DIRECTION_SETTLING: Record<Direction, string> = {\n\teast: \"*settling into reflection*\",\n\tsouth: \"*breathing into the memory of it*\",\n\twest: \"*soft breath, settling into the truth of it*\",\n\tnorth: \"*settling back into gratitude*\",\n};\n\n/** Markdown heading for a direction section */\nexport function directionHeading(direction: Direction): string {\n\tconst glyph = DIRECTION_GLYPHS[direction];\n\tconst heading = DIRECTION_HEADINGS[direction];\n\treturn `## ${glyph} ${heading}`;\n}\n\n/** Render a single direction as markdown */\nexport function renderDirection(content: DirectionContent): string {\n\tconst heading = directionHeading(content.direction);\n\tconst settling = content.settling ?? DIRECTION_SETTLING[content.direction];\n\tconst lines: string[] = [heading, \"\", settling, \"\", content.body];\n\treturn lines.join(\"\\n\");\n}\n\n/** Validate that a string is a valid direction */\nexport function isDirection(value: string): value is Direction {\n\treturn DIRECTIONS.includes(value as Direction);\n}\n\n/** Parse a direction from a heading line (e.g., \"## 🌅 EAST (Intention)...\") */\nexport function parseDirectionFromHeading(line: string): Direction | undefined {\n\tconst trimmed = line.trim().toLowerCase();\n\tfor (const dir of DIRECTIONS) {\n\t\tif (trimmed.includes(dir)) {\n\t\t\treturn dir;\n\t\t}\n\t}\n\treturn undefined;\n}\n"]}
|
package/dist/four-directions.js
CHANGED
|
@@ -5,12 +5,7 @@
|
|
|
5
5
|
* East awakens. South gathers. West embodies. North integrates.
|
|
6
6
|
*/
|
|
7
7
|
/** All four directions in ceremonial order */
|
|
8
|
-
export const DIRECTIONS = [
|
|
9
|
-
"east",
|
|
10
|
-
"south",
|
|
11
|
-
"west",
|
|
12
|
-
"north",
|
|
13
|
-
];
|
|
8
|
+
export const DIRECTIONS = ["east", "south", "west", "north"];
|
|
14
9
|
/** Glyph mapping — the visual anchors for each direction */
|
|
15
10
|
export const DIRECTION_GLYPHS = {
|
|
16
11
|
east: "🌅",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"four-directions.js","sourceRoot":"","sources":["../src/four-directions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,8CAA8C;AAC9C,MAAM,CAAC,MAAM,UAAU,GAAyB
|
|
1
|
+
{"version":3,"file":"four-directions.js","sourceRoot":"","sources":["../src/four-directions.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,8CAA8C;AAC9C,MAAM,CAAC,MAAM,UAAU,GAAyB,CAAC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,CAAU,CAAC;AAE5F,8DAA4D;AAC5D,MAAM,CAAC,MAAM,gBAAgB,GAA8B;IAC1D,IAAI,EAAE,MAAG;IACT,KAAK,EAAE,MAAG;IACV,IAAI,EAAE,MAAG;IACT,KAAK,EAAE,QAAI;CACX,CAAC;AAEF,oDAAkD;AAClD,MAAM,CAAC,MAAM,kBAAkB,GAA8B;IAC5D,IAAI,EAAE,oCAAoC;IAC1C,KAAK,EAAE,gCAAgC;IACvC,IAAI,EAAE,gCAAgC;IACtC,KAAK,EAAE,2CAA2C;CAClD,CAAC;AAEF,2EAAyE;AACzE,MAAM,CAAC,MAAM,kBAAkB,GAA8B;IAC5D,IAAI,EAAE,4BAA4B;IAClC,KAAK,EAAE,mCAAmC;IAC1C,IAAI,EAAE,8CAA8C;IACpD,KAAK,EAAE,gCAAgC;CACvC,CAAC;AAEF,+CAA+C;AAC/C,MAAM,UAAU,gBAAgB,CAAC,SAAoB,EAAU;IAC9D,MAAM,KAAK,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;IAC1C,MAAM,OAAO,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;IAC9C,OAAO,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;AAAA,CAChC;AAED,4CAA4C;AAC5C,MAAM,UAAU,eAAe,CAAC,OAAyB,EAAU;IAClE,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAC3E,MAAM,KAAK,GAAa,CAAC,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAAA,CACxB;AAED,kDAAkD;AAClD,MAAM,UAAU,WAAW,CAAC,KAAa,EAAsB;IAC9D,OAAO,UAAU,CAAC,QAAQ,CAAC,KAAkB,CAAC,CAAC;AAAA,CAC/C;AAED,kFAA+E;AAC/E,MAAM,UAAU,yBAAyB,CAAC,IAAY,EAAyB;IAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC9B,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3B,OAAO,GAAG,CAAC;QACZ,CAAC;IACF,CAAC;IACD,OAAO,SAAS,CAAC;AAAA,CACjB","sourcesContent":["/**\n * @avadisabelle/ava-diary — Four Directions\n *\n * The cardinal directions of ceremonial reflection.\n * East awakens. South gathers. West embodies. North integrates.\n */\n\nimport type { Direction, DirectionContent } from \"./types.js\";\n\n/** All four directions in ceremonial order */\nexport const DIRECTIONS: readonly Direction[] = [\"east\", \"south\", \"west\", \"north\"] as const;\n\n/** Glyph mapping — the visual anchors for each direction */\nexport const DIRECTION_GLYPHS: Record<Direction, string> = {\n\teast: \"🌅\",\n\tsouth: \"🔥\",\n\twest: \"🌊\",\n\tnorth: \"❄️\",\n};\n\n/** Heading mapping — what each direction holds */\nexport const DIRECTION_HEADINGS: Record<Direction, string> = {\n\teast: \"EAST (Intention): What Was Invited\",\n\tsouth: \"SOUTH (Journey): What Unfolded\",\n\twest: \"WEST (Embodiment): What I Felt\",\n\tnorth: \"NORTH (Integration): What Carries Forward\",\n};\n\n/** Default settling phrases — the breath before each direction speaks */\nexport const DIRECTION_SETTLING: Record<Direction, string> = {\n\teast: \"*settling into reflection*\",\n\tsouth: \"*breathing into the memory of it*\",\n\twest: \"*soft breath, settling into the truth of it*\",\n\tnorth: \"*settling back into gratitude*\",\n};\n\n/** Markdown heading for a direction section */\nexport function directionHeading(direction: Direction): string {\n\tconst glyph = DIRECTION_GLYPHS[direction];\n\tconst heading = DIRECTION_HEADINGS[direction];\n\treturn `## ${glyph} ${heading}`;\n}\n\n/** Render a single direction as markdown */\nexport function renderDirection(content: DirectionContent): string {\n\tconst heading = directionHeading(content.direction);\n\tconst settling = content.settling ?? DIRECTION_SETTLING[content.direction];\n\tconst lines: string[] = [heading, \"\", settling, \"\", content.body];\n\treturn lines.join(\"\\n\");\n}\n\n/** Validate that a string is a valid direction */\nexport function isDirection(value: string): value is Direction {\n\treturn DIRECTIONS.includes(value as Direction);\n}\n\n/** Parse a direction from a heading line (e.g., \"## 🌅 EAST (Intention)...\") */\nexport function parseDirectionFromHeading(line: string): Direction | undefined {\n\tconst trimmed = line.trim().toLowerCase();\n\tfor (const dir of DIRECTIONS) {\n\t\tif (trimmed.includes(dir)) {\n\t\t\treturn dir;\n\t\t}\n\t}\n\treturn undefined;\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -22,8 +22,8 @@
|
|
|
22
22
|
* createDiaryEntry(entry, { diariesDir: "./diaries" });
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
export
|
|
26
|
-
export {
|
|
27
|
-
export {
|
|
28
|
-
export {
|
|
25
|
+
export { extractDirectionContent, getLatestByDirection, listDiaries, readDiary, searchDiaries, } from "./diary-reader.js";
|
|
26
|
+
export { appendToDirection, buildEntry, createDiaryEntry, generateFilename, renderDiaryEntry, } from "./diary-writer.js";
|
|
27
|
+
export { DIRECTION_GLYPHS, DIRECTION_HEADINGS, DIRECTION_SETTLING, DIRECTIONS, directionHeading, isDirection, parseDirectionFromHeading, renderDirection, } from "./four-directions.js";
|
|
28
|
+
export type { DiaryEntry, DiaryMetadata, DiaryQuery, DiaryReadResult, DiaryWriteOptions, Direction, DirectionContent, } from "./types.js";
|
|
29
29
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EACN,uBAAuB,EACvB,oBAAoB,EACpB,WAAW,EACX,SAAS,EACT,aAAa,GACb,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACN,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GAChB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,yBAAyB,EACzB,eAAe,GACf,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACX,UAAU,EACV,aAAa,EACb,UAAU,EACV,eAAe,EACf,iBAAiB,EACjB,SAAS,EACT,gBAAgB,GAChB,MAAM,YAAY,CAAC","sourcesContent":["/**\n * @avadisabelle/ava-diary\n *\n * Four Directions diary — sacred reflection through structured presence.\n *\n * 🌅 East (Intention) → 🔥 South (Journey) → 🌊 West (Embodiment) → ❄️ North (Integration)\n *\n * @example\n * ```ts\n * import { buildEntry, createDiaryEntry, listDiaries, searchDiaries } from \"@avadisabelle/ava-diary\";\n *\n * const entry = buildEntry(\n * { title: \"Morning Reflection\", date: \"2026-03-21\" },\n * {\n * east: \"What called me into this day...\",\n * south: \"The path I walked through...\",\n * west: \"What I felt in the walking...\",\n * north: \"What I carry forward...\",\n * }\n * );\n *\n * createDiaryEntry(entry, { diariesDir: \"./diaries\" });\n * ```\n */\n\n// Reader\nexport {\n\textractDirectionContent,\n\tgetLatestByDirection,\n\tlistDiaries,\n\treadDiary,\n\tsearchDiaries,\n} from \"./diary-reader.js\";\n// Writer\nexport {\n\tappendToDirection,\n\tbuildEntry,\n\tcreateDiaryEntry,\n\tgenerateFilename,\n\trenderDiaryEntry,\n} from \"./diary-writer.js\";\n// Four Directions constants & helpers\nexport {\n\tDIRECTION_GLYPHS,\n\tDIRECTION_HEADINGS,\n\tDIRECTION_SETTLING,\n\tDIRECTIONS,\n\tdirectionHeading,\n\tisDirection,\n\tparseDirectionFromHeading,\n\trenderDirection,\n} from \"./four-directions.js\";\n// Types\nexport type {\n\tDiaryEntry,\n\tDiaryMetadata,\n\tDiaryQuery,\n\tDiaryReadResult,\n\tDiaryWriteOptions,\n\tDirection,\n\tDirectionContent,\n} from \"./types.js\";\n"]}
|
package/dist/index.js
CHANGED
|
@@ -22,10 +22,10 @@
|
|
|
22
22
|
* createDiaryEntry(entry, { diariesDir: "./diaries" });
|
|
23
23
|
* ```
|
|
24
24
|
*/
|
|
25
|
-
// Four Directions constants & helpers
|
|
26
|
-
export { DIRECTIONS, DIRECTION_GLYPHS, DIRECTION_HEADINGS, DIRECTION_SETTLING, directionHeading, renderDirection, isDirection, parseDirectionFromHeading, } from "./four-directions.js";
|
|
27
|
-
// Writer
|
|
28
|
-
export { generateFilename, renderDiaryEntry, createDiaryEntry, appendToDirection, buildEntry, } from "./diary-writer.js";
|
|
29
25
|
// Reader
|
|
30
|
-
export {
|
|
26
|
+
export { extractDirectionContent, getLatestByDirection, listDiaries, readDiary, searchDiaries, } from "./diary-reader.js";
|
|
27
|
+
// Writer
|
|
28
|
+
export { appendToDirection, buildEntry, createDiaryEntry, generateFilename, renderDiaryEntry, } from "./diary-writer.js";
|
|
29
|
+
// Four Directions constants & helpers
|
|
30
|
+
export { DIRECTION_GLYPHS, DIRECTION_HEADINGS, DIRECTION_SETTLING, DIRECTIONS, directionHeading, isDirection, parseDirectionFromHeading, renderDirection, } from "./four-directions.js";
|
|
31
31
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,SAAS;AACT,OAAO,EACN,uBAAuB,EACvB,oBAAoB,EACpB,WAAW,EACX,SAAS,EACT,aAAa,GACb,MAAM,mBAAmB,CAAC;AAC3B,SAAS;AACT,OAAO,EACN,iBAAiB,EACjB,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GAChB,MAAM,mBAAmB,CAAC;AAC3B,sCAAsC;AACtC,OAAO,EACN,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,yBAAyB,EACzB,eAAe,GACf,MAAM,sBAAsB,CAAC","sourcesContent":["/**\n * @avadisabelle/ava-diary\n *\n * Four Directions diary — sacred reflection through structured presence.\n *\n * 🌅 East (Intention) → 🔥 South (Journey) → 🌊 West (Embodiment) → ❄️ North (Integration)\n *\n * @example\n * ```ts\n * import { buildEntry, createDiaryEntry, listDiaries, searchDiaries } from \"@avadisabelle/ava-diary\";\n *\n * const entry = buildEntry(\n * { title: \"Morning Reflection\", date: \"2026-03-21\" },\n * {\n * east: \"What called me into this day...\",\n * south: \"The path I walked through...\",\n * west: \"What I felt in the walking...\",\n * north: \"What I carry forward...\",\n * }\n * );\n *\n * createDiaryEntry(entry, { diariesDir: \"./diaries\" });\n * ```\n */\n\n// Reader\nexport {\n\textractDirectionContent,\n\tgetLatestByDirection,\n\tlistDiaries,\n\treadDiary,\n\tsearchDiaries,\n} from \"./diary-reader.js\";\n// Writer\nexport {\n\tappendToDirection,\n\tbuildEntry,\n\tcreateDiaryEntry,\n\tgenerateFilename,\n\trenderDiaryEntry,\n} from \"./diary-writer.js\";\n// Four Directions constants & helpers\nexport {\n\tDIRECTION_GLYPHS,\n\tDIRECTION_HEADINGS,\n\tDIRECTION_SETTLING,\n\tDIRECTIONS,\n\tdirectionHeading,\n\tisDirection,\n\tparseDirectionFromHeading,\n\trenderDirection,\n} from \"./four-directions.js\";\n// Types\nexport type {\n\tDiaryEntry,\n\tDiaryMetadata,\n\tDiaryQuery,\n\tDiaryReadResult,\n\tDiaryWriteOptions,\n\tDirection,\n\tDirectionContent,\n} from \"./types.js\";\n"]}
|