@memoire-ai/collector 0.1.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/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-test.log +45 -0
- package/cursor-hooks/README.md +119 -0
- package/cursor-hooks/context-inject.sh +118 -0
- package/cursor-hooks/hooks.json +39 -0
- package/cursor-hooks/save-file-edit.sh +130 -0
- package/cursor-hooks/save-observation.sh +116 -0
- package/cursor-hooks/save-shell-execution.sh +121 -0
- package/cursor-hooks/session-summary.sh +142 -0
- package/dist/capture.d.ts +111 -0
- package/dist/capture.d.ts.map +1 -0
- package/dist/capture.integration.d.ts +2 -0
- package/dist/capture.integration.d.ts.map +1 -0
- package/dist/capture.integration.js +67 -0
- package/dist/capture.integration.js.map +1 -0
- package/dist/capture.js +264 -0
- package/dist/capture.js.map +1 -0
- package/dist/client-summarizer.d.ts +59 -0
- package/dist/client-summarizer.d.ts.map +1 -0
- package/dist/client-summarizer.js +211 -0
- package/dist/client-summarizer.js.map +1 -0
- package/dist/client-summarizer.test.d.ts +2 -0
- package/dist/client-summarizer.test.d.ts.map +1 -0
- package/dist/client-summarizer.test.js +127 -0
- package/dist/client-summarizer.test.js.map +1 -0
- package/dist/config.d.ts +13 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +131 -0
- package/dist/config.js.map +1 -0
- package/dist/config.test.d.ts +2 -0
- package/dist/config.test.d.ts.map +1 -0
- package/dist/config.test.js +182 -0
- package/dist/config.test.js.map +1 -0
- package/dist/cursor-hooks.d.ts +46 -0
- package/dist/cursor-hooks.d.ts.map +1 -0
- package/dist/cursor-hooks.js +251 -0
- package/dist/cursor-hooks.js.map +1 -0
- package/dist/cursor-rules.d.ts +42 -0
- package/dist/cursor-rules.d.ts.map +1 -0
- package/dist/cursor-rules.js +229 -0
- package/dist/cursor-rules.js.map +1 -0
- package/dist/cursor-rules.test.d.ts +2 -0
- package/dist/cursor-rules.test.d.ts.map +1 -0
- package/dist/cursor-rules.test.js +55 -0
- package/dist/cursor-rules.test.js.map +1 -0
- package/dist/dedup.d.ts +22 -0
- package/dist/dedup.d.ts.map +1 -0
- package/dist/dedup.js +60 -0
- package/dist/dedup.js.map +1 -0
- package/dist/dedup.test.d.ts +2 -0
- package/dist/dedup.test.d.ts.map +1 -0
- package/dist/dedup.test.js +83 -0
- package/dist/dedup.test.js.map +1 -0
- package/dist/hooks/index.d.ts +52 -0
- package/dist/hooks/index.d.ts.map +1 -0
- package/dist/hooks/index.js +136 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks.test.d.ts +2 -0
- package/dist/hooks.test.d.ts.map +1 -0
- package/dist/hooks.test.js +94 -0
- package/dist/hooks.test.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/strip-private.d.ts +12 -0
- package/dist/strip-private.d.ts.map +1 -0
- package/dist/strip-private.js +28 -0
- package/dist/strip-private.js.map +1 -0
- package/dist/strip-private.test.d.ts +2 -0
- package/dist/strip-private.test.d.ts.map +1 -0
- package/dist/strip-private.test.js +37 -0
- package/dist/strip-private.test.js.map +1 -0
- package/dist/utils.d.ts +3 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +11 -0
- package/dist/utils.js.map +1 -0
- package/package.json +28 -0
- package/src/capture.integration.ts +98 -0
- package/src/capture.ts +352 -0
- package/src/client-summarizer.test.ts +144 -0
- package/src/client-summarizer.ts +338 -0
- package/src/config.test.ts +211 -0
- package/src/config.ts +157 -0
- package/src/cursor-hooks.ts +309 -0
- package/src/cursor-rules.test.ts +63 -0
- package/src/cursor-rules.ts +313 -0
- package/src/dedup.test.ts +84 -0
- package/src/dedup.ts +67 -0
- package/src/hooks/index.ts +226 -0
- package/src/hooks.test.ts +111 -0
- package/src/index.ts +32 -0
- package/src/strip-private.test.ts +57 -0
- package/src/strip-private.ts +34 -0
- package/src/utils.ts +10 -0
- package/tsconfig.json +12 -0
- package/tsconfig.tsbuildinfo +1 -0
package/dist/capture.js
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { MemoireClient, OfflineQueue } from '@memoire-ai/sdk';
|
|
2
|
+
import { nanoid } from './utils.js';
|
|
3
|
+
import { writeCursorRules } from './cursor-rules.js';
|
|
4
|
+
import { stripPrivateTags } from './strip-private.js';
|
|
5
|
+
import { ContentDedup } from './dedup.js';
|
|
6
|
+
import { ClientSummarizer } from './client-summarizer.js';
|
|
7
|
+
/**
|
|
8
|
+
* Collector captures events from IDE environments and forwards them
|
|
9
|
+
* to the Memoire API. If the API is unavailable, events are queued
|
|
10
|
+
* locally and retried.
|
|
11
|
+
*
|
|
12
|
+
* Follows the claude-mem hook lifecycle pattern:
|
|
13
|
+
* SessionStart → PostToolUse → SessionEnd
|
|
14
|
+
*
|
|
15
|
+
* Edge processing:
|
|
16
|
+
* - Privacy: <private> tags are stripped before storage
|
|
17
|
+
* - Dedup: Content-hash deduplication within a 30s sliding window
|
|
18
|
+
* - Structured summaries: Session end accepts typed summary objects
|
|
19
|
+
*/
|
|
20
|
+
export class Collector {
|
|
21
|
+
memoireClient;
|
|
22
|
+
queue;
|
|
23
|
+
config;
|
|
24
|
+
sessionId;
|
|
25
|
+
dedup;
|
|
26
|
+
summarizer;
|
|
27
|
+
constructor(config) {
|
|
28
|
+
this.config = config;
|
|
29
|
+
this.sessionId = nanoid();
|
|
30
|
+
this.memoireClient = new MemoireClient({
|
|
31
|
+
apiUrl: config.apiUrl,
|
|
32
|
+
apiKey: config.apiKey,
|
|
33
|
+
clientId: config.clientId,
|
|
34
|
+
});
|
|
35
|
+
this.queue = new OfflineQueue(this.memoireClient);
|
|
36
|
+
this.dedup = new ContentDedup(config.dedupWindowMs ?? 30_000);
|
|
37
|
+
this.summarizer = config.summarizer ? new ClientSummarizer(config.summarizer) : null;
|
|
38
|
+
}
|
|
39
|
+
/** Start a new session */
|
|
40
|
+
async sessionStart() {
|
|
41
|
+
this.sessionId = nanoid();
|
|
42
|
+
await this.emit({
|
|
43
|
+
event_type: 'observation',
|
|
44
|
+
content: `Session started on ${this.config.client}`,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/** Record an observation from a tool use */
|
|
48
|
+
async observation(content, opts) {
|
|
49
|
+
await this.emit({
|
|
50
|
+
event_type: 'observation',
|
|
51
|
+
content,
|
|
52
|
+
files_read: opts?.filesRead,
|
|
53
|
+
files_modified: opts?.filesModified,
|
|
54
|
+
concepts: opts?.concepts,
|
|
55
|
+
branch_name: opts?.branchName,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/** Record a user prompt */
|
|
59
|
+
async prompt(content, opts) {
|
|
60
|
+
await this.emit({
|
|
61
|
+
event_type: 'prompt',
|
|
62
|
+
content,
|
|
63
|
+
files_read: opts?.filesRead,
|
|
64
|
+
files_modified: opts?.filesModified,
|
|
65
|
+
concepts: opts?.concepts,
|
|
66
|
+
branch_name: opts?.branchName,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/** Record a decision */
|
|
70
|
+
async decision(content, opts) {
|
|
71
|
+
await this.emit({
|
|
72
|
+
event_type: 'decision',
|
|
73
|
+
content,
|
|
74
|
+
files_modified: opts?.filesModified,
|
|
75
|
+
concepts: opts?.concepts,
|
|
76
|
+
branch_name: opts?.branchName,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
/** Record a failed attempt */
|
|
80
|
+
async attempt(content, opts) {
|
|
81
|
+
await this.emit({
|
|
82
|
+
event_type: 'attempt',
|
|
83
|
+
content,
|
|
84
|
+
files_modified: opts?.filesModified,
|
|
85
|
+
concepts: opts?.concepts,
|
|
86
|
+
branch_name: opts?.branchName,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
/** Record a convention or standard */
|
|
90
|
+
async convention(content, opts) {
|
|
91
|
+
await this.emit({
|
|
92
|
+
event_type: 'convention',
|
|
93
|
+
content,
|
|
94
|
+
files_modified: opts?.filesModified,
|
|
95
|
+
concepts: opts?.concepts,
|
|
96
|
+
branch_name: opts?.branchName,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
/** Record a branch lifecycle event */
|
|
100
|
+
async branchEvent(content, opts) {
|
|
101
|
+
await this.emit({
|
|
102
|
+
event_type: 'branch_event',
|
|
103
|
+
content,
|
|
104
|
+
files_modified: opts?.filesModified,
|
|
105
|
+
concepts: opts?.concepts,
|
|
106
|
+
branch_name: opts?.branchName,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/** End a session with a structured or plain-text summary */
|
|
110
|
+
async sessionEnd(summary) {
|
|
111
|
+
const content = typeof summary === 'string'
|
|
112
|
+
? summary
|
|
113
|
+
: formatStructuredSummary(summary);
|
|
114
|
+
await this.emit({
|
|
115
|
+
event_type: 'session_summary',
|
|
116
|
+
content,
|
|
117
|
+
});
|
|
118
|
+
// Flush any remaining events
|
|
119
|
+
await this.queue.flush();
|
|
120
|
+
// Auto-write Cursor rules context if workspace path is configured
|
|
121
|
+
if (this.config.workspacePath && this.config.client === 'cursor') {
|
|
122
|
+
try {
|
|
123
|
+
await this.updateCursorRules(content);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
// Non-fatal: cursor rules update is best-effort
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Update .cursor/rules/memoire-context.mdc with latest project context.
|
|
132
|
+
* Called automatically on session end for Cursor clients.
|
|
133
|
+
*/
|
|
134
|
+
async updateCursorRules(sessionSummary) {
|
|
135
|
+
if (!this.config.workspacePath)
|
|
136
|
+
return;
|
|
137
|
+
// Try to fetch profile from API
|
|
138
|
+
let profile;
|
|
139
|
+
try {
|
|
140
|
+
const profileResp = await this.memoireClient.projectProfile({
|
|
141
|
+
org_id: this.config.orgId,
|
|
142
|
+
project_id: this.config.projectId,
|
|
143
|
+
viewer_user_id: this.config.userId,
|
|
144
|
+
});
|
|
145
|
+
if (profileResp?.project_profile) {
|
|
146
|
+
const pp = profileResp.project_profile;
|
|
147
|
+
profile = {
|
|
148
|
+
architecture: pp.architecture?.join(', '),
|
|
149
|
+
stack: pp.key_files?.slice(0, 5),
|
|
150
|
+
conventions: pp.conventions?.slice(0, 10),
|
|
151
|
+
currentFocus: pp.current_focus?.join(', '),
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
// API unavailable — write rules with just the session summary
|
|
157
|
+
}
|
|
158
|
+
writeCursorRules(this.config.workspacePath, {
|
|
159
|
+
projectName: this.config.projectName ?? 'Project',
|
|
160
|
+
profile,
|
|
161
|
+
recentSummary: sessionSummary,
|
|
162
|
+
apiUrl: this.config.apiUrl,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
/** Emit a raw event — applies privacy stripping, dedup, and optional client-side summarization */
|
|
166
|
+
async emit(partial) {
|
|
167
|
+
// Edge processing: strip <private> tags from content AND all metadata fields
|
|
168
|
+
const cleanContent = stripPrivateTags(partial.content);
|
|
169
|
+
// Skip empty content after stripping
|
|
170
|
+
if (!cleanContent)
|
|
171
|
+
return;
|
|
172
|
+
const cleanFilesRead = stripPrivateArray(partial.files_read);
|
|
173
|
+
const cleanFilesModified = stripPrivateArray(partial.files_modified);
|
|
174
|
+
const cleanConcepts = stripPrivateArray(partial.concepts);
|
|
175
|
+
const cleanBranch = partial.branch_name ? stripPrivateTags(partial.branch_name) : partial.branch_name;
|
|
176
|
+
// Edge processing: deduplicate within sliding window (keyed on event_type + content)
|
|
177
|
+
if (this.dedup.isDuplicate(`${partial.event_type}\0${cleanContent}`))
|
|
178
|
+
return;
|
|
179
|
+
const event = {
|
|
180
|
+
org_id: this.config.orgId,
|
|
181
|
+
project_id: this.config.projectId,
|
|
182
|
+
repo_id: this.config.repoId,
|
|
183
|
+
user_id: this.config.userId,
|
|
184
|
+
session_id: this.sessionId,
|
|
185
|
+
client: this.config.client,
|
|
186
|
+
created_at: new Date().toISOString(),
|
|
187
|
+
idempotency_key: nanoid(),
|
|
188
|
+
private: false,
|
|
189
|
+
...partial,
|
|
190
|
+
event_type: partial.event_type,
|
|
191
|
+
content: cleanContent,
|
|
192
|
+
files_read: cleanFilesRead,
|
|
193
|
+
files_modified: cleanFilesModified,
|
|
194
|
+
concepts: cleanConcepts,
|
|
195
|
+
branch_name: cleanBranch,
|
|
196
|
+
};
|
|
197
|
+
// Edge processing: client-side AI summarization (non-blocking on failure)
|
|
198
|
+
if (this.summarizer) {
|
|
199
|
+
try {
|
|
200
|
+
const result = await this.summarizer.summarize(cleanContent, partial.event_type, {
|
|
201
|
+
filesRead: cleanFilesRead,
|
|
202
|
+
filesModified: cleanFilesModified,
|
|
203
|
+
concepts: cleanConcepts,
|
|
204
|
+
branchName: cleanBranch,
|
|
205
|
+
});
|
|
206
|
+
if (result) {
|
|
207
|
+
event.summary = result.summary;
|
|
208
|
+
event.summary_details = result.summary_details;
|
|
209
|
+
// Merge AI-extracted concepts with existing ones
|
|
210
|
+
if (result.concepts.length > 0) {
|
|
211
|
+
const merged = new Set([...(event.concepts ?? []), ...result.concepts]);
|
|
212
|
+
event.concepts = Array.from(merged).slice(0, 12);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// Summarization failure is non-fatal — server will handle it
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
try {
|
|
221
|
+
await this.memoireClient.ingestEvent(event);
|
|
222
|
+
}
|
|
223
|
+
catch {
|
|
224
|
+
// API unreachable — queue for retry
|
|
225
|
+
this.queue.enqueue([event]);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
/** Get the number of pending events in the offline queue */
|
|
229
|
+
get pendingEvents() {
|
|
230
|
+
return this.queue.pending;
|
|
231
|
+
}
|
|
232
|
+
destroy() {
|
|
233
|
+
this.dedup.destroy();
|
|
234
|
+
this.queue.destroy();
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
/** Strip private tags from each element of a string array */
|
|
238
|
+
function stripPrivateArray(arr) {
|
|
239
|
+
if (!arr)
|
|
240
|
+
return arr;
|
|
241
|
+
return arr.map(stripPrivateTags).filter(Boolean);
|
|
242
|
+
}
|
|
243
|
+
/** Format a structured summary into a readable content string */
|
|
244
|
+
function formatStructuredSummary(summary) {
|
|
245
|
+
const parts = [];
|
|
246
|
+
parts.push(`Request: ${summary.request}`);
|
|
247
|
+
if (summary.investigated?.length) {
|
|
248
|
+
parts.push(`Investigated: ${summary.investigated.join('; ')}`);
|
|
249
|
+
}
|
|
250
|
+
if (summary.learned?.length) {
|
|
251
|
+
parts.push(`Learned: ${summary.learned.join('; ')}`);
|
|
252
|
+
}
|
|
253
|
+
if (summary.completed?.length) {
|
|
254
|
+
parts.push(`Completed: ${summary.completed.join('; ')}`);
|
|
255
|
+
}
|
|
256
|
+
if (summary.next_steps?.length) {
|
|
257
|
+
parts.push(`Next steps: ${summary.next_steps.join('; ')}`);
|
|
258
|
+
}
|
|
259
|
+
if (summary.notes) {
|
|
260
|
+
parts.push(`Notes: ${summary.notes}`);
|
|
261
|
+
}
|
|
262
|
+
return parts.join('\n');
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=capture.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capture.js","sourceRoot":"","sources":["../src/capture.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge/native summarization options for Memoire collectors.
|
|
3
|
+
*
|
|
4
|
+
* Supported modes:
|
|
5
|
+
* - edge Anthropic API using the user's own key
|
|
6
|
+
* - native Claude Code CLI using local Claude auth/subscription
|
|
7
|
+
* - native Codex CLI using local Codex auth/session
|
|
8
|
+
*
|
|
9
|
+
* All modes share the same prompt templates from @memoire-ai/shared.
|
|
10
|
+
*/
|
|
11
|
+
import { type EventSummaryDetails } from '@memoire-ai/shared';
|
|
12
|
+
export interface ClientSummaryResult {
|
|
13
|
+
summary: string;
|
|
14
|
+
concepts: string[];
|
|
15
|
+
summary_details?: EventSummaryDetails;
|
|
16
|
+
}
|
|
17
|
+
interface BaseSummarizerConfig {
|
|
18
|
+
/** Model override for the selected summarizer mode */
|
|
19
|
+
model?: string;
|
|
20
|
+
/** Timeout in ms (default: 15000) */
|
|
21
|
+
timeout?: number;
|
|
22
|
+
/** Prefer running from the repo/workspace root when using local CLIs */
|
|
23
|
+
cwd?: string;
|
|
24
|
+
/** Optional runner override for tests */
|
|
25
|
+
runCommand?: CommandRunner;
|
|
26
|
+
}
|
|
27
|
+
export interface AnthropicClientSummarizerConfig extends BaseSummarizerConfig {
|
|
28
|
+
mode: 'anthropic';
|
|
29
|
+
/** Anthropic API key (user's own) */
|
|
30
|
+
apiKey: string;
|
|
31
|
+
}
|
|
32
|
+
export interface NativeClaudeSummarizerConfig extends BaseSummarizerConfig {
|
|
33
|
+
mode: 'native-claude';
|
|
34
|
+
}
|
|
35
|
+
export interface NativeCodexSummarizerConfig extends BaseSummarizerConfig {
|
|
36
|
+
mode: 'native-codex';
|
|
37
|
+
}
|
|
38
|
+
export type ClientSummarizerConfig = AnthropicClientSummarizerConfig | NativeClaudeSummarizerConfig | NativeCodexSummarizerConfig;
|
|
39
|
+
type CommandRunner = (args: {
|
|
40
|
+
command: string;
|
|
41
|
+
args: string[];
|
|
42
|
+
cwd?: string;
|
|
43
|
+
env?: NodeJS.ProcessEnv;
|
|
44
|
+
timeoutMs?: number;
|
|
45
|
+
}) => Promise<string>;
|
|
46
|
+
export declare class ClientSummarizer {
|
|
47
|
+
private config;
|
|
48
|
+
private timeout;
|
|
49
|
+
private runCommand;
|
|
50
|
+
constructor(config: ClientSummarizerConfig);
|
|
51
|
+
summarize(content: string, eventType: string, context?: {
|
|
52
|
+
filesRead?: string[];
|
|
53
|
+
filesModified?: string[];
|
|
54
|
+
concepts?: string[];
|
|
55
|
+
branchName?: string;
|
|
56
|
+
}): Promise<ClientSummaryResult | null>;
|
|
57
|
+
}
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=client-summarizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-summarizer.d.ts","sourceRoot":"","sources":["../src/client-summarizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,EACL,KAAK,mBAAmB,EAIzB,MAAM,oBAAoB,CAAC;AAO5B,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,eAAe,CAAC,EAAE,mBAAmB,CAAC;CACvC;AAED,UAAU,oBAAoB;IAC5B,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yCAAyC;IACzC,UAAU,CAAC,EAAE,aAAa,CAAC;CAC5B;AAED,MAAM,WAAW,+BAAgC,SAAQ,oBAAoB;IAC3E,IAAI,EAAE,WAAW,CAAC;IAClB,qCAAqC;IACrC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,4BAA6B,SAAQ,oBAAoB;IACxE,IAAI,EAAE,eAAe,CAAC;CACvB;AAED,MAAM,WAAW,2BAA4B,SAAQ,oBAAoB;IACvE,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,MAAM,MAAM,sBAAsB,GAC9B,+BAA+B,GAC/B,4BAA4B,GAC5B,2BAA2B,CAAC;AAEhC,KAAK,aAAa,GAAG,CAAC,IAAI,EAAE;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;AAEtB,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAgB;gBAEtB,MAAM,EAAE,sBAAsB;IAMpC,SAAS,CACb,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;QACrB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,GACA,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC;CA4CvC"}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge/native summarization options for Memoire collectors.
|
|
3
|
+
*
|
|
4
|
+
* Supported modes:
|
|
5
|
+
* - edge Anthropic API using the user's own key
|
|
6
|
+
* - native Claude Code CLI using local Claude auth/subscription
|
|
7
|
+
* - native Codex CLI using local Codex auth/session
|
|
8
|
+
*
|
|
9
|
+
* All modes share the same prompt templates from @memoire-ai/shared.
|
|
10
|
+
*/
|
|
11
|
+
import { promisify } from 'node:util';
|
|
12
|
+
import { execFile as execFileCb } from 'node:child_process';
|
|
13
|
+
import { buildSummarizationSystemPrompt, buildSummarizationUserPrompt, MAX_SUMMARY_LENGTH, } from '@memoire-ai/shared';
|
|
14
|
+
const execFile = promisify(execFileCb);
|
|
15
|
+
const DEFAULT_ANTHROPIC_MODEL = 'claude-3-5-haiku-20241022';
|
|
16
|
+
const ANTHROPIC_API_URL = 'https://api.anthropic.com/v1/messages';
|
|
17
|
+
export class ClientSummarizer {
|
|
18
|
+
config;
|
|
19
|
+
timeout;
|
|
20
|
+
runCommand;
|
|
21
|
+
constructor(config) {
|
|
22
|
+
this.config = config;
|
|
23
|
+
this.timeout = config.timeout ?? 15_000;
|
|
24
|
+
this.runCommand = config.runCommand ?? defaultCommandRunner;
|
|
25
|
+
}
|
|
26
|
+
async summarize(content, eventType, context) {
|
|
27
|
+
try {
|
|
28
|
+
const systemPrompt = buildSummarizationSystemPrompt(eventType);
|
|
29
|
+
const userPrompt = buildSummarizationUserPrompt({
|
|
30
|
+
content,
|
|
31
|
+
eventType,
|
|
32
|
+
filesRead: context?.filesRead,
|
|
33
|
+
filesModified: context?.filesModified,
|
|
34
|
+
concepts: context?.concepts,
|
|
35
|
+
branchName: context?.branchName,
|
|
36
|
+
});
|
|
37
|
+
let text;
|
|
38
|
+
switch (this.config.mode) {
|
|
39
|
+
case 'anthropic':
|
|
40
|
+
text = await requestAnthropicText(this.config, systemPrompt, userPrompt);
|
|
41
|
+
break;
|
|
42
|
+
case 'native-claude':
|
|
43
|
+
text = await requestClaudeNativeText(this.runCommand, this.config, systemPrompt, userPrompt, this.timeout);
|
|
44
|
+
break;
|
|
45
|
+
case 'native-codex':
|
|
46
|
+
text = await requestCodexNativeText(this.runCommand, this.config, systemPrompt, userPrompt, this.timeout);
|
|
47
|
+
break;
|
|
48
|
+
default:
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
return parseResponse(text);
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function requestAnthropicText(config, system, content) {
|
|
59
|
+
const controller = new AbortController();
|
|
60
|
+
const timer = setTimeout(() => controller.abort(), config.timeout ?? 15_000);
|
|
61
|
+
try {
|
|
62
|
+
const response = await fetch(ANTHROPIC_API_URL, {
|
|
63
|
+
method: 'POST',
|
|
64
|
+
headers: {
|
|
65
|
+
'Content-Type': 'application/json',
|
|
66
|
+
'anthropic-version': '2023-06-01',
|
|
67
|
+
'x-api-key': config.apiKey,
|
|
68
|
+
},
|
|
69
|
+
body: JSON.stringify({
|
|
70
|
+
model: config.model ?? DEFAULT_ANTHROPIC_MODEL,
|
|
71
|
+
max_tokens: 360,
|
|
72
|
+
temperature: 0,
|
|
73
|
+
system,
|
|
74
|
+
messages: [{ role: 'user', content }],
|
|
75
|
+
}),
|
|
76
|
+
signal: controller.signal,
|
|
77
|
+
});
|
|
78
|
+
if (!response.ok) {
|
|
79
|
+
throw new Error(`Anthropic ${response.status}`);
|
|
80
|
+
}
|
|
81
|
+
const payload = await response.json();
|
|
82
|
+
return (payload.content
|
|
83
|
+
?.filter((item) => item.type === 'text' && typeof item.text === 'string')
|
|
84
|
+
.map((item) => item.text ?? '')
|
|
85
|
+
.join('\n')
|
|
86
|
+
.trim() ?? '');
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
clearTimeout(timer);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async function requestClaudeNativeText(runCommand, config, system, userPrompt, timeout) {
|
|
93
|
+
const output = await runCommand({
|
|
94
|
+
command: 'claude',
|
|
95
|
+
args: [
|
|
96
|
+
'-p',
|
|
97
|
+
'--output-format',
|
|
98
|
+
'json',
|
|
99
|
+
'--permission-mode',
|
|
100
|
+
'bypassPermissions',
|
|
101
|
+
'--tools',
|
|
102
|
+
'',
|
|
103
|
+
...(config.model ? ['--model', config.model] : []),
|
|
104
|
+
'--system-prompt',
|
|
105
|
+
system,
|
|
106
|
+
userPrompt,
|
|
107
|
+
],
|
|
108
|
+
cwd: config.cwd,
|
|
109
|
+
env: buildNativeClaudeEnv(),
|
|
110
|
+
timeoutMs: timeout,
|
|
111
|
+
});
|
|
112
|
+
const parsed = JSON.parse(output);
|
|
113
|
+
return typeof parsed.result === 'string' ? parsed.result.trim() : '';
|
|
114
|
+
}
|
|
115
|
+
async function requestCodexNativeText(runCommand, config, system, userPrompt, timeout) {
|
|
116
|
+
const prompt = [
|
|
117
|
+
system,
|
|
118
|
+
'',
|
|
119
|
+
'Return only the required JSON for this event.',
|
|
120
|
+
'',
|
|
121
|
+
userPrompt,
|
|
122
|
+
].join('\n');
|
|
123
|
+
const output = await runCommand({
|
|
124
|
+
command: 'codex',
|
|
125
|
+
args: [
|
|
126
|
+
'exec',
|
|
127
|
+
'--skip-git-repo-check',
|
|
128
|
+
'--json',
|
|
129
|
+
'--sandbox',
|
|
130
|
+
'read-only',
|
|
131
|
+
...(config.cwd ? ['-C', config.cwd] : []),
|
|
132
|
+
...(config.model ? ['--model', config.model] : []),
|
|
133
|
+
prompt,
|
|
134
|
+
],
|
|
135
|
+
cwd: config.cwd,
|
|
136
|
+
env: buildNativeCodexEnv(),
|
|
137
|
+
timeoutMs: timeout,
|
|
138
|
+
});
|
|
139
|
+
return extractCodexAgentMessage(output);
|
|
140
|
+
}
|
|
141
|
+
function buildNativeClaudeEnv() {
|
|
142
|
+
const env = { ...process.env };
|
|
143
|
+
delete env.ANTHROPIC_API_KEY;
|
|
144
|
+
delete env.MEMOIRE_ANTHROPIC_API_KEY;
|
|
145
|
+
delete env.CLAUDECODE;
|
|
146
|
+
env.CLAUDE_CODE_ENTRYPOINT = 'sdk-ts';
|
|
147
|
+
return env;
|
|
148
|
+
}
|
|
149
|
+
function buildNativeCodexEnv() {
|
|
150
|
+
const env = { ...process.env };
|
|
151
|
+
delete env.OPENAI_API_KEY;
|
|
152
|
+
delete env.OPENAI_BASE_URL;
|
|
153
|
+
return env;
|
|
154
|
+
}
|
|
155
|
+
function extractCodexAgentMessage(output) {
|
|
156
|
+
const lines = output
|
|
157
|
+
.split('\n')
|
|
158
|
+
.map((line) => line.trim())
|
|
159
|
+
.filter(Boolean);
|
|
160
|
+
for (let index = lines.length - 1; index >= 0; index--) {
|
|
161
|
+
try {
|
|
162
|
+
const parsed = JSON.parse(lines[index]);
|
|
163
|
+
if (parsed.type === 'item.completed' && parsed.item?.type === 'agent_message' && typeof parsed.item.text === 'string') {
|
|
164
|
+
return parsed.item.text.trim();
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return '';
|
|
172
|
+
}
|
|
173
|
+
async function defaultCommandRunner(args) {
|
|
174
|
+
const { stdout } = await execFile(args.command, args.args, {
|
|
175
|
+
cwd: args.cwd,
|
|
176
|
+
env: args.env,
|
|
177
|
+
timeout: args.timeoutMs,
|
|
178
|
+
maxBuffer: 8 * 1024 * 1024,
|
|
179
|
+
});
|
|
180
|
+
return stdout;
|
|
181
|
+
}
|
|
182
|
+
function parseResponse(text) {
|
|
183
|
+
if (!text)
|
|
184
|
+
return null;
|
|
185
|
+
const normalized = text
|
|
186
|
+
.replace(/^```json\s*/i, '')
|
|
187
|
+
.replace(/^```\s*/i, '')
|
|
188
|
+
.replace(/\s*```$/i, '')
|
|
189
|
+
.trim();
|
|
190
|
+
const start = normalized.indexOf('{');
|
|
191
|
+
const end = normalized.lastIndexOf('}');
|
|
192
|
+
if (start === -1 || end === -1 || end < start)
|
|
193
|
+
return null;
|
|
194
|
+
try {
|
|
195
|
+
const parsed = JSON.parse(normalized.slice(start, end + 1));
|
|
196
|
+
if (typeof parsed.summary !== 'string' || !Array.isArray(parsed.concepts)) {
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
summary: parsed.summary.slice(0, MAX_SUMMARY_LENGTH),
|
|
201
|
+
concepts: parsed.concepts
|
|
202
|
+
.filter((c) => typeof c === 'string')
|
|
203
|
+
.slice(0, 12),
|
|
204
|
+
summary_details: parsed.details,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
//# sourceMappingURL=client-summarizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-summarizer.js","sourceRoot":"","sources":["../src/client-summarizer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-summarizer.test.d.ts","sourceRoot":"","sources":["../src/client-summarizer.test.ts"],"names":[],"mappings":""}
|