trove-cli 0.0.0-stage → 0.2.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.
Files changed (210) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +200 -2
  3. package/dist/adapters/file-source.d.ts +31 -0
  4. package/dist/adapters/file-source.js +97 -0
  5. package/dist/adapters/file-source.js.map +1 -0
  6. package/dist/adapters/index.d.ts +34 -0
  7. package/dist/adapters/index.js +146 -0
  8. package/dist/adapters/index.js.map +1 -0
  9. package/dist/adapters/opencode.d.ts +30 -0
  10. package/dist/adapters/opencode.js +135 -0
  11. package/dist/adapters/opencode.js.map +1 -0
  12. package/dist/cli.d.ts +58 -0
  13. package/dist/cli.js +972 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/config.d.ts +81 -0
  16. package/dist/config.js +99 -0
  17. package/dist/config.js.map +1 -0
  18. package/dist/core/archive.d.ts +27 -0
  19. package/dist/core/archive.js +101 -0
  20. package/dist/core/archive.js.map +1 -0
  21. package/dist/core/chunker.d.ts +28 -0
  22. package/dist/core/chunker.js +67 -0
  23. package/dist/core/chunker.js.map +1 -0
  24. package/dist/core/clean.d.ts +36 -0
  25. package/dist/core/clean.js +182 -0
  26. package/dist/core/clean.js.map +1 -0
  27. package/dist/core/collect.d.ts +39 -0
  28. package/dist/core/collect.js +194 -0
  29. package/dist/core/collect.js.map +1 -0
  30. package/dist/core/concurrency.d.ts +2 -0
  31. package/dist/core/concurrency.js +16 -0
  32. package/dist/core/concurrency.js.map +1 -0
  33. package/dist/core/cursor.d.ts +31 -0
  34. package/dist/core/cursor.js +31 -0
  35. package/dist/core/cursor.js.map +1 -0
  36. package/dist/core/events/claude.d.ts +7 -0
  37. package/dist/core/events/claude.js +287 -0
  38. package/dist/core/events/claude.js.map +1 -0
  39. package/dist/core/events/codex.d.ts +6 -0
  40. package/dist/core/events/codex.js +149 -0
  41. package/dist/core/events/codex.js.map +1 -0
  42. package/dist/core/events/doubao.d.ts +9 -0
  43. package/dist/core/events/doubao.js +151 -0
  44. package/dist/core/events/doubao.js.map +1 -0
  45. package/dist/core/events/index.d.ts +6 -0
  46. package/dist/core/events/index.js +20 -0
  47. package/dist/core/events/index.js.map +1 -0
  48. package/dist/core/events/opencode.d.ts +7 -0
  49. package/dist/core/events/opencode.js +189 -0
  50. package/dist/core/events/opencode.js.map +1 -0
  51. package/dist/core/events/schema.d.ts +83 -0
  52. package/dist/core/events/schema.js +35 -0
  53. package/dist/core/events/schema.js.map +1 -0
  54. package/dist/core/layout.d.ts +26 -0
  55. package/dist/core/layout.js +122 -0
  56. package/dist/core/layout.js.map +1 -0
  57. package/dist/core/lessons/analyze.d.ts +40 -0
  58. package/dist/core/lessons/analyze.js +107 -0
  59. package/dist/core/lessons/analyze.js.map +1 -0
  60. package/dist/core/lessons/audit.d.ts +51 -0
  61. package/dist/core/lessons/audit.js +57 -0
  62. package/dist/core/lessons/audit.js.map +1 -0
  63. package/dist/core/lessons/compaction.d.ts +5 -0
  64. package/dist/core/lessons/compaction.js +58 -0
  65. package/dist/core/lessons/compaction.js.map +1 -0
  66. package/dist/core/lessons/config.d.ts +15 -0
  67. package/dist/core/lessons/config.js +31 -0
  68. package/dist/core/lessons/config.js.map +1 -0
  69. package/dist/core/lessons/existing.d.ts +4 -0
  70. package/dist/core/lessons/existing.js +22 -0
  71. package/dist/core/lessons/existing.js.map +1 -0
  72. package/dist/core/lessons/extract.d.ts +21 -0
  73. package/dist/core/lessons/extract.js +106 -0
  74. package/dist/core/lessons/extract.js.map +1 -0
  75. package/dist/core/lessons/frontmatter.d.ts +29 -0
  76. package/dist/core/lessons/frontmatter.js +87 -0
  77. package/dist/core/lessons/frontmatter.js.map +1 -0
  78. package/dist/core/lessons/graph.d.ts +256 -0
  79. package/dist/core/lessons/graph.js +86 -0
  80. package/dist/core/lessons/graph.js.map +1 -0
  81. package/dist/core/lessons/jev.d.ts +36 -0
  82. package/dist/core/lessons/jev.js +100 -0
  83. package/dist/core/lessons/jev.js.map +1 -0
  84. package/dist/core/lessons/layout.d.ts +2 -0
  85. package/dist/core/lessons/layout.js +56 -0
  86. package/dist/core/lessons/layout.js.map +1 -0
  87. package/dist/core/lessons/learn.d.ts +38 -0
  88. package/dist/core/lessons/learn.js +190 -0
  89. package/dist/core/lessons/learn.js.map +1 -0
  90. package/dist/core/lessons/llm.d.ts +42 -0
  91. package/dist/core/lessons/llm.js +106 -0
  92. package/dist/core/lessons/llm.js.map +1 -0
  93. package/dist/core/lessons/memo.d.ts +19 -0
  94. package/dist/core/lessons/memo.js +170 -0
  95. package/dist/core/lessons/memo.js.map +1 -0
  96. package/dist/core/lessons/merge.d.ts +39 -0
  97. package/dist/core/lessons/merge.js +79 -0
  98. package/dist/core/lessons/merge.js.map +1 -0
  99. package/dist/core/lessons/queue.d.ts +6 -0
  100. package/dist/core/lessons/queue.js +52 -0
  101. package/dist/core/lessons/queue.js.map +1 -0
  102. package/dist/core/lessons/recent.d.ts +21 -0
  103. package/dist/core/lessons/recent.js +111 -0
  104. package/dist/core/lessons/recent.js.map +1 -0
  105. package/dist/core/lessons/schema.d.ts +26 -0
  106. package/dist/core/lessons/schema.js +64 -0
  107. package/dist/core/lessons/schema.js.map +1 -0
  108. package/dist/core/lessons/select.d.ts +19 -0
  109. package/dist/core/lessons/select.js +55 -0
  110. package/dist/core/lessons/select.js.map +1 -0
  111. package/dist/core/lessons/sidecar.d.ts +23 -0
  112. package/dist/core/lessons/sidecar.js +171 -0
  113. package/dist/core/lessons/sidecar.js.map +1 -0
  114. package/dist/core/lessons/storage.d.ts +21 -0
  115. package/dist/core/lessons/storage.js +65 -0
  116. package/dist/core/lessons/storage.js.map +1 -0
  117. package/dist/core/lessons/usage.d.ts +31 -0
  118. package/dist/core/lessons/usage.js +91 -0
  119. package/dist/core/lessons/usage.js.map +1 -0
  120. package/dist/core/lessons/write.d.ts +18 -0
  121. package/dist/core/lessons/write.js +131 -0
  122. package/dist/core/lessons/write.js.map +1 -0
  123. package/dist/core/library/build.d.ts +22 -0
  124. package/dist/core/library/build.js +163 -0
  125. package/dist/core/library/build.js.map +1 -0
  126. package/dist/core/library/group.d.ts +14 -0
  127. package/dist/core/library/group.js +129 -0
  128. package/dist/core/library/group.js.map +1 -0
  129. package/dist/core/library/index-file.d.ts +7 -0
  130. package/dist/core/library/index-file.js +250 -0
  131. package/dist/core/library/index-file.js.map +1 -0
  132. package/dist/core/library/schema.d.ts +78 -0
  133. package/dist/core/library/schema.js +37 -0
  134. package/dist/core/library/schema.js.map +1 -0
  135. package/dist/core/library/skills.d.ts +26 -0
  136. package/dist/core/library/skills.js +168 -0
  137. package/dist/core/library/skills.js.map +1 -0
  138. package/dist/core/library/sync.d.ts +48 -0
  139. package/dist/core/library/sync.js +271 -0
  140. package/dist/core/library/sync.js.map +1 -0
  141. package/dist/core/lock.d.ts +6 -0
  142. package/dist/core/lock.js +56 -0
  143. package/dist/core/lock.js.map +1 -0
  144. package/dist/core/pull.d.ts +23 -0
  145. package/dist/core/pull.js +147 -0
  146. package/dist/core/pull.js.map +1 -0
  147. package/dist/core/push.d.ts +29 -0
  148. package/dist/core/push.js +170 -0
  149. package/dist/core/push.js.map +1 -0
  150. package/dist/core/remote-layout.d.ts +67 -0
  151. package/dist/core/remote-layout.js +94 -0
  152. package/dist/core/remote-layout.js.map +1 -0
  153. package/dist/core/sessions.d.ts +29 -0
  154. package/dist/core/sessions.js +96 -0
  155. package/dist/core/sessions.js.map +1 -0
  156. package/dist/core/state.d.ts +94 -0
  157. package/dist/core/state.js +62 -0
  158. package/dist/core/state.js.map +1 -0
  159. package/dist/core/sync.d.ts +48 -0
  160. package/dist/core/sync.js +140 -0
  161. package/dist/core/sync.js.map +1 -0
  162. package/dist/core/time-window.d.ts +8 -0
  163. package/dist/core/time-window.js +36 -0
  164. package/dist/core/time-window.js.map +1 -0
  165. package/dist/daemon.d.ts +73 -0
  166. package/dist/daemon.js +272 -0
  167. package/dist/daemon.js.map +1 -0
  168. package/dist/format.d.ts +4 -0
  169. package/dist/format.js +28 -0
  170. package/dist/format.js.map +1 -0
  171. package/dist/main.d.ts +2 -0
  172. package/dist/main.js +9 -0
  173. package/dist/main.js.map +1 -0
  174. package/dist/paths.d.ts +19 -0
  175. package/dist/paths.js +19 -0
  176. package/dist/paths.js.map +1 -0
  177. package/dist/progress-console.d.ts +12 -0
  178. package/dist/progress-console.js +42 -0
  179. package/dist/progress-console.js.map +1 -0
  180. package/dist/progress.d.ts +7 -0
  181. package/dist/progress.js +6 -0
  182. package/dist/progress.js.map +1 -0
  183. package/dist/remote/create-remote.d.ts +20 -0
  184. package/dist/remote/create-remote.js +86 -0
  185. package/dist/remote/create-remote.js.map +1 -0
  186. package/dist/remote/prompt.d.ts +17 -0
  187. package/dist/remote/prompt.js +111 -0
  188. package/dist/remote/prompt.js.map +1 -0
  189. package/dist/remote/s3-sigv4.d.ts +28 -0
  190. package/dist/remote/s3-sigv4.js +100 -0
  191. package/dist/remote/s3-sigv4.js.map +1 -0
  192. package/dist/remote/s3-store.d.ts +75 -0
  193. package/dist/remote/s3-store.js +438 -0
  194. package/dist/remote/s3-store.js.map +1 -0
  195. package/dist/remote/s3-vendors.d.ts +31 -0
  196. package/dist/remote/s3-vendors.js +47 -0
  197. package/dist/remote/s3-vendors.js.map +1 -0
  198. package/dist/remote/store.d.ts +44 -0
  199. package/dist/remote/store.js +2 -0
  200. package/dist/remote/store.js.map +1 -0
  201. package/dist/remote/webdav-store.d.ts +41 -0
  202. package/dist/remote/webdav-store.js +285 -0
  203. package/dist/remote/webdav-store.js.map +1 -0
  204. package/dist/sqlite.d.ts +3 -0
  205. package/dist/sqlite.js +12 -0
  206. package/dist/sqlite.js.map +1 -0
  207. package/dist/status.d.ts +82 -0
  208. package/dist/status.js +162 -0
  209. package/dist/status.js.map +1 -0
  210. package/package.json +43 -4
@@ -0,0 +1,20 @@
1
+ import { EVENTS_PREFIX } from './schema.js';
2
+ import { mapClaude } from './claude.js';
3
+ import { mapCodex } from './codex.js';
4
+ import { mapOpencode } from './opencode.js';
5
+ import { mapDoubao } from './doubao.js';
6
+ /** 已实现映射的 harness;没有 mapper 的源只保留 raw。 */
7
+ const mappers = {
8
+ 'claude-code': mapClaude,
9
+ codex: mapCodex,
10
+ opencode: mapOpencode,
11
+ doubao: mapDoubao,
12
+ };
13
+ export function hasMapper(harness) {
14
+ return Boolean(mappers[harness]);
15
+ }
16
+ /** 把一组 raw 文件映射成事件流(纯函数,供 library 构建使用)。 */
17
+ export function mapSession(harness, files) {
18
+ return mappers[harness]?.(files) ?? [];
19
+ }
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/events/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAA+B,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAIxC,0CAA0C;AAC1C,MAAM,OAAO,GAAuC;IAClD,aAAa,EAAE,SAAS;IACxB,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE,WAAW;IACrB,MAAM,EAAE,SAAS;CAClB,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,OAAkB;IAC1C,OAAO,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;AACnC,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,UAAU,CAAC,OAAkB,EAAE,KAAmB;IAChE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;AACzC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import type { Event, MapperFile } from './schema.js';
2
+ /**
3
+ * OpenCode:trove 导出的逐会话 JSONL(一行一个数据库行)。
4
+ * `session_message` 是权威对话,旧表 `message`/`part` 是第二套序列化——对话层不重复映射,
5
+ * 需要的字段仍可从 raw 回查。
6
+ */
7
+ export declare function mapOpencode(files: MapperFile[]): Event[];
@@ -0,0 +1,189 @@
1
+ import { compact, firstLine, isoTime } from './schema.js';
2
+ function isObj(v) {
3
+ return typeof v === 'object' && v !== null;
4
+ }
5
+ /** OpenCode 的 model 列是 JSON 字符串(或对象),统一成 {id, provider}。 */
6
+ function parseModel(value) {
7
+ const raw = typeof value === 'string' ? safeJson(value) : value;
8
+ if (!isObj(raw))
9
+ return undefined;
10
+ const id = raw['id'];
11
+ const provider = raw['providerID'];
12
+ if (typeof id !== 'string' && typeof provider !== 'string')
13
+ return undefined;
14
+ return compact({
15
+ id: typeof id === 'string' ? id : undefined,
16
+ provider: typeof provider === 'string' ? provider : undefined,
17
+ });
18
+ }
19
+ function safeJson(text) {
20
+ try {
21
+ return JSON.parse(text);
22
+ }
23
+ catch {
24
+ return undefined;
25
+ }
26
+ }
27
+ /** tool.state.output 可能是字符串、数组或对象,统一成可读字符串。 */
28
+ function outputOf(state) {
29
+ const out = state['output'] ?? state['content'];
30
+ if (typeof out === 'string')
31
+ return out || undefined;
32
+ if (Array.isArray(out)) {
33
+ const text = out
34
+ .filter(isObj)
35
+ .map((b) => (typeof b['text'] === 'string' ? b['text'] : ''))
36
+ .filter(Boolean)
37
+ .join('\n');
38
+ return text || undefined;
39
+ }
40
+ if (out !== undefined)
41
+ return JSON.stringify(out);
42
+ return undefined;
43
+ }
44
+ function usageOf(tokens) {
45
+ if (!isObj(tokens))
46
+ return undefined;
47
+ const cache = isObj(tokens['cache']) ? tokens['cache'] : {};
48
+ const usage = compact({
49
+ input: typeof tokens['input'] === 'number' ? tokens['input'] : undefined,
50
+ output: typeof tokens['output'] === 'number' ? tokens['output'] : undefined,
51
+ reasoning: typeof tokens['reasoning'] === 'number' ? tokens['reasoning'] : undefined,
52
+ cache_read: typeof cache['read'] === 'number' ? cache['read'] : undefined,
53
+ cache_write: typeof cache['write'] === 'number' ? cache['write'] : undefined,
54
+ });
55
+ // 0 与缺失同义(计数器),只保留非零值
56
+ for (const k of Object.keys(usage)) {
57
+ if (!usage[k])
58
+ delete usage[k];
59
+ }
60
+ return Object.keys(usage).length ? usage : undefined;
61
+ }
62
+ /**
63
+ * OpenCode:trove 导出的逐会话 JSONL(一行一个数据库行)。
64
+ * `session_message` 是权威对话,旧表 `message`/`part` 是第二套序列化——对话层不重复映射,
65
+ * 需要的字段仍可从 raw 回查。
66
+ */
67
+ export function mapOpencode(files) {
68
+ const lines = [];
69
+ for (const file of files) {
70
+ const parts = file.text.split('\n');
71
+ for (let i = 0; i < parts.length; i++) {
72
+ const raw = parts[i];
73
+ if (!raw.trim())
74
+ continue;
75
+ const o = safeJson(raw);
76
+ if (isObj(o))
77
+ lines.push({ file, line: i + 1, o });
78
+ }
79
+ }
80
+ const rowOf = (l) => isObj(l.o['row']) ? l.o['row'] : {};
81
+ const sessionRow = lines.find((l) => l.o['table'] === 'session_v2') ?? lines.find((l) => l.o['table'] === 'session');
82
+ const head = sessionRow ? rowOf(sessionRow) : {};
83
+ const session = String(head['id'] ?? '');
84
+ const messages = lines.filter((l) => l.o['table'] === 'session_message');
85
+ const firstUser = messages.find((l) => rowOf(l)['type'] === 'user');
86
+ const dataOf = (l) => {
87
+ const d = rowOf(l)['data'];
88
+ const parsed = typeof d === 'string' ? safeJson(d) : d;
89
+ return isObj(parsed) ? parsed : {};
90
+ };
91
+ const firstText = firstUser ? dataOf(firstUser)['text'] : undefined;
92
+ const startedAt = isoTime(head['time_created']);
93
+ // 没有会话行或没有消息:不产生对话层
94
+ if (!session || !messages.length)
95
+ return [];
96
+ const events = [
97
+ compact({
98
+ v: 1,
99
+ ts: startedAt,
100
+ seq: 0,
101
+ harness: 'opencode',
102
+ session,
103
+ kind: 'session',
104
+ id: session,
105
+ title: head['title'],
106
+ firstText: firstLine(firstText),
107
+ startedAt: startedAt || undefined,
108
+ cwd: head['directory'],
109
+ model: parseModel(head['model']),
110
+ raw: sessionRow ? { path: sessionRow.file.rawPath, line: sessionRow.line } : undefined,
111
+ }),
112
+ ];
113
+ for (const parsed of messages) {
114
+ const { file, line } = parsed;
115
+ const row = rowOf(parsed);
116
+ const data = dataOf(parsed);
117
+ const kind = row['type'];
118
+ const ts = isoTime(row['time_created']);
119
+ const usage = usageOf(data['tokens']);
120
+ const model = parseModel(data['model']);
121
+ const base = {
122
+ v: 1,
123
+ ts,
124
+ seq: typeof row['seq'] === 'number' ? row['seq'] : events.length,
125
+ harness: 'opencode',
126
+ session,
127
+ model,
128
+ usage,
129
+ raw: { path: file.rawPath, line },
130
+ };
131
+ const id = row['id'];
132
+ if (kind === 'user') {
133
+ events.push(compact({ ...base, kind: 'message', role: 'user', id, text: data['text'] }));
134
+ }
135
+ else if (kind === 'assistant') {
136
+ for (const part of Array.isArray(data['content']) ? data['content'] : []) {
137
+ if (!isObj(part))
138
+ continue;
139
+ const type = part['type'];
140
+ if (type === 'reasoning' && typeof part['text'] === 'string') {
141
+ events.push(compact({ ...base, kind: 'reasoning', role: 'assistant', text: part['text'] }));
142
+ }
143
+ else if (type === 'text' && typeof part['text'] === 'string') {
144
+ events.push(compact({ ...base, kind: 'message', role: 'assistant', id, text: part['text'] }));
145
+ }
146
+ else if (type === 'tool') {
147
+ const state = isObj(part['state']) ? part['state'] : {};
148
+ const callId = part['id'] ?? part['callID'];
149
+ events.push(compact({
150
+ ...base,
151
+ kind: 'tool_call',
152
+ role: 'assistant',
153
+ id: callId,
154
+ tool: { name: part['name'], call_id: callId, input: state['input'] },
155
+ }));
156
+ const output = outputOf(state);
157
+ if (output !== undefined) {
158
+ events.push(compact({
159
+ ...base,
160
+ kind: 'tool_result',
161
+ role: 'tool',
162
+ id: callId,
163
+ result: {
164
+ call_id: callId,
165
+ status: state['status'] === 'error' ? 'error' : 'ok',
166
+ output,
167
+ },
168
+ }));
169
+ }
170
+ }
171
+ }
172
+ }
173
+ else if (kind === 'system' || kind === 'synthetic') {
174
+ events.push(compact({
175
+ ...base,
176
+ kind: 'message',
177
+ role: 'system',
178
+ id,
179
+ text: data['text'],
180
+ extra: kind === 'synthetic' ? { synthetic: true } : undefined,
181
+ }));
182
+ }
183
+ else {
184
+ events.push(compact({ ...base, kind: 'meta', id, extra: { native_type: kind } }));
185
+ }
186
+ }
187
+ return events;
188
+ }
189
+ //# sourceMappingURL=opencode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../../src/core/events/opencode.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import type { HarnessId } from '../../adapters/index.js';
2
+ /** 对话层文件在 harness 目录下的前缀。 */
3
+ export declare const EVENTS_PREFIX = "_events/";
4
+ /** 对话层格式版本:映射逻辑变化时递增,collect 会据此重生成(旧事件文件自动换个世代)。 */
5
+ export declare const EVENTS_FORMAT_VERSION = 4;
6
+ export type EventKind = 'session' | 'message' | 'reasoning' | 'tool_call' | 'tool_result' | 'meta';
7
+ export type EventRole = 'user' | 'assistant' | 'system' | 'tool';
8
+ export interface EventPart {
9
+ type: string;
10
+ text?: string;
11
+ mime?: string;
12
+ name?: string;
13
+ }
14
+ /** 一个待映射的原始文件。 */
15
+ export interface MapperFile {
16
+ /** 相对 harness 目录的路径,如 `projects/x.jsonl` */
17
+ relPath: string;
18
+ /** 完整 raw 路径(相对 vault),如 `raw/dev1/claude-code/projects/x.jsonl` */
19
+ rawPath: string;
20
+ text: string;
21
+ /** 文件级线程归属(Claude 子代理文件) */
22
+ thread?: string;
23
+ }
24
+ export interface EventUsage {
25
+ input?: number;
26
+ output?: number;
27
+ cache_read?: number;
28
+ cache_write?: number;
29
+ reasoning?: number;
30
+ }
31
+ /**
32
+ * 一条对话层事件。`raw` 回指 vault 内的原始文件与行号,
33
+ * 事件里没映射到的内容(注入上下文、图片二进制、旧序列化字段)都能凭它反查。
34
+ */
35
+ export interface Event {
36
+ v: 1; /** ISO-8601 UTC 毫秒;源里没有则为空串 */
37
+ ts: string;
38
+ /** 会话内递增序号,从 0 开始(0 固定是 session 头) */
39
+ seq: number;
40
+ harness: HarnessId;
41
+ session: string;
42
+ kind: EventKind;
43
+ role?: EventRole;
44
+ id?: string;
45
+ text?: string;
46
+ parts?: EventPart[];
47
+ tool?: {
48
+ name?: string;
49
+ call_id?: string;
50
+ input?: unknown;
51
+ };
52
+ result?: {
53
+ call_id?: string;
54
+ status?: 'ok' | 'error';
55
+ output?: unknown;
56
+ };
57
+ usage?: EventUsage;
58
+ model?: {
59
+ provider?: string;
60
+ id?: string;
61
+ };
62
+ cwd?: string;
63
+ /** 子代理 / sidechain / 豆包 agent */
64
+ thread?: string;
65
+ /** raw 路径相对 vault/devices/<device>/,如 claude-code/projects/x.jsonl */
66
+ raw?: {
67
+ path: string;
68
+ line: number;
69
+ };
70
+ /** 未映射的原生字段,保留但不保证语义 */
71
+ extra?: Record<string, unknown>;
72
+ title?: string;
73
+ /** 该会话的 raw 来源(完整路径),仅 session 头 */
74
+ sources?: string[];
75
+ firstText?: string;
76
+ startedAt?: string;
77
+ }
78
+ /** 数字时间戳(ms)或字符串 → ISO-8601 UTC;无法解析返回空串。 */
79
+ export declare function isoTime(value: unknown): string;
80
+ /** 去掉 undefined/空串字段,避免事件里出现大量 null。 */
81
+ export declare function compact<T extends Record<string, unknown>>(obj: T): T;
82
+ /** 把一段文本截成列表页要的一行摘要。 */
83
+ export declare function firstLine(text: string | undefined, max?: number): string | undefined;
@@ -0,0 +1,35 @@
1
+ /** 对话层文件在 harness 目录下的前缀。 */
2
+ export const EVENTS_PREFIX = '_events/';
3
+ /** 对话层格式版本:映射逻辑变化时递增,collect 会据此重生成(旧事件文件自动换个世代)。 */
4
+ export const EVENTS_FORMAT_VERSION = 4;
5
+ /** 数字时间戳(ms)或字符串 → ISO-8601 UTC;无法解析返回空串。 */
6
+ export function isoTime(value) {
7
+ if (typeof value === 'number' && Number.isFinite(value))
8
+ return new Date(value).toISOString();
9
+ if (typeof value === 'string' && value.trim()) {
10
+ const t = Date.parse(value);
11
+ if (Number.isFinite(t))
12
+ return new Date(t).toISOString();
13
+ }
14
+ return '';
15
+ }
16
+ /** 去掉 undefined/空串字段,避免事件里出现大量 null。 */
17
+ export function compact(obj) {
18
+ const out = {};
19
+ for (const [k, v] of Object.entries(obj)) {
20
+ if (v === undefined || v === '' || v === null)
21
+ continue;
22
+ out[k] = v;
23
+ }
24
+ return out;
25
+ }
26
+ /** 把一段文本截成列表页要的一行摘要。 */
27
+ export function firstLine(text, max = 120) {
28
+ if (!text)
29
+ return undefined;
30
+ const line = text.replace(/\s+/g, ' ').trim();
31
+ if (!line)
32
+ return undefined;
33
+ return line.length > max ? `${line.slice(0, max)}…` : line;
34
+ }
35
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/core/events/schema.ts"],"names":[],"mappings":"AAEA,6BAA6B;AAC7B,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC;AAExC,qDAAqD;AACrD,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC;AAkEvC,6CAA6C;AAC7C,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,CAAC;IAC9F,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAC5B,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC3D,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,OAAO,CAAoC,GAAM;IAC/D,MAAM,GAAG,GAA4B,EAAE,CAAC;IACxC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACzC,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI;YAAE,SAAS;QACxD,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACb,CAAC;IACD,OAAO,GAAQ,CAAC;AAClB,CAAC;AAED,wBAAwB;AACxB,MAAM,UAAU,SAAS,CAAC,IAAwB,EAAE,GAAG,GAAG,GAAG;IAC3D,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,IAAI,CAAC,IAAI;QAAE,OAAO,SAAS,CAAC;IAC5B,OAAO,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7D,CAAC"}
@@ -0,0 +1,26 @@
1
+ /** 设备事实层的目录名(原 `devices`)。 */
2
+ export declare const RAW_DIR = "raw";
3
+ /** 个人资产层的目录名。 */
4
+ export declare const LIBRARY_DIR = "library";
5
+ export declare function rawDeviceDir(vaultRoot: string, deviceId: string): string;
6
+ export declare function rawFilePath(vaultRoot: string, deviceId: string, harness: string, relPath: string): string;
7
+ export declare function libraryDir(vaultRoot: string): string;
8
+ export declare function librarySessionsDir(vaultRoot: string): string;
9
+ export declare function libraryIndexDir(vaultRoot: string): string;
10
+ export declare function librarySkillsDir(vaultRoot: string): string;
11
+ export declare function libraryLessonsDir(vaultRoot: string): string;
12
+ /** 会话 id 作为目录名:不安全字符替换,发生替换时附 hash 防碰撞。 */
13
+ export declare function safeSessionName(id: string): string;
14
+ /** 单设备会话文件:library/sessions/<harness>/<session>/<device>.jsonl */
15
+ export declare function librarySessionRelPath(harness: string, sessionId: string, deviceId: string): string;
16
+ /** 多设备并集文件:library/sessions/<harness>/<session>/merged.<hash8>.jsonl */
17
+ export declare function libraryMergedRelPath(harness: string, sessionId: string, hash: string): string;
18
+ /** 建立 library 骨架(幂等);lessons 先留说明文件。 */
19
+ export declare function ensureLibraryLayout(vaultRoot: string): Promise<void>;
20
+ /** 删除旧版挂在 raw/<device>/<harness>/_events 下的派生数据(可重建)。 */
21
+ export declare function cleanupLegacyEvents(vaultRoot: string): Promise<number>;
22
+ /**
23
+ * 一次性布局迁移:`vault/devices` → `vault/raw`。
24
+ * 两边同时存在时拒绝迁移,交给人工确认,绝不静默合并。
25
+ */
26
+ export declare function migrateLegacyLayout(vaultRoot: string): Promise<'renamed' | 'none'>;
@@ -0,0 +1,122 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { constants } from 'node:fs';
3
+ import { access, mkdir, readdir, rename, rm, writeFile } from 'node:fs/promises';
4
+ import { join } from 'node:path';
5
+ /** 设备事实层的目录名(原 `devices`)。 */
6
+ export const RAW_DIR = 'raw';
7
+ /** 个人资产层的目录名。 */
8
+ export const LIBRARY_DIR = 'library';
9
+ export function rawDeviceDir(vaultRoot, deviceId) {
10
+ return join(vaultRoot, RAW_DIR, deviceId);
11
+ }
12
+ export function rawFilePath(vaultRoot, deviceId, harness, relPath) {
13
+ return join(rawDeviceDir(vaultRoot, deviceId), harness, ...relPath.split('/'));
14
+ }
15
+ export function libraryDir(vaultRoot) {
16
+ return join(vaultRoot, LIBRARY_DIR);
17
+ }
18
+ export function librarySessionsDir(vaultRoot) {
19
+ return join(libraryDir(vaultRoot), 'sessions');
20
+ }
21
+ export function libraryIndexDir(vaultRoot) {
22
+ return join(libraryDir(vaultRoot), 'index');
23
+ }
24
+ export function librarySkillsDir(vaultRoot) {
25
+ return join(libraryDir(vaultRoot), 'skills');
26
+ }
27
+ export function libraryLessonsDir(vaultRoot) {
28
+ return join(libraryDir(vaultRoot), 'lessons');
29
+ }
30
+ /** 会话 id 作为目录名:不安全字符替换,发生替换时附 hash 防碰撞。 */
31
+ export function safeSessionName(id) {
32
+ const clean = id.replace(/[^A-Za-z0-9._-]+/g, '_').slice(0, 120);
33
+ if (clean === id && clean)
34
+ return clean;
35
+ const hash = createHash('sha256').update(id).digest('hex').slice(0, 8);
36
+ return `${clean || 'session'}-${hash}`;
37
+ }
38
+ /** 单设备会话文件:library/sessions/<harness>/<session>/<device>.jsonl */
39
+ export function librarySessionRelPath(harness, sessionId, deviceId) {
40
+ return `sessions/${harness}/${safeSessionName(sessionId)}/${deviceId}.jsonl`;
41
+ }
42
+ /** 多设备并集文件:library/sessions/<harness>/<session>/merged.<hash8>.jsonl */
43
+ export function libraryMergedRelPath(harness, sessionId, hash) {
44
+ return `sessions/${harness}/${safeSessionName(sessionId)}/merged.${hash.slice(0, 8)}.jsonl`;
45
+ }
46
+ /** 建立 library 骨架(幂等);lessons 先留说明文件。 */
47
+ export async function ensureLibraryLayout(vaultRoot) {
48
+ await mkdir(librarySessionsDir(vaultRoot), { recursive: true });
49
+ await mkdir(libraryIndexDir(vaultRoot), { recursive: true });
50
+ await mkdir(librarySkillsDir(vaultRoot), { recursive: true });
51
+ await mkdir(libraryLessonsDir(vaultRoot), { recursive: true });
52
+ const readme = join(libraryLessonsDir(vaultRoot), 'README.md');
53
+ try {
54
+ await access(readme, constants.F_OK);
55
+ }
56
+ catch {
57
+ await writeFile(readme, '# lessons\n\n学习沉淀占位目录。后续按主题存放经验、总结与可复用结论,\n' +
58
+ '每条内容用 `(harness, session, seq)` 引用会话,不复制正文。\n', 'utf8');
59
+ }
60
+ }
61
+ /** 删除旧版挂在 raw/<device>/<harness>/_events 下的派生数据(可重建)。 */
62
+ export async function cleanupLegacyEvents(vaultRoot) {
63
+ const rawRoot = join(vaultRoot, RAW_DIR);
64
+ let devices = [];
65
+ try {
66
+ devices = (await readdir(rawRoot, { withFileTypes: true }))
67
+ .filter((e) => e.isDirectory())
68
+ .map((e) => e.name);
69
+ }
70
+ catch {
71
+ return 0;
72
+ }
73
+ let removed = 0;
74
+ for (const device of devices) {
75
+ let harnesses = [];
76
+ try {
77
+ harnesses = (await readdir(join(rawRoot, device), { withFileTypes: true }))
78
+ .filter((e) => e.isDirectory())
79
+ .map((e) => e.name);
80
+ }
81
+ catch {
82
+ continue;
83
+ }
84
+ for (const harness of harnesses) {
85
+ const legacy = join(rawRoot, device, harness, '_events');
86
+ try {
87
+ await access(legacy, constants.F_OK);
88
+ await rm(legacy, { recursive: true, force: true });
89
+ removed++;
90
+ }
91
+ catch {
92
+ // 不存在
93
+ }
94
+ }
95
+ }
96
+ return removed;
97
+ }
98
+ async function exists(path) {
99
+ try {
100
+ await access(path, constants.F_OK);
101
+ return true;
102
+ }
103
+ catch {
104
+ return false;
105
+ }
106
+ }
107
+ /**
108
+ * 一次性布局迁移:`vault/devices` → `vault/raw`。
109
+ * 两边同时存在时拒绝迁移,交给人工确认,绝不静默合并。
110
+ */
111
+ export async function migrateLegacyLayout(vaultRoot) {
112
+ const legacy = join(vaultRoot, 'devices');
113
+ const next = join(vaultRoot, RAW_DIR);
114
+ const [hasLegacy, hasNext] = await Promise.all([exists(legacy), exists(next)]);
115
+ if (!hasLegacy)
116
+ return 'none';
117
+ if (hasNext)
118
+ throw new Error('vault 中 devices/ 与 raw/ 同时存在,请先人工确认后再迁移');
119
+ await rename(legacy, next);
120
+ return 'renamed';
121
+ }
122
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"layout.js","sourceRoot":"","sources":["../../src/core/layout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /** 阶段 4:会话摘要、分类与打分。摘要/分类走 LlmProvider,打分走 JevProvider,均可 mock。 */
2
+ import type { Event } from '../events/schema.js';
3
+ import type { LlmProvider } from './llm.js';
4
+ import type { JevProvider, JevScores } from './jev.js';
5
+ export type Outcome = 'success' | 'failure' | 'partial' | 'trivial';
6
+ export interface SessionSummary {
7
+ topic: string;
8
+ intent: string;
9
+ outcome: Outcome;
10
+ keySteps: string[];
11
+ hasError: boolean;
12
+ hasCorrection: boolean;
13
+ hasWorkflow: boolean;
14
+ }
15
+ export interface Classification {
16
+ preferences: boolean;
17
+ entities: boolean;
18
+ experiences: boolean;
19
+ events: boolean;
20
+ resources: boolean;
21
+ }
22
+ export type AnalyzeResult = {
23
+ status: 'continue';
24
+ summary: SessionSummary;
25
+ classification: Classification;
26
+ } | {
27
+ status: 'skip';
28
+ reason: 'trivial' | 'no_category' | 'low_score';
29
+ scores?: JevScores;
30
+ };
31
+ export declare function summarizeSession(events: Event[], llm: LlmProvider): Promise<SessionSummary>;
32
+ export declare function classifySession(summary: SessionSummary, llm: LlmProvider): Promise<Classification>;
33
+ export declare function anyCategory(c: Classification): boolean;
34
+ export interface AnalyzeDeps {
35
+ llm: LlmProvider;
36
+ jev: JevProvider;
37
+ }
38
+ /** 阶段 4 总入口:摘要 → 分类 → 打分,任一不达标即跳过并说明原因。 */
39
+ export declare function analyzeSession(events: Event[], deps: AnalyzeDeps): Promise<AnalyzeResult>;
40
+ export declare function renderEvents(events: Event[]): string;