@stardustlc/dsh-dream 0.4.1 → 0.5.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.
@@ -0,0 +1,172 @@
1
+ import { type Evidence, type EvidenceInput, type Lesson, type LessonInput, type LessonState, type ReviewDecision } from './knowledge.js';
2
+ /** events.jsonl 默认最多回放的行数(有界读取)。 */
3
+ export declare const MAX_REPLAY_EVENTS = 200000;
4
+ /** KnowledgeStore 构造选项(都可省略,保持 FREEZE 的 constructor(knowledgeDir) 可用)。 */
5
+ export interface KnowledgeStoreOptions {
6
+ /** 写盘前是否按 mask.ts 脱敏;默认 true(与插件默认 maskSecrets=true 一致)。 */
7
+ maskSecrets?: boolean;
8
+ /** 回放行数上限;默认 MAX_REPLAY_EVENTS,测试可调小。 */
9
+ maxReplayEvents?: number;
10
+ /** 获取锁的最长等待毫秒数;默认 2000。 */
11
+ lockTimeoutMs?: number;
12
+ /** 锁年龄超过该毫秒数且 pid 不存活才允许接管;默认 30000。 */
13
+ lockStaleMs?: number;
14
+ /** 锁硬上限:超过且心跳停滞时给可操作错误、不静默抢占;默认 600000(10 分钟)。 */
15
+ lockHardLimitMs?: number;
16
+ /** 心跳刷新间隔毫秒;默认 5000。长回放/压缩也会按行数主动 touch。 */
17
+ lockHeartbeatMs?: number;
18
+ }
19
+ /**
20
+ * 经验知识存储。无文件时所有读取方法安全返回空,写入方法在首次写入时自建目录。
21
+ */
22
+ export declare class KnowledgeStore {
23
+ private readonly dir;
24
+ private readonly eventsPath;
25
+ private readonly evidencePath;
26
+ private readonly indexPath;
27
+ private readonly lockPath;
28
+ private readonly mask;
29
+ private readonly maxReplayEvents;
30
+ private readonly lockTimeoutMs;
31
+ private readonly lockStaleMs;
32
+ private readonly lockHardLimitMs;
33
+ private readonly lockHeartbeatMs;
34
+ private lastIndexError?;
35
+ constructor(knowledgeDir: string, options?: KnowledgeStoreOptions);
36
+ /** 全部经验,按 updatedAt 降序(同刻按 id 稳定排序)。 */
37
+ listLessons(): Lesson[];
38
+ /** 全部证据,按 observedAt 升序(同刻按 id 稳定排序)。 */
39
+ listEvidence(): Evidence[];
40
+ /** 按 id 取经验;不存在返回 undefined。 */
41
+ getLesson(id: string): Lesson | undefined;
42
+ /** 追加证据;同 sessionId+recordSeq 或同 sourceHash 视为重复,返回已有记录且不写。 */
43
+ appendEvidence(input: EvidenceInput): {
44
+ evidence: Evidence;
45
+ created: boolean;
46
+ };
47
+ /**
48
+ * 创建候选经验。同 idempotencyKey + 同 requestHash 幂等;同指纹(文本 + 范围相同)确定性合并,
49
+ * 只把新证据并入已有经验,不新增经验。
50
+ * R2′:有 read 证据 → 初始 usable(含 user-correction read 时 review=accepted/user);只有 claimed 或无证据 → candidate。
51
+ */
52
+ createLesson(input: LessonInput, idempotencyKey: string): {
53
+ lesson: Lesson;
54
+ created: boolean;
55
+ };
56
+ /** 按 patch 更新经验;revision 不符抛 KnowledgeError('revision')(details 带 currentRevision)且不写。 */
57
+ updateLesson(id: string, patch: Partial<Lesson>, expectedRevision: number, idempotencyKey: string): Lesson;
58
+ /** 审阅经验:accepted → usable,rejected → rejected,unreviewed → candidate。 */
59
+ reviewLesson(id: string, decision: ReviewDecision, expectedRevision: number, idempotencyKey: string, actor?: string): Lesson;
60
+ /** 状态迁移;不允许的迁移抛 KnowledgeError('invalid') 且不写。 */
61
+ applyTransition(id: string, to: LessonState, expectedRevision: number, idempotencyKey: string): Lesson;
62
+ /** 从事件完整重建派生索引与 checkpoint;不删除、不改写 events.jsonl / evidence.jsonl。 */
63
+ rebuildIndex(): void;
64
+ /** 统计。truncated=true 表示事件总量超过有界回放上限(不静默);快照模式下实体已折叠进 checkpoint。 */
65
+ stats(): {
66
+ lessons: number;
67
+ evidence: number;
68
+ events: number;
69
+ byState: Record<LessonState, number>;
70
+ truncated: boolean;
71
+ badLines: number;
72
+ orphanEvents: number;
73
+ unsupportedVersions: number;
74
+ firstReplayedEventId?: string;
75
+ replayMode: 'full' | 'snapshot+tail';
76
+ replayedEvents: number;
77
+ skippedEvents: number;
78
+ };
79
+ /** 只读诊断:锁、文件、计数与最近一次派生索引写失败;绝不获取锁、绝不写盘。 */
80
+ diagnose(): {
81
+ writable: boolean;
82
+ lock: {
83
+ present: boolean;
84
+ ageMs?: number;
85
+ pid?: number;
86
+ alive?: boolean;
87
+ bootId?: string;
88
+ stale: boolean;
89
+ };
90
+ files: {
91
+ dir: string;
92
+ events: {
93
+ path: string;
94
+ exists: boolean;
95
+ bytes: number;
96
+ };
97
+ evidence: {
98
+ path: string;
99
+ exists: boolean;
100
+ bytes: number;
101
+ };
102
+ index: {
103
+ path: string;
104
+ exists: boolean;
105
+ bytes: number;
106
+ generatedAt?: string;
107
+ };
108
+ };
109
+ counts: {
110
+ lessons: number;
111
+ evidence: number;
112
+ events: number;
113
+ badLines: number;
114
+ orphanEvents: number;
115
+ unsupportedVersions: number;
116
+ truncated: boolean;
117
+ byState: Record<LessonState, number>;
118
+ };
119
+ lastIndexError?: {
120
+ message: string;
121
+ at: string;
122
+ };
123
+ };
124
+ private ensureDir;
125
+ private withLock;
126
+ private fileInfo;
127
+ private hashRequest;
128
+ private hashablePatch;
129
+ private cleanPatch;
130
+ private assertSameRequest;
131
+ /**
132
+ * 恢复"首次结果":
133
+ * - 尾部回放产生的 entry 自带快照,直接返回;
134
+ * - checkpoint 里的 entry 只有 lessonId/requestHash,则做一次有针对性的完整扫描,
135
+ * 在命中该幂等键的那一刻取快照;失败再退回当前实体(best effort)。
136
+ */
137
+ private resolveIdempotentLesson;
138
+ private replayUntilIdempotencyKey;
139
+ /** 顺序读取 JSONL 的非空行;每 TOUCH_EVERY_LINES 行调用一次 touch(长回放锁心跳)。 */
140
+ private forEachLine;
141
+ /** 有界读取:只保留最后 maxReplayEvents 条非空行,并报告总行数与是否截断。 */
142
+ private readBoundedLines;
143
+ /** 快照 + 尾部增量(checkpoint 有效时);否则有界全量回放。 */
144
+ private loadEvents;
145
+ private loadEventsBounded;
146
+ /** 无界完整回放(显式压缩 / 写路径发现截断或状态不完整时使用)。 */
147
+ private loadAllUnbounded;
148
+ /** 事件流 + evidence.jsonl(两条路径都留痕,按 id 合并去重)。 */
149
+ private loadAll;
150
+ /** 写路径:状态不完整、证据疑似缺失或截断未折叠时,自动做一次完整回放。 */
151
+ private loadCompleteState;
152
+ private hasMissingEvidenceRefs;
153
+ private mergeEvidenceFile;
154
+ private applyEventLine;
155
+ private appendEvent;
156
+ private appendLine;
157
+ private findEvidenceByNaturalKey;
158
+ /** 在锁内追加/复用一条证据;同天然身份键返回已有记录且不写。 */
159
+ private persistEvidenceLocked;
160
+ /** 在锁内追加 lesson.update 并同步内存与索引。 */
161
+ private appendLessonUpdate;
162
+ private maskLesson;
163
+ private maskEvidence;
164
+ private hashPrefix;
165
+ private readLastLineId;
166
+ private tryLoadCheckpoint;
167
+ private buildCheckpoint;
168
+ private buildIndexPayload;
169
+ /** 自动更新派生索引:失败降级(权威事件已落盘),记录 lastIndexError 供 diagnose()。 */
170
+ private writeIndex;
171
+ private writeIndexStrict;
172
+ }