Read every markdown file directly under `dir` (one level), oldest→newest by name.
(dir: string)
| 60 | |
| 61 | /** Read every markdown file directly under `dir` (one level), oldest→newest by name. */ |
| 62 | async function readMarkdownDir(dir: string): Promise<Array<{ name: string; content: string; mtimeMs: number }>> { |
| 63 | let entries: string[] = []; |
| 64 | try { |
| 65 | entries = (await fs.readdir(dir, { withFileTypes: true })) |
| 66 | .filter(e => e.isFile() && /\.(md|markdown|txt)$/i.test(e.name)) |
| 67 | .map(e => e.name); |
| 68 | } catch { |
| 69 | return []; |
| 70 | } |
| 71 | const out: Array<{ name: string; content: string; mtimeMs: number }> = []; |
| 72 | for (const name of entries) { |
| 73 | const full = path.join(dir, name); |
| 74 | try { |
| 75 | const [content, st] = await Promise.all([ |
| 76 | fs.readFile(full, 'utf-8'), |
| 77 | fs.stat(full), |
| 78 | ]); |
| 79 | out.push({ name, content: content.trim(), mtimeMs: st.mtimeMs }); |
| 80 | } catch { /* skip unreadable */ } |
| 81 | } |
| 82 | return out; |
| 83 | } |
| 84 | |
| 85 | /** Concatenate files under a byte budget, marking truncation. */ |
| 86 | function packFiles( |
no test coverage detected