agent-recall-mcp 3.2.2 → 3.3.1
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/README.md +162 -2
- package/dist/helpers/journal-files.d.ts +30 -0
- package/dist/helpers/journal-files.d.ts.map +1 -0
- package/dist/helpers/journal-files.js +96 -0
- package/dist/helpers/journal-files.js.map +1 -0
- package/dist/helpers/sections.d.ts +12 -0
- package/dist/helpers/sections.d.ts.map +1 -0
- package/dist/helpers/sections.js +84 -0
- package/dist/helpers/sections.js.map +1 -0
- package/dist/index.js +59 -1199
- package/dist/index.js.map +1 -1
- package/dist/palace/awareness.d.ts +67 -0
- package/dist/palace/awareness.d.ts.map +1 -0
- package/dist/palace/awareness.js +231 -0
- package/dist/palace/awareness.js.map +1 -0
- package/dist/palace/consolidate.d.ts +28 -0
- package/dist/palace/consolidate.d.ts.map +1 -0
- package/dist/palace/consolidate.js +129 -0
- package/dist/palace/consolidate.js.map +1 -0
- package/dist/palace/fan-out.d.ts +15 -0
- package/dist/palace/fan-out.d.ts.map +1 -0
- package/dist/palace/fan-out.js +78 -0
- package/dist/palace/fan-out.js.map +1 -0
- package/dist/palace/graph.d.ts +11 -0
- package/dist/palace/graph.d.ts.map +1 -0
- package/dist/palace/graph.js +59 -0
- package/dist/palace/graph.js.map +1 -0
- package/dist/palace/identity.d.ts +6 -0
- package/dist/palace/identity.d.ts.map +1 -0
- package/dist/palace/identity.js +18 -0
- package/dist/palace/identity.js.map +1 -0
- package/dist/palace/index-manager.d.ts +7 -0
- package/dist/palace/index-manager.d.ts.map +1 -0
- package/dist/palace/index-manager.js +46 -0
- package/dist/palace/index-manager.js.map +1 -0
- package/dist/palace/insights-index.d.ts +39 -0
- package/dist/palace/insights-index.d.ts.map +1 -0
- package/dist/palace/insights-index.js +101 -0
- package/dist/palace/insights-index.js.map +1 -0
- package/dist/palace/log.d.ts +9 -0
- package/dist/palace/log.d.ts.map +1 -0
- package/dist/palace/log.js +28 -0
- package/dist/palace/log.js.map +1 -0
- package/dist/palace/obsidian.d.ts +12 -0
- package/dist/palace/obsidian.d.ts.map +1 -0
- package/dist/palace/obsidian.js +76 -0
- package/dist/palace/obsidian.js.map +1 -0
- package/dist/palace/rooms.d.ts +14 -0
- package/dist/palace/rooms.d.ts.map +1 -0
- package/dist/palace/rooms.js +117 -0
- package/dist/palace/rooms.js.map +1 -0
- package/dist/palace/salience.d.ts +15 -0
- package/dist/palace/salience.d.ts.map +1 -0
- package/dist/palace/salience.js +33 -0
- package/dist/palace/salience.js.map +1 -0
- package/dist/resources/journal-resources.d.ts +3 -0
- package/dist/resources/journal-resources.d.ts.map +1 -0
- package/dist/resources/journal-resources.js +72 -0
- package/dist/resources/journal-resources.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +7 -0
- package/dist/server.js.map +1 -0
- package/dist/storage/fs-utils.d.ts +8 -0
- package/dist/storage/fs-utils.d.ts.map +1 -0
- package/dist/storage/fs-utils.js +28 -0
- package/dist/storage/fs-utils.js.map +1 -0
- package/dist/storage/paths.d.ts +21 -0
- package/dist/storage/paths.d.ts.map +1 -0
- package/dist/storage/paths.js +59 -0
- package/dist/storage/paths.js.map +1 -0
- package/dist/storage/project.d.ts +17 -0
- package/dist/storage/project.d.ts.map +1 -0
- package/dist/storage/project.js +130 -0
- package/dist/storage/project.js.map +1 -0
- package/dist/tools/alignment-check.d.ts +3 -0
- package/dist/tools/alignment-check.d.ts.map +1 -0
- package/dist/tools/alignment-check.js +73 -0
- package/dist/tools/alignment-check.js.map +1 -0
- package/dist/tools/awareness-update.d.ts +9 -0
- package/dist/tools/awareness-update.d.ts.map +1 -0
- package/dist/tools/awareness-update.js +90 -0
- package/dist/tools/awareness-update.js.map +1 -0
- package/dist/tools/context-synthesize.d.ts +3 -0
- package/dist/tools/context-synthesize.d.ts.map +1 -0
- package/dist/tools/context-synthesize.js +204 -0
- package/dist/tools/context-synthesize.js.map +1 -0
- package/dist/tools/journal-archive.d.ts +3 -0
- package/dist/tools/journal-archive.d.ts.map +1 -0
- package/dist/tools/journal-archive.js +62 -0
- package/dist/tools/journal-archive.js.map +1 -0
- package/dist/tools/journal-capture.d.ts +3 -0
- package/dist/tools/journal-capture.d.ts.map +1 -0
- package/dist/tools/journal-capture.js +87 -0
- package/dist/tools/journal-capture.js.map +1 -0
- package/dist/tools/journal-cold-start.d.ts +3 -0
- package/dist/tools/journal-cold-start.d.ts.map +1 -0
- package/dist/tools/journal-cold-start.js +70 -0
- package/dist/tools/journal-cold-start.js.map +1 -0
- package/dist/tools/journal-list.d.ts +3 -0
- package/dist/tools/journal-list.d.ts.map +1 -0
- package/dist/tools/journal-list.js +43 -0
- package/dist/tools/journal-list.js.map +1 -0
- package/dist/tools/journal-projects.d.ts +3 -0
- package/dist/tools/journal-projects.d.ts.map +1 -0
- package/dist/tools/journal-projects.js +25 -0
- package/dist/tools/journal-projects.js.map +1 -0
- package/dist/tools/journal-read.d.ts +3 -0
- package/dist/tools/journal-read.d.ts.map +1 -0
- package/dist/tools/journal-read.js +72 -0
- package/dist/tools/journal-read.js.map +1 -0
- package/dist/tools/journal-search.d.ts +3 -0
- package/dist/tools/journal-search.d.ts.map +1 -0
- package/dist/tools/journal-search.js +113 -0
- package/dist/tools/journal-search.js.map +1 -0
- package/dist/tools/journal-state.d.ts +6 -0
- package/dist/tools/journal-state.d.ts.map +1 -0
- package/dist/tools/journal-state.js +111 -0
- package/dist/tools/journal-state.js.map +1 -0
- package/dist/tools/journal-write.d.ts +3 -0
- package/dist/tools/journal-write.d.ts.map +1 -0
- package/dist/tools/journal-write.js +88 -0
- package/dist/tools/journal-write.js.map +1 -0
- package/dist/tools/knowledge-read.d.ts +3 -0
- package/dist/tools/knowledge-read.d.ts.map +1 -0
- package/dist/tools/knowledge-read.js +118 -0
- package/dist/tools/knowledge-read.js.map +1 -0
- package/dist/tools/knowledge-write.d.ts +3 -0
- package/dist/tools/knowledge-write.d.ts.map +1 -0
- package/dist/tools/knowledge-write.js +89 -0
- package/dist/tools/knowledge-write.js.map +1 -0
- package/dist/tools/nudge.d.ts +3 -0
- package/dist/tools/nudge.d.ts.map +1 -0
- package/dist/tools/nudge.js +41 -0
- package/dist/tools/nudge.js.map +1 -0
- package/dist/tools/palace-lint.d.ts +7 -0
- package/dist/tools/palace-lint.d.ts.map +1 -0
- package/dist/tools/palace-lint.js +149 -0
- package/dist/tools/palace-lint.js.map +1 -0
- package/dist/tools/palace-read.d.ts +6 -0
- package/dist/tools/palace-read.d.ts.map +1 -0
- package/dist/tools/palace-read.js +78 -0
- package/dist/tools/palace-read.js.map +1 -0
- package/dist/tools/palace-search.d.ts +6 -0
- package/dist/tools/palace-search.d.ts.map +1 -0
- package/dist/tools/palace-search.js +81 -0
- package/dist/tools/palace-search.js.map +1 -0
- package/dist/tools/palace-walk.d.ts +12 -0
- package/dist/tools/palace-walk.d.ts.map +1 -0
- package/dist/tools/palace-walk.js +167 -0
- package/dist/tools/palace-walk.js.map +1 -0
- package/dist/tools/palace-write.d.ts +6 -0
- package/dist/tools/palace-write.d.ts.map +1 -0
- package/dist/tools/palace-write.js +108 -0
- package/dist/tools/palace-write.js.map +1 -0
- package/dist/tools/recall-insight.d.ts +9 -0
- package/dist/tools/recall-insight.d.ts.map +1 -0
- package/dist/tools/recall-insight.js +51 -0
- package/dist/tools/recall-insight.js.map +1 -0
- package/dist/types.d.ts +112 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +31 -0
- package/dist/types.js.map +1 -0
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<p align="center">
|
|
8
8
|
<a href="https://www.npmjs.com/package/agent-recall-mcp"><img src="https://img.shields.io/npm/v/agent-recall-mcp?style=flat-square&color=5D34F2" alt="npm"></a>
|
|
9
9
|
<a href="https://github.com/NovadaLabs/AgentRecall/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-brightgreen?style=flat-square" alt="License"></a>
|
|
10
|
-
<img src="https://img.shields.io/badge/MCP-
|
|
10
|
+
<img src="https://img.shields.io/badge/MCP-14_tools-orange?style=flat-square" alt="Tools">
|
|
11
11
|
<img src="https://img.shields.io/badge/protocol-Intelligent_Distance-5B2D8E?style=flat-square" alt="Protocol">
|
|
12
12
|
<img src="https://img.shields.io/badge/cloud-zero-blue?style=flat-square" alt="Zero Cloud">
|
|
13
13
|
</p>
|
|
@@ -85,7 +85,7 @@ Say **"save"** to journal. Say **"read the latest journal"** to resume.
|
|
|
85
85
|
|
|
86
86
|
---
|
|
87
87
|
|
|
88
|
-
##
|
|
88
|
+
## 14 MCP Tools
|
|
89
89
|
|
|
90
90
|
### Session Memory (6 tools)
|
|
91
91
|
|
|
@@ -106,6 +106,13 @@ Say **"save"** to journal. Say **"read the latest journal"** to resume.
|
|
|
106
106
|
| `journal_cold_start` | **Cache-aware cold start** — HOT (today+yesterday), WARM (2-7 days), COLD (7+ days) |
|
|
107
107
|
| `journal_archive` | **Archive old entries** — moves to `archive/` with summaries, keeps journal/ clean |
|
|
108
108
|
|
|
109
|
+
### Knowledge Loop (2 tools) — NEW
|
|
110
|
+
|
|
111
|
+
| Tool | Purpose |
|
|
112
|
+
|------|---------|
|
|
113
|
+
| `knowledge_write` | **Write permanent lessons** — structured entries by category (extraction, build, verification, tools, general). Agents learn from past mistakes. |
|
|
114
|
+
| `knowledge_read` | **Read past lessons** — filter by project, category, or search query. Agents check what went wrong before starting work. |
|
|
115
|
+
|
|
109
116
|
### Alignment & Synthesis (3 tools)
|
|
110
117
|
|
|
111
118
|
| Tool | Purpose |
|
|
@@ -229,3 +236,156 @@ Built by [tongwu](https://github.com/Goldentrii) at [NovadaLabs](https://github.
|
|
|
229
236
|
MIT — *Concept & Design: [tongwu](https://github.com/Goldentrii)*
|
|
230
237
|
|
|
231
238
|
**Memory solves forgetting. AgentRecall solves misunderstanding.**
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
# agent-recall-mcp(中文文档)
|
|
245
|
+
|
|
246
|
+
> 给你的 AI 智能体一个跨会话记忆的大脑。
|
|
247
|
+
|
|
248
|
+
---
|
|
249
|
+
|
|
250
|
+
## 智能距离(Intelligent Distance)— 核心理念
|
|
251
|
+
|
|
252
|
+
> *「人类智能与 AI 智能之间的差距是结构性的、永久的 — 不是一个临时的技术问题。」*
|
|
253
|
+
|
|
254
|
+
人类是「生出来的」(具身经验、情感、生存压力)。机器是「造出来的」(规则、确定性)。AI 是「训练出来的」(数据上的统计共现)。三种不同的认知起源,产生三种不同的理解方式。这个差距不会随 AI 进步而消失 — 因为差异在于**起源**,而非能力。
|
|
255
|
+
|
|
256
|
+
```
|
|
257
|
+
人类说:「全部点击」
|
|
258
|
+
AI 理解:「点击主要的」
|
|
259
|
+
差距:「全部」≠「主要的」
|
|
260
|
+
|
|
261
|
+
人类说:「做完意味着完全一样」
|
|
262
|
+
AI 认为:「差不多就行」
|
|
263
|
+
差距:「完全一样」≠「差不多」
|
|
264
|
+
|
|
265
|
+
人类给出:零散、非线性的指令
|
|
266
|
+
AI 选择:一条指令,忽略其余
|
|
267
|
+
差距:点与点之间的逻辑关联丢失了
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**AgentRecall 不试图缩小这个差距,而是构建一个协议来导航它。**
|
|
271
|
+
|
|
272
|
+
---
|
|
273
|
+
|
|
274
|
+
## AgentRecall 如何弥合差距
|
|
275
|
+
|
|
276
|
+
| 智能距离缺口 | AgentRecall 工具 | 功能 |
|
|
277
|
+
|-------------|-----------------|------|
|
|
278
|
+
| 智能体忘了人类昨天说的话 | `journal_read` + `journal_cold_start` | 三层记忆 + 缓存感知冷启动 |
|
|
279
|
+
| 智能体误解人类意图 | `alignment_check` | 记录置信度 + 假设 → 人类在工作开始前纠正 |
|
|
280
|
+
| 智能体与之前的决策矛盾 | `nudge` | 检测矛盾 → 在造成损失前提出 |
|
|
281
|
+
| 智能体说「完成了」但人类不同意 | Think-Execute-Reflect 循环 | 用数字评分(「建了 11 页 35 个标签」),不用感觉(「做得不错」)|
|
|
282
|
+
| 智能体凭想象构建,而非基于数据 | `journal_state` (JSON) | agent 间结构化交接 — 毫秒级,无需解析散文 |
|
|
283
|
+
| 智能体重复同样的错误 | 失败记录 + `context_synthesize` | 跨会话模式检测 → 提升为永久记忆 |
|
|
284
|
+
| 下一个 agent 从零开始 | `journal_cold_start` (v3) | 热/温/冷缓存 — 加载 3 个文件而非 28 个 |
|
|
285
|
+
|
|
286
|
+
**记忆解决遗忘,AgentRecall 解决误解。**
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## 快速开始
|
|
291
|
+
|
|
292
|
+
```bash
|
|
293
|
+
# Claude Code
|
|
294
|
+
claude mcp add agent-recall -- npx -y agent-recall-mcp
|
|
295
|
+
|
|
296
|
+
# Cursor — .cursor/mcp.json
|
|
297
|
+
{ "mcpServers": { "agent-recall": { "command": "npx", "args": ["-y", "agent-recall-mcp"] } } }
|
|
298
|
+
|
|
299
|
+
# VS Code — .vscode/mcp.json
|
|
300
|
+
{ "servers": { "agent-recall": { "command": "npx", "args": ["-y", "agent-recall-mcp"] } } }
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## 14 个工具
|
|
306
|
+
|
|
307
|
+
### 会话记忆(6 个)
|
|
308
|
+
|
|
309
|
+
| 工具 | 功能 |
|
|
310
|
+
|------|------|
|
|
311
|
+
| `journal_read` | 按日期读取日志,支持章节过滤 |
|
|
312
|
+
| `journal_write` | 追加或替换今日日志 |
|
|
313
|
+
| `journal_capture` | 轻量问答捕获 |
|
|
314
|
+
| `journal_list` | 列出最近日志 |
|
|
315
|
+
| `journal_search` | 全文搜索 |
|
|
316
|
+
| `journal_projects` | 列出所有项目 |
|
|
317
|
+
|
|
318
|
+
### v3 架构(3 个)— 新增
|
|
319
|
+
|
|
320
|
+
| 工具 | 功能 |
|
|
321
|
+
|------|------|
|
|
322
|
+
| `journal_state` | **JSON 状态层** — 结构化读写,agent 间毫秒级交接 |
|
|
323
|
+
| `journal_cold_start` | **缓存感知冷启动** — 热(0-1天)/ 温(2-7天)/ 冷(7天+) |
|
|
324
|
+
| `journal_archive` | **归档旧条目** — 移至 archive/,保留单行摘要 |
|
|
325
|
+
|
|
326
|
+
### 知识循环(2 个)— 新增
|
|
327
|
+
|
|
328
|
+
| 工具 | 功能 |
|
|
329
|
+
|------|------|
|
|
330
|
+
| `knowledge_write` | **写入永久教训** — 按类别结构化记录(提取、构建、验证、工具、通用)。Agent 从过去的错误中学习。 |
|
|
331
|
+
| `knowledge_read` | **读取过去教训** — 按项目、类别或搜索词过滤。Agent 开始工作前检查过去的失败。 |
|
|
332
|
+
|
|
333
|
+
### 对齐 & 合成(3 个)
|
|
334
|
+
|
|
335
|
+
| 工具 | 功能 |
|
|
336
|
+
|------|------|
|
|
337
|
+
| `alignment_check` | 记录理解度、置信度、假设、人类纠正 |
|
|
338
|
+
| `nudge` | 检测矛盾,主动提问 |
|
|
339
|
+
| `context_synthesize` | 跨会话合成:目标演变、决策历史、模式检测 |
|
|
340
|
+
|
|
341
|
+
---
|
|
342
|
+
|
|
343
|
+
## 三层记忆 + v3 缓存
|
|
344
|
+
|
|
345
|
+
```
|
|
346
|
+
┌─────────────────────────────────────────────────────────┐
|
|
347
|
+
│ L1: 工作记忆 [每轮, ~50 tok] 「发生了什么」 │
|
|
348
|
+
│ ↓ 合成为 │
|
|
349
|
+
│ L2: 情景记忆 [每日日志, ~800 tok] 「这意味着什么」 │
|
|
350
|
+
│ ↓ 合成为 │
|
|
351
|
+
│ L3: 语义记忆 [跨会话] 「跨会话的真相」 │
|
|
352
|
+
│ (矛盾检测 + 目标演变追踪) │
|
|
353
|
+
├─────────────────────────────────────────────────────────┤
|
|
354
|
+
│ v3: JSON 状态层 [每会话] agent 间结构化数据 │
|
|
355
|
+
├─────────────────────────────────────────────────────────┤
|
|
356
|
+
│ v3: 缓存层 热(0-1天)→ 温(2-7天)→ 冷(7天+) │
|
|
357
|
+
│ journal_cold_start → 加载 3 个文件而非 28 个 │
|
|
358
|
+
└─────────────────────────────────────────────────────────┘
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## Think-Execute-Reflect 质量循环
|
|
364
|
+
|
|
365
|
+
```
|
|
366
|
+
🧠 THINK → 方法对吗?做了调研吗?
|
|
367
|
+
⚡ EXECUTE → 实际 vs 计划?(用数字,不用感觉)
|
|
368
|
+
🔍 REFLECT → 5 维度质量评分 + 智能距离差距分析
|
|
369
|
+
🔄 FEEDBACK → 循环(需要迭代)或 退出(质量足够)
|
|
370
|
+
```
|
|
371
|
+
|
|
372
|
+
**Reflect 步骤显式测量智能距离:**
|
|
373
|
+
- 用户意图 vs 我的理解
|
|
374
|
+
- 两者之间的差距(或「无 — 已对齐」)
|
|
375
|
+
- 下次如何缩小差距
|
|
376
|
+
|
|
377
|
+
---
|
|
378
|
+
|
|
379
|
+
## 反馈 & 贡献
|
|
380
|
+
|
|
381
|
+
由 [tongwu](https://github.com/Goldentrii) 在 [NovadaLabs](https://github.com/NovadaLabs) 构建。
|
|
382
|
+
|
|
383
|
+
**我们期待你的反馈:**
|
|
384
|
+
- 邮箱:tongwu0824@gmail.com
|
|
385
|
+
- GitHub Issues:[NovadaLabs/AgentRecall](https://github.com/NovadaLabs/AgentRecall/issues)
|
|
386
|
+
|
|
387
|
+
---
|
|
388
|
+
|
|
389
|
+
## 许可证
|
|
390
|
+
|
|
391
|
+
MIT — [tongwu](https://github.com/Goldentrii) @ [NovadaLabs](https://github.com/NovadaLabs)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Journal file listing, reading, and index maintenance.
|
|
3
|
+
*/
|
|
4
|
+
import type { JournalEntry } from "../types.js";
|
|
5
|
+
/**
|
|
6
|
+
* List all .md journal files across all directories for a project.
|
|
7
|
+
* Returns sorted array with most recent first.
|
|
8
|
+
*/
|
|
9
|
+
export declare function listJournalFiles(project: string): JournalEntry[];
|
|
10
|
+
/**
|
|
11
|
+
* Read a journal file. Checks primary dir first, then legacy.
|
|
12
|
+
*/
|
|
13
|
+
export declare function readJournalFile(project: string, date: string): string | null;
|
|
14
|
+
/**
|
|
15
|
+
* Extract title from journal file content.
|
|
16
|
+
*/
|
|
17
|
+
export declare function extractTitle(content: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Extract momentum indicator from journal content.
|
|
20
|
+
*/
|
|
21
|
+
export declare function extractMomentum(content: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Count entries in a log file (for journal_capture entry numbering).
|
|
24
|
+
*/
|
|
25
|
+
export declare function countLogEntries(logPath: string): number;
|
|
26
|
+
/**
|
|
27
|
+
* Update the index.md for a project.
|
|
28
|
+
*/
|
|
29
|
+
export declare function updateIndex(project: string): void;
|
|
30
|
+
//# sourceMappingURL=journal-files.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal-files.d.ts","sourceRoot":"","sources":["../../src/helpers/journal-files.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAmBhE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAa5E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAuBjD"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Journal file listing, reading, and index maintenance.
|
|
3
|
+
*/
|
|
4
|
+
import * as fs from "node:fs";
|
|
5
|
+
import * as path from "node:path";
|
|
6
|
+
import { journalDir, journalDirs } from "../storage/paths.js";
|
|
7
|
+
import { ensureDir } from "../storage/fs-utils.js";
|
|
8
|
+
/**
|
|
9
|
+
* List all .md journal files across all directories for a project.
|
|
10
|
+
* Returns sorted array with most recent first.
|
|
11
|
+
*/
|
|
12
|
+
export function listJournalFiles(project) {
|
|
13
|
+
const dirs = journalDirs(project);
|
|
14
|
+
const entries = [];
|
|
15
|
+
const seen = new Set();
|
|
16
|
+
for (const dir of dirs) {
|
|
17
|
+
if (!fs.existsSync(dir))
|
|
18
|
+
continue;
|
|
19
|
+
const files = fs.readdirSync(dir);
|
|
20
|
+
for (const file of files) {
|
|
21
|
+
const match = file.match(/^(\d{4}-\d{2}-\d{2})\.md$/);
|
|
22
|
+
if (match && !seen.has(match[1])) {
|
|
23
|
+
seen.add(match[1]);
|
|
24
|
+
entries.push({ date: match[1], file, dir });
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
entries.sort((a, b) => b.date.localeCompare(a.date));
|
|
29
|
+
return entries;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Read a journal file. Checks primary dir first, then legacy.
|
|
33
|
+
*/
|
|
34
|
+
export function readJournalFile(project, date) {
|
|
35
|
+
const filename = `${date}.md`;
|
|
36
|
+
const dirs = journalDirs(project);
|
|
37
|
+
const primaryDir = journalDir(project);
|
|
38
|
+
const allDirs = [primaryDir, ...dirs.filter((d) => d !== primaryDir)];
|
|
39
|
+
for (const dir of allDirs) {
|
|
40
|
+
const filePath = path.join(dir, filename);
|
|
41
|
+
if (fs.existsSync(filePath)) {
|
|
42
|
+
return fs.readFileSync(filePath, "utf-8");
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Extract title from journal file content.
|
|
49
|
+
*/
|
|
50
|
+
export function extractTitle(content) {
|
|
51
|
+
const match = content.match(/^# (.+)$/m);
|
|
52
|
+
return match ? match[1].trim() : "(untitled)";
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Extract momentum indicator from journal content.
|
|
56
|
+
*/
|
|
57
|
+
export function extractMomentum(content) {
|
|
58
|
+
const patterns = [/[🟢🟡🔴⚪]\s*\S+/];
|
|
59
|
+
for (const pattern of patterns) {
|
|
60
|
+
const match = content.match(pattern);
|
|
61
|
+
if (match)
|
|
62
|
+
return match[0];
|
|
63
|
+
}
|
|
64
|
+
return "";
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Count entries in a log file (for journal_capture entry numbering).
|
|
68
|
+
*/
|
|
69
|
+
export function countLogEntries(logPath) {
|
|
70
|
+
if (!fs.existsSync(logPath))
|
|
71
|
+
return 0;
|
|
72
|
+
const content = fs.readFileSync(logPath, "utf-8");
|
|
73
|
+
const matches = content.match(/^### Q\d+/gm);
|
|
74
|
+
return matches ? matches.length : 0;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Update the index.md for a project.
|
|
78
|
+
*/
|
|
79
|
+
export function updateIndex(project) {
|
|
80
|
+
const dir = journalDir(project);
|
|
81
|
+
ensureDir(dir);
|
|
82
|
+
const indexPath = path.join(dir, "index.md");
|
|
83
|
+
const entries = listJournalFiles(project);
|
|
84
|
+
let index = `# ${project} — Journal Index\n\n`;
|
|
85
|
+
index += `> Auto-generated. ${entries.length} entries.\n\n`;
|
|
86
|
+
index += `| Date | Title | Momentum |\n`;
|
|
87
|
+
index += `|------|-------|----------|\n`;
|
|
88
|
+
for (const entry of entries) {
|
|
89
|
+
const content = fs.readFileSync(path.join(entry.dir, entry.file), "utf-8");
|
|
90
|
+
const title = extractTitle(content);
|
|
91
|
+
const momentum = extractMomentum(content);
|
|
92
|
+
index += `| ${entry.date} | ${title} | ${momentum} |\n`;
|
|
93
|
+
}
|
|
94
|
+
fs.writeFileSync(indexPath, index, "utf-8");
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=journal-files.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal-files.js","sourceRoot":"","sources":["../../src/helpers/journal-files.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown section extraction and manipulation.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Extract a section from a markdown journal entry.
|
|
6
|
+
*/
|
|
7
|
+
export declare function extractSection(content: string, section: string): string | null;
|
|
8
|
+
/**
|
|
9
|
+
* Append content to a specific section in a journal file, or to end of file.
|
|
10
|
+
*/
|
|
11
|
+
export declare function appendToSection(existingContent: string, newContent: string, section: string | null): string;
|
|
12
|
+
//# sourceMappingURL=sections.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sections.d.ts","sourceRoot":"","sources":["../../src/helpers/sections.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAsC9E;AAED;;GAEG;AACH,wBAAgB,eAAe,CAC7B,eAAe,EAAE,MAAM,EACvB,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GAAG,IAAI,GACrB,MAAM,CA0CR"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Markdown section extraction and manipulation.
|
|
3
|
+
*/
|
|
4
|
+
import { SECTION_HEADERS } from "../types.js";
|
|
5
|
+
/**
|
|
6
|
+
* Extract a section from a markdown journal entry.
|
|
7
|
+
*/
|
|
8
|
+
export function extractSection(content, section) {
|
|
9
|
+
if (section === "all")
|
|
10
|
+
return content;
|
|
11
|
+
if (section === "brief") {
|
|
12
|
+
const lines = content.split("\n");
|
|
13
|
+
const nonEmpty = [];
|
|
14
|
+
let pastTitle = false;
|
|
15
|
+
for (const line of lines) {
|
|
16
|
+
if (line.startsWith("# ")) {
|
|
17
|
+
pastTitle = true;
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
if (!pastTitle)
|
|
21
|
+
continue;
|
|
22
|
+
const trimmed = line.trim();
|
|
23
|
+
if (trimmed === "")
|
|
24
|
+
continue;
|
|
25
|
+
nonEmpty.push(trimmed);
|
|
26
|
+
if (nonEmpty.length >= 4)
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
return nonEmpty.join("\n") || null;
|
|
30
|
+
}
|
|
31
|
+
const header = SECTION_HEADERS[section];
|
|
32
|
+
if (!header)
|
|
33
|
+
return null;
|
|
34
|
+
const idx = content.indexOf(header);
|
|
35
|
+
if (idx === -1)
|
|
36
|
+
return null;
|
|
37
|
+
const afterHeader = content.slice(idx);
|
|
38
|
+
const lines = afterHeader.split("\n");
|
|
39
|
+
const result = [lines[0]];
|
|
40
|
+
let inCodeFence = false;
|
|
41
|
+
for (let i = 1; i < lines.length; i++) {
|
|
42
|
+
if (lines[i].startsWith("```"))
|
|
43
|
+
inCodeFence = !inCodeFence;
|
|
44
|
+
if (!inCodeFence && lines[i].startsWith("## "))
|
|
45
|
+
break;
|
|
46
|
+
result.push(lines[i]);
|
|
47
|
+
}
|
|
48
|
+
return result.join("\n").trimEnd();
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Append content to a specific section in a journal file, or to end of file.
|
|
52
|
+
*/
|
|
53
|
+
export function appendToSection(existingContent, newContent, section) {
|
|
54
|
+
if (section === "replace_all") {
|
|
55
|
+
return newContent;
|
|
56
|
+
}
|
|
57
|
+
if (!section) {
|
|
58
|
+
return existingContent.trimEnd() + "\n\n" + newContent + "\n";
|
|
59
|
+
}
|
|
60
|
+
const header = SECTION_HEADERS[section];
|
|
61
|
+
if (!header) {
|
|
62
|
+
return existingContent.trimEnd() + "\n\n" + newContent + "\n";
|
|
63
|
+
}
|
|
64
|
+
const idx = existingContent.indexOf(header);
|
|
65
|
+
if (idx === -1) {
|
|
66
|
+
return (existingContent.trimEnd() + "\n\n" + header + "\n\n" + newContent + "\n");
|
|
67
|
+
}
|
|
68
|
+
const afterHeader = existingContent.slice(idx);
|
|
69
|
+
const lines = afterHeader.split("\n");
|
|
70
|
+
let insertAt = lines.length;
|
|
71
|
+
let inCodeFence = false;
|
|
72
|
+
for (let i = 1; i < lines.length; i++) {
|
|
73
|
+
if (lines[i].startsWith("```"))
|
|
74
|
+
inCodeFence = !inCodeFence;
|
|
75
|
+
if (!inCodeFence && lines[i].startsWith("## ")) {
|
|
76
|
+
insertAt = i;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const before = existingContent.slice(0, idx + lines.slice(0, insertAt).join("\n").length);
|
|
81
|
+
const after = existingContent.slice(idx + lines.slice(0, insertAt).join("\n").length);
|
|
82
|
+
return before.trimEnd() + "\n\n" + newContent + "\n" + after;
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=sections.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sections.js","sourceRoot":"","sources":["../../src/helpers/sections.ts"],"names":[],"mappings":"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"}
|