@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
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { ClientSummarizer } from './client-summarizer.js';
|
|
4
|
+
test('ClientSummarizer parses Anthropic responses', async () => {
|
|
5
|
+
const originalFetch = globalThis.fetch;
|
|
6
|
+
globalThis.fetch = (async () => new Response(JSON.stringify({
|
|
7
|
+
content: [
|
|
8
|
+
{
|
|
9
|
+
type: 'text',
|
|
10
|
+
text: JSON.stringify({
|
|
11
|
+
summary: 'Added OAuth2 PKCE flow to auth service',
|
|
12
|
+
concepts: ['oauth', 'pkce', 'authentication'],
|
|
13
|
+
details: { title: 'OAuth2 PKCE', subtitle: 'Added PKCE flow' },
|
|
14
|
+
}),
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
}), {
|
|
18
|
+
status: 200,
|
|
19
|
+
headers: { 'content-type': 'application/json' },
|
|
20
|
+
}));
|
|
21
|
+
try {
|
|
22
|
+
const summarizer = new ClientSummarizer({
|
|
23
|
+
mode: 'anthropic',
|
|
24
|
+
apiKey: 'sk-ant-test-fake',
|
|
25
|
+
});
|
|
26
|
+
const result = await summarizer.summarize('Implemented OAuth2 with PKCE', 'observation');
|
|
27
|
+
assert.ok(result);
|
|
28
|
+
assert.equal(result.summary, 'Added OAuth2 PKCE flow to auth service');
|
|
29
|
+
assert.deepEqual(result.concepts, ['oauth', 'pkce', 'authentication']);
|
|
30
|
+
assert.equal(result.summary_details?.title, 'OAuth2 PKCE');
|
|
31
|
+
}
|
|
32
|
+
finally {
|
|
33
|
+
globalThis.fetch = originalFetch;
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
test('ClientSummarizer parses native Claude JSON output', async () => {
|
|
37
|
+
const summarizer = new ClientSummarizer({
|
|
38
|
+
mode: 'native-claude',
|
|
39
|
+
runCommand: async ({ command }) => {
|
|
40
|
+
assert.equal(command, 'claude');
|
|
41
|
+
return JSON.stringify({
|
|
42
|
+
result: '{"summary":"Verified auth middleware refresh flow.","concepts":["auth","middleware","refresh"],"details":{"title":"Auth middleware refresh"}}',
|
|
43
|
+
});
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
const result = await summarizer.summarize('Inspected auth middleware', 'observation');
|
|
47
|
+
assert.ok(result);
|
|
48
|
+
assert.equal(result.summary, 'Verified auth middleware refresh flow.');
|
|
49
|
+
assert.deepEqual(result.concepts, ['auth', 'middleware', 'refresh']);
|
|
50
|
+
});
|
|
51
|
+
test('ClientSummarizer parses native Codex JSONL output', async () => {
|
|
52
|
+
const summarizer = new ClientSummarizer({
|
|
53
|
+
mode: 'native-codex',
|
|
54
|
+
runCommand: async ({ command }) => {
|
|
55
|
+
assert.equal(command, 'codex');
|
|
56
|
+
return [
|
|
57
|
+
'{"type":"thread.started","thread_id":"abc"}',
|
|
58
|
+
'{"type":"item.completed","item":{"id":"item_0","type":"reasoning","text":"thinking"}}',
|
|
59
|
+
'{"type":"item.completed","item":{"id":"item_1","type":"agent_message","text":"{\\"summary\\":\\"Captured OAuth callback fix.\\",\\"concepts\\":[\\"oauth\\",\\"callback\\"],\\"details\\":{\\"title\\":\\"OAuth callback\\"}}"}}',
|
|
60
|
+
].join('\n');
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
const result = await summarizer.summarize('Fixed OAuth callback edge case', 'attempt');
|
|
64
|
+
assert.ok(result);
|
|
65
|
+
assert.equal(result.summary, 'Captured OAuth callback fix.');
|
|
66
|
+
assert.deepEqual(result.concepts, ['oauth', 'callback']);
|
|
67
|
+
assert.equal(result.summary_details?.title, 'OAuth callback');
|
|
68
|
+
});
|
|
69
|
+
test('ClientSummarizer returns null on command failure', async () => {
|
|
70
|
+
const summarizer = new ClientSummarizer({
|
|
71
|
+
mode: 'native-codex',
|
|
72
|
+
runCommand: async () => {
|
|
73
|
+
throw new Error('boom');
|
|
74
|
+
},
|
|
75
|
+
});
|
|
76
|
+
const result = await summarizer.summarize('test', 'observation');
|
|
77
|
+
assert.equal(result, null);
|
|
78
|
+
});
|
|
79
|
+
test('ClientSummarizer truncates summary to 180 chars', async () => {
|
|
80
|
+
const summarizer = new ClientSummarizer({
|
|
81
|
+
mode: 'native-claude',
|
|
82
|
+
runCommand: async () => JSON.stringify({
|
|
83
|
+
result: JSON.stringify({
|
|
84
|
+
summary: 'A'.repeat(300),
|
|
85
|
+
concepts: ['test'],
|
|
86
|
+
}),
|
|
87
|
+
}),
|
|
88
|
+
});
|
|
89
|
+
const result = await summarizer.summarize('test', 'observation');
|
|
90
|
+
assert.ok(result);
|
|
91
|
+
assert.equal(result.summary.length, 180);
|
|
92
|
+
});
|
|
93
|
+
test('ClientSummarizer limits concepts to 12', async () => {
|
|
94
|
+
const summarizer = new ClientSummarizer({
|
|
95
|
+
mode: 'native-codex',
|
|
96
|
+
runCommand: async () => [
|
|
97
|
+
'{"type":"item.completed","item":{"type":"agent_message","text":"{\\"summary\\":\\"test\\",\\"concepts\\":[' +
|
|
98
|
+
Array.from({ length: 20 }, (_, i) => `\\"concept${i}\\"`).join(',') +
|
|
99
|
+
']}"}}',
|
|
100
|
+
].join('\n'),
|
|
101
|
+
});
|
|
102
|
+
const result = await summarizer.summarize('test', 'observation');
|
|
103
|
+
assert.ok(result);
|
|
104
|
+
assert.equal(result.concepts.length, 12);
|
|
105
|
+
});
|
|
106
|
+
test('ClientSummarizer handles session_summary details', async () => {
|
|
107
|
+
const summarizer = new ClientSummarizer({
|
|
108
|
+
mode: 'native-claude',
|
|
109
|
+
runCommand: async () => JSON.stringify({
|
|
110
|
+
result: JSON.stringify({
|
|
111
|
+
summary: 'Implemented auth middleware',
|
|
112
|
+
concepts: ['auth', 'middleware'],
|
|
113
|
+
details: {
|
|
114
|
+
request: 'Add WorkOS auth',
|
|
115
|
+
investigated: ['existing auth flow'],
|
|
116
|
+
completed: ['WorkOS integration'],
|
|
117
|
+
next_steps: ['add RBAC'],
|
|
118
|
+
},
|
|
119
|
+
}),
|
|
120
|
+
}),
|
|
121
|
+
});
|
|
122
|
+
const result = await summarizer.summarize('session content', 'session_summary');
|
|
123
|
+
assert.ok(result);
|
|
124
|
+
assert.equal(result.summary_details?.request, 'Add WorkOS auth');
|
|
125
|
+
assert.deepEqual(result.summary_details?.completed, ['WorkOS integration']);
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=client-summarizer.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-summarizer.test.js","sourceRoot":"","sources":["../src/client-summarizer.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE1D,IAAI,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;IAC7D,MAAM,aAAa,GAAG,UAAU,CAAC,KAAK,CAAC;IACvC,UAAU,CAAC,KAAK,GAAG,CAAC,KAAK,IAAI,EAAE,CAC7B,IAAI,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC;QAC1B,OAAO,EAAE;YACP;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;oBACnB,OAAO,EAAE,wCAAwC;oBACjD,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC;oBAC7C,OAAO,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,iBAAiB,EAAE;iBAC/D,CAAC;aACH;SACF;KACF,CAAC,EAAE;QACF,MAAM,EAAE,GAAG;QACX,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;KAChD,CAAC,CAAiB,CAAC;IAEtB,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC;YACtC,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,kBAAkB;SAC3B,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,8BAA8B,EAAE,aAAa,CAAC,CAAC;QAEzF,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;QAClB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,wCAAwC,CAAC,CAAC;QACvE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC;QACvE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,KAAK,EAAE,aAAa,CAAC,CAAC;IAC7D,CAAC;YAAS,CAAC;QACT,UAAU,CAAC,KAAK,GAAG,aAAa,CAAC;IACnC,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;IACnE,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC;QACtC,IAAI,EAAE,eAAe;QACrB,UAAU,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;YAChC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAChC,OAAO,IAAI,CAAC,SAAS,CAAC;gBACpB,MAAM,EAAE,+IAA+I;aACxJ,CAAC,CAAC;QACL,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,2BAA2B,EAAE,aAAa,CAAC,CAAC;IAEtF,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IAClB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,wCAAwC,CAAC,CAAC;IACvE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;AACvE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,mDAAmD,EAAE,KAAK,IAAI,EAAE;IACnE,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC;QACtC,IAAI,EAAE,cAAc;QACpB,UAAU,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE;YAChC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAC/B,OAAO;gBACL,6CAA6C;gBAC7C,uFAAuF;gBACvF,kOAAkO;aACnO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACf,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,gCAAgC,EAAE,SAAS,CAAC,CAAC;IAEvF,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IAClB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,EAAE,8BAA8B,CAAC,CAAC;IAC7D,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC;IACzD,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,KAAK,EAAE,gBAAgB,CAAC,CAAC;AAChE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;IAClE,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC;QACtC,IAAI,EAAE,cAAc;QACpB,UAAU,EAAE,KAAK,IAAI,EAAE;YACrB,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;QAC1B,CAAC;KACF,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjE,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,iDAAiD,EAAE,KAAK,IAAI,EAAE;IACjE,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC;QACtC,IAAI,EAAE,eAAe;QACrB,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC;YACrC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;gBACrB,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;gBACxB,QAAQ,EAAE,CAAC,MAAM,CAAC;aACnB,CAAC;SACH,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IAClB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;IACxD,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC;QACtC,IAAI,EAAE,cAAc;QACpB,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC;YACtB,4GAA4G;gBAC1G,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;gBACnE,OAAO;SACV,CAAC,IAAI,CAAC,IAAI,CAAC;KACb,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IACjE,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IAClB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC3C,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,kDAAkD,EAAE,KAAK,IAAI,EAAE;IAClE,MAAM,UAAU,GAAG,IAAI,gBAAgB,CAAC;QACtC,IAAI,EAAE,eAAe;QACrB,UAAU,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC;YACrC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC;gBACrB,OAAO,EAAE,6BAA6B;gBACtC,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,CAAC;gBAChC,OAAO,EAAE;oBACP,OAAO,EAAE,iBAAiB;oBAC1B,YAAY,EAAE,CAAC,oBAAoB,CAAC;oBACpC,SAAS,EAAE,CAAC,oBAAoB,CAAC;oBACjC,UAAU,EAAE,CAAC,UAAU,CAAC;iBACzB;aACF,CAAC;SACH,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;IAChF,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IAClB,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,eAAe,EAAE,OAAO,EAAE,iBAAiB,CAAC,CAAC;IACjE,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,eAAe,EAAE,SAAS,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC;AAC9E,CAAC,CAAC,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { MemoireConfig } from '@memoire-ai/shared';
|
|
2
|
+
import { Collector, type CollectorConfig } from './capture.js';
|
|
3
|
+
export interface ConfigPathOptions {
|
|
4
|
+
configPath?: string;
|
|
5
|
+
homeDir?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface CollectorFromConfigOptions extends ConfigPathOptions {
|
|
8
|
+
overrides?: Partial<CollectorConfig>;
|
|
9
|
+
}
|
|
10
|
+
export declare function getMemoireConfigPath(opts?: ConfigPathOptions): string;
|
|
11
|
+
export declare function readMemoireConfig(opts?: ConfigPathOptions): MemoireConfig;
|
|
12
|
+
export declare function createCollectorFromConfig(opts?: CollectorFromConfigOptions): Collector;
|
|
13
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,aAAa,EAGd,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/D,MAAM,WAAW,iBAAiB;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,0BAA2B,SAAQ,iBAAiB;IACnE,SAAS,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;CACtC;AAED,wBAAgB,oBAAoB,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,MAAM,CAGrE;AAED,wBAAgB,iBAAiB,CAAC,IAAI,CAAC,EAAE,iBAAiB,GAAG,aAAa,CAyBzE;AAED,wBAAgB,yBAAyB,CAAC,IAAI,CAAC,EAAE,0BAA0B,GAAG,SAAS,CAiBtF"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { delimiter, join } from 'node:path';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { Collector } from './capture.js';
|
|
5
|
+
export function getMemoireConfigPath(opts) {
|
|
6
|
+
if (opts?.configPath)
|
|
7
|
+
return opts.configPath;
|
|
8
|
+
return join(opts?.homeDir ?? homedir(), '.memoire', 'config.json');
|
|
9
|
+
}
|
|
10
|
+
export function readMemoireConfig(opts) {
|
|
11
|
+
const configPath = getMemoireConfigPath(opts);
|
|
12
|
+
if (!existsSync(configPath)) {
|
|
13
|
+
throw new Error(`Memoire config not found at ${configPath}`);
|
|
14
|
+
}
|
|
15
|
+
const raw = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
16
|
+
const requiredFields = [
|
|
17
|
+
'api_url',
|
|
18
|
+
'api_key',
|
|
19
|
+
'org_id',
|
|
20
|
+
'project_id',
|
|
21
|
+
'user_id',
|
|
22
|
+
'client',
|
|
23
|
+
'installed_at',
|
|
24
|
+
];
|
|
25
|
+
for (const field of requiredFields) {
|
|
26
|
+
if (!raw[field] || typeof raw[field] !== 'string') {
|
|
27
|
+
throw new Error(`Memoire config is missing required field "${field}"`);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return raw;
|
|
31
|
+
}
|
|
32
|
+
export function createCollectorFromConfig(opts) {
|
|
33
|
+
const config = readMemoireConfig(opts);
|
|
34
|
+
const summarizer = resolveSummarizerConfig(config);
|
|
35
|
+
return new Collector({
|
|
36
|
+
apiUrl: config.api_url,
|
|
37
|
+
apiKey: config.api_key,
|
|
38
|
+
orgId: config.org_id,
|
|
39
|
+
projectId: config.project_id,
|
|
40
|
+
userId: config.user_id,
|
|
41
|
+
client: config.client,
|
|
42
|
+
repoId: config.repo_id,
|
|
43
|
+
clientId: config.client_id,
|
|
44
|
+
workspacePath: config.repo_root,
|
|
45
|
+
summarizer,
|
|
46
|
+
...opts?.overrides,
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function resolveSummarizerConfig(config) {
|
|
50
|
+
const anthropicKey = config.anthropic_api_key
|
|
51
|
+
?? process.env.MEMOIRE_ANTHROPIC_API_KEY
|
|
52
|
+
?? process.env.ANTHROPIC_API_KEY;
|
|
53
|
+
const explicitMode = config.summarization_mode
|
|
54
|
+
?? parseSummarizationMode(process.env.MEMOIRE_SUMMARIZATION_MODE)
|
|
55
|
+
?? (config.client_side_summarization || process.env.MEMOIRE_CLIENT_SUMMARIZE === 'true'
|
|
56
|
+
? 'edge_anthropic'
|
|
57
|
+
: 'server');
|
|
58
|
+
if (explicitMode === 'server') {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
if (explicitMode === 'edge_anthropic') {
|
|
62
|
+
return anthropicKey
|
|
63
|
+
? {
|
|
64
|
+
mode: 'anthropic',
|
|
65
|
+
apiKey: anthropicKey,
|
|
66
|
+
model: config.summarizer_model,
|
|
67
|
+
cwd: config.repo_root,
|
|
68
|
+
}
|
|
69
|
+
: undefined;
|
|
70
|
+
}
|
|
71
|
+
const requestedAgent = config.native_summarizer_agent
|
|
72
|
+
?? parseNativeAgent(process.env.MEMOIRE_NATIVE_SUMMARIZER_AGENT)
|
|
73
|
+
?? defaultNativeAgent(config);
|
|
74
|
+
if (requestedAgent === 'claude' && commandExists('claude')) {
|
|
75
|
+
return {
|
|
76
|
+
mode: 'native-claude',
|
|
77
|
+
model: config.summarizer_model,
|
|
78
|
+
cwd: config.repo_root,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
if (requestedAgent === 'codex' && commandExists('codex')) {
|
|
82
|
+
return {
|
|
83
|
+
mode: 'native-codex',
|
|
84
|
+
model: config.summarizer_model,
|
|
85
|
+
cwd: config.repo_root,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
return anthropicKey
|
|
89
|
+
? {
|
|
90
|
+
mode: 'anthropic',
|
|
91
|
+
apiKey: anthropicKey,
|
|
92
|
+
model: config.summarizer_model,
|
|
93
|
+
cwd: config.repo_root,
|
|
94
|
+
}
|
|
95
|
+
: undefined;
|
|
96
|
+
}
|
|
97
|
+
function parseSummarizationMode(value) {
|
|
98
|
+
if (value === 'server' || value === 'edge_anthropic' || value === 'native_agent') {
|
|
99
|
+
return value;
|
|
100
|
+
}
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
function parseNativeAgent(value) {
|
|
104
|
+
if (value === 'claude' || value === 'codex') {
|
|
105
|
+
return value;
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
function defaultNativeAgent(config) {
|
|
110
|
+
if (config.client === 'claude' && commandExists('claude'))
|
|
111
|
+
return 'claude';
|
|
112
|
+
if (config.client === 'codex' && commandExists('codex'))
|
|
113
|
+
return 'codex';
|
|
114
|
+
if (commandExists('claude'))
|
|
115
|
+
return 'claude';
|
|
116
|
+
if (commandExists('codex'))
|
|
117
|
+
return 'codex';
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
function commandExists(command) {
|
|
121
|
+
const pathValue = process.env.PATH ?? '';
|
|
122
|
+
for (const segment of pathValue.split(delimiter)) {
|
|
123
|
+
if (!segment)
|
|
124
|
+
continue;
|
|
125
|
+
if (existsSync(join(segment, command))) {
|
|
126
|
+
return true;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return false;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAMlC,OAAO,EAAE,SAAS,EAAwB,MAAM,cAAc,CAAC;AAW/D,MAAM,UAAU,oBAAoB,CAAC,IAAwB;IAC3D,IAAI,IAAI,EAAE,UAAU;QAAE,OAAO,IAAI,CAAC,UAAU,CAAC;IAC7C,OAAO,IAAI,CAAC,IAAI,EAAE,OAAO,IAAI,OAAO,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAwB;IACxD,MAAM,UAAU,GAAG,oBAAoB,CAAC,IAAI,CAAC,CAAC;IAE9C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,+BAA+B,UAAU,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAA2B,CAAC;IACpF,MAAM,cAAc,GAAG;QACrB,SAAS;QACT,SAAS;QACT,QAAQ;QACR,YAAY;QACZ,SAAS;QACT,QAAQ;QACR,cAAc;KACN,CAAC;IAEX,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;QACnC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,OAAO,GAAG,CAAC,KAAK,CAAC,KAAK,QAAQ,EAAE,CAAC;YAClD,MAAM,IAAI,KAAK,CAAC,6CAA6C,KAAK,GAAG,CAAC,CAAC;QACzE,CAAC;IACH,CAAC;IAED,OAAO,GAAoB,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,IAAiC;IACzE,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,UAAU,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAEnD,OAAO,IAAI,SAAS,CAAC;QACnB,MAAM,EAAE,MAAM,CAAC,OAAO;QACtB,MAAM,EAAE,MAAM,CAAC,OAAO;QACtB,KAAK,EAAE,MAAM,CAAC,MAAM;QACpB,SAAS,EAAE,MAAM,CAAC,UAAU;QAC5B,MAAM,EAAE,MAAM,CAAC,OAAO;QACtB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,MAAM,EAAE,MAAM,CAAC,OAAO;QACtB,QAAQ,EAAE,MAAM,CAAC,SAAS;QAC1B,aAAa,EAAE,MAAM,CAAC,SAAS;QAC/B,UAAU;QACV,GAAG,IAAI,EAAE,SAAS;KACnB,CAAC,CAAC;AACL,CAAC;AAED,SAAS,uBAAuB,CAAC,MAAqB;IACpD,MAAM,YAAY,GAAG,MAAM,CAAC,iBAAiB;WACxC,OAAO,CAAC,GAAG,CAAC,yBAAyB;WACrC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;IACnC,MAAM,YAAY,GAAG,MAAM,CAAC,kBAAkB;WACzC,sBAAsB,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;WAC9D,CAAC,MAAM,CAAC,yBAAyB,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,MAAM;YACrF,CAAC,CAAC,gBAAgB;YAClB,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEhB,IAAI,YAAY,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,IAAI,YAAY,KAAK,gBAAgB,EAAE,CAAC;QACtC,OAAO,YAAY;YACjB,CAAC,CAAC;gBACE,IAAI,EAAE,WAAW;gBACjB,MAAM,EAAE,YAAY;gBACpB,KAAK,EAAE,MAAM,CAAC,gBAAgB;gBAC9B,GAAG,EAAE,MAAM,CAAC,SAAS;aACtB;YACH,CAAC,CAAC,SAAS,CAAC;IAChB,CAAC;IAED,MAAM,cAAc,GAAG,MAAM,CAAC,uBAAuB;WAChD,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC;WAC7D,kBAAkB,CAAC,MAAM,CAAC,CAAC;IAEhC,IAAI,cAAc,KAAK,QAAQ,IAAI,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC3D,OAAO;YACL,IAAI,EAAE,eAAe;YACrB,KAAK,EAAE,MAAM,CAAC,gBAAgB;YAC9B,GAAG,EAAE,MAAM,CAAC,SAAS;SACtB,CAAC;IACJ,CAAC;IAED,IAAI,cAAc,KAAK,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC;QACzD,OAAO;YACL,IAAI,EAAE,cAAc;YACpB,KAAK,EAAE,MAAM,CAAC,gBAAgB;YAC9B,GAAG,EAAE,MAAM,CAAC,SAAS;SACtB,CAAC;IACJ,CAAC;IAED,OAAO,YAAY;QACjB,CAAC,CAAC;YACE,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,YAAY;YACpB,KAAK,EAAE,MAAM,CAAC,gBAAgB;YAC9B,GAAG,EAAE,MAAM,CAAC,SAAS;SACtB;QACH,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,SAAS,sBAAsB,CAAC,KAAyB;IACvD,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,gBAAgB,IAAI,KAAK,KAAK,cAAc,EAAE,CAAC;QACjF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAyB;IACjD,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,kBAAkB,CAAC,MAAqB;IAC/C,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,aAAa,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC3E,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,IAAI,aAAa,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IACxE,IAAI,aAAa,CAAC,QAAQ,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC7C,IAAI,aAAa,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC3C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;IACzC,KAAK,MAAM,OAAO,IAAI,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACjD,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.test.d.ts","sourceRoot":"","sources":["../src/config.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { chmodSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { tmpdir } from 'node:os';
|
|
6
|
+
import { createCollectorFromConfig, readMemoireConfig } from './config.js';
|
|
7
|
+
test('readMemoireConfig loads the shared config file', () => {
|
|
8
|
+
const homeDir = mkdtempSync(join(tmpdir(), 'memoire-collector-'));
|
|
9
|
+
try {
|
|
10
|
+
const configDir = join(homeDir, '.memoire');
|
|
11
|
+
mkdirSync(configDir, { recursive: true });
|
|
12
|
+
writeFileSync(join(configDir, 'config.json'), JSON.stringify({
|
|
13
|
+
api_url: 'http://localhost:8080',
|
|
14
|
+
api_key: 'sk_mem_test',
|
|
15
|
+
org_id: 'org-1',
|
|
16
|
+
project_id: 'project-1',
|
|
17
|
+
user_id: 'user-1',
|
|
18
|
+
client: 'cursor',
|
|
19
|
+
repo_id: 'memoire',
|
|
20
|
+
installed_at: '2026-03-10T00:00:00.000Z',
|
|
21
|
+
}));
|
|
22
|
+
const config = readMemoireConfig({ homeDir });
|
|
23
|
+
assert.equal(config.project_id, 'project-1');
|
|
24
|
+
assert.equal(config.client, 'cursor');
|
|
25
|
+
assert.equal(config.repo_id, 'memoire');
|
|
26
|
+
}
|
|
27
|
+
finally {
|
|
28
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
test('createCollectorFromConfig instantiates a collector from the shared config', () => {
|
|
32
|
+
const homeDir = mkdtempSync(join(tmpdir(), 'memoire-collector-'));
|
|
33
|
+
try {
|
|
34
|
+
const configDir = join(homeDir, '.memoire');
|
|
35
|
+
mkdirSync(configDir, { recursive: true });
|
|
36
|
+
writeFileSync(join(configDir, 'config.json'), JSON.stringify({
|
|
37
|
+
api_url: 'http://localhost:8080',
|
|
38
|
+
api_key: 'sk_mem_test',
|
|
39
|
+
org_id: 'org-1',
|
|
40
|
+
project_id: 'project-1',
|
|
41
|
+
user_id: 'user-1',
|
|
42
|
+
client: 'cursor',
|
|
43
|
+
installed_at: '2026-03-10T00:00:00.000Z',
|
|
44
|
+
}));
|
|
45
|
+
const collector = createCollectorFromConfig({ homeDir });
|
|
46
|
+
assert.equal(collector.pendingEvents, 0);
|
|
47
|
+
collector.destroy();
|
|
48
|
+
}
|
|
49
|
+
finally {
|
|
50
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
test('createCollectorFromConfig enables client-side summarization from config', () => {
|
|
54
|
+
const homeDir = mkdtempSync(join(tmpdir(), 'memoire-collector-'));
|
|
55
|
+
try {
|
|
56
|
+
const configDir = join(homeDir, '.memoire');
|
|
57
|
+
mkdirSync(configDir, { recursive: true });
|
|
58
|
+
writeFileSync(join(configDir, 'config.json'), JSON.stringify({
|
|
59
|
+
api_url: 'http://localhost:8080',
|
|
60
|
+
api_key: 'sk_mem_test',
|
|
61
|
+
org_id: 'org-1',
|
|
62
|
+
project_id: 'project-1',
|
|
63
|
+
user_id: 'user-1',
|
|
64
|
+
client: 'claude',
|
|
65
|
+
installed_at: '2026-03-10T00:00:00.000Z',
|
|
66
|
+
client_side_summarization: true,
|
|
67
|
+
anthropic_api_key: 'sk-ant-test-key',
|
|
68
|
+
summarizer_model: 'claude-3-5-haiku-20241022',
|
|
69
|
+
}));
|
|
70
|
+
const collector = createCollectorFromConfig({ homeDir });
|
|
71
|
+
assert.equal(collector.summarizer?.config?.mode, 'anthropic');
|
|
72
|
+
assert.equal(collector.pendingEvents, 0);
|
|
73
|
+
collector.destroy();
|
|
74
|
+
}
|
|
75
|
+
finally {
|
|
76
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
test('createCollectorFromConfig does not enable summarizer without anthropic key', () => {
|
|
80
|
+
const homeDir = mkdtempSync(join(tmpdir(), 'memoire-collector-'));
|
|
81
|
+
// Clear env vars that could enable it
|
|
82
|
+
const savedKey = process.env.ANTHROPIC_API_KEY;
|
|
83
|
+
const savedMemoireKey = process.env.MEMOIRE_ANTHROPIC_API_KEY;
|
|
84
|
+
const savedToggle = process.env.MEMOIRE_CLIENT_SUMMARIZE;
|
|
85
|
+
delete process.env.ANTHROPIC_API_KEY;
|
|
86
|
+
delete process.env.MEMOIRE_ANTHROPIC_API_KEY;
|
|
87
|
+
delete process.env.MEMOIRE_CLIENT_SUMMARIZE;
|
|
88
|
+
try {
|
|
89
|
+
const configDir = join(homeDir, '.memoire');
|
|
90
|
+
mkdirSync(configDir, { recursive: true });
|
|
91
|
+
writeFileSync(join(configDir, 'config.json'), JSON.stringify({
|
|
92
|
+
api_url: 'http://localhost:8080',
|
|
93
|
+
api_key: 'sk_mem_test',
|
|
94
|
+
org_id: 'org-1',
|
|
95
|
+
project_id: 'project-1',
|
|
96
|
+
user_id: 'user-1',
|
|
97
|
+
client: 'cursor',
|
|
98
|
+
installed_at: '2026-03-10T00:00:00.000Z',
|
|
99
|
+
client_side_summarization: true,
|
|
100
|
+
// No anthropic_api_key
|
|
101
|
+
}));
|
|
102
|
+
const collector = createCollectorFromConfig({ homeDir });
|
|
103
|
+
assert.equal(collector.summarizer, null);
|
|
104
|
+
assert.equal(collector.pendingEvents, 0);
|
|
105
|
+
collector.destroy();
|
|
106
|
+
}
|
|
107
|
+
finally {
|
|
108
|
+
// Restore env
|
|
109
|
+
if (savedKey)
|
|
110
|
+
process.env.ANTHROPIC_API_KEY = savedKey;
|
|
111
|
+
if (savedMemoireKey)
|
|
112
|
+
process.env.MEMOIRE_ANTHROPIC_API_KEY = savedMemoireKey;
|
|
113
|
+
if (savedToggle)
|
|
114
|
+
process.env.MEMOIRE_CLIENT_SUMMARIZE = savedToggle;
|
|
115
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
test('createCollectorFromConfig uses native Claude mode when requested and CLI is available', () => {
|
|
119
|
+
const homeDir = mkdtempSync(join(tmpdir(), 'memoire-collector-'));
|
|
120
|
+
const binDir = mkdtempSync(join(tmpdir(), 'memoire-bin-'));
|
|
121
|
+
const savedPath = process.env.PATH;
|
|
122
|
+
try {
|
|
123
|
+
writeFileSync(join(binDir, 'claude'), '#!/bin/sh\nexit 0\n');
|
|
124
|
+
chmodSync(join(binDir, 'claude'), 0o755);
|
|
125
|
+
process.env.PATH = `${binDir}:${savedPath ?? ''}`;
|
|
126
|
+
const configDir = join(homeDir, '.memoire');
|
|
127
|
+
mkdirSync(configDir, { recursive: true });
|
|
128
|
+
writeFileSync(join(configDir, 'config.json'), JSON.stringify({
|
|
129
|
+
api_url: 'http://localhost:8080',
|
|
130
|
+
api_key: 'sk_mem_test',
|
|
131
|
+
org_id: 'org-1',
|
|
132
|
+
project_id: 'project-1',
|
|
133
|
+
user_id: 'user-1',
|
|
134
|
+
client: 'claude',
|
|
135
|
+
repo_root: '/tmp/project',
|
|
136
|
+
installed_at: '2026-03-10T00:00:00.000Z',
|
|
137
|
+
summarization_mode: 'native_agent',
|
|
138
|
+
native_summarizer_agent: 'claude',
|
|
139
|
+
}));
|
|
140
|
+
const collector = createCollectorFromConfig({ homeDir });
|
|
141
|
+
assert.equal(collector.summarizer?.config?.mode, 'native-claude');
|
|
142
|
+
assert.equal(collector.summarizer?.config?.cwd, '/tmp/project');
|
|
143
|
+
collector.destroy();
|
|
144
|
+
}
|
|
145
|
+
finally {
|
|
146
|
+
process.env.PATH = savedPath;
|
|
147
|
+
rmSync(binDir, { recursive: true, force: true });
|
|
148
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
test('createCollectorFromConfig uses native Codex mode when requested and CLI is available', () => {
|
|
152
|
+
const homeDir = mkdtempSync(join(tmpdir(), 'memoire-collector-'));
|
|
153
|
+
const binDir = mkdtempSync(join(tmpdir(), 'memoire-bin-'));
|
|
154
|
+
const savedPath = process.env.PATH;
|
|
155
|
+
try {
|
|
156
|
+
writeFileSync(join(binDir, 'codex'), '#!/bin/sh\nexit 0\n');
|
|
157
|
+
chmodSync(join(binDir, 'codex'), 0o755);
|
|
158
|
+
process.env.PATH = `${binDir}:${savedPath ?? ''}`;
|
|
159
|
+
const configDir = join(homeDir, '.memoire');
|
|
160
|
+
mkdirSync(configDir, { recursive: true });
|
|
161
|
+
writeFileSync(join(configDir, 'config.json'), JSON.stringify({
|
|
162
|
+
api_url: 'http://localhost:8080',
|
|
163
|
+
api_key: 'sk_mem_test',
|
|
164
|
+
org_id: 'org-1',
|
|
165
|
+
project_id: 'project-1',
|
|
166
|
+
user_id: 'user-1',
|
|
167
|
+
client: 'codex',
|
|
168
|
+
installed_at: '2026-03-10T00:00:00.000Z',
|
|
169
|
+
summarization_mode: 'native_agent',
|
|
170
|
+
native_summarizer_agent: 'codex',
|
|
171
|
+
}));
|
|
172
|
+
const collector = createCollectorFromConfig({ homeDir });
|
|
173
|
+
assert.equal(collector.summarizer?.config?.mode, 'native-codex');
|
|
174
|
+
collector.destroy();
|
|
175
|
+
}
|
|
176
|
+
finally {
|
|
177
|
+
process.env.PATH = savedPath;
|
|
178
|
+
rmSync(binDir, { recursive: true, force: true });
|
|
179
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
//# sourceMappingURL=config.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.test.js","sourceRoot":"","sources":["../src/config.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export interface CursorHooksConfig {
|
|
2
|
+
/** Hook definitions keyed by Cursor lifecycle event. */
|
|
3
|
+
hooks: {
|
|
4
|
+
beforeSubmitPrompt?: CursorHookEntry[];
|
|
5
|
+
stop?: CursorHookEntry[];
|
|
6
|
+
afterMCPExecution?: CursorHookEntry[];
|
|
7
|
+
afterShellExecution?: CursorHookEntry[];
|
|
8
|
+
afterFileEdit?: CursorHookEntry[];
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
interface CursorHookEntry {
|
|
12
|
+
command: string;
|
|
13
|
+
description: string;
|
|
14
|
+
blocking: boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Generate a Cursor `hooks.json` configuration object.
|
|
18
|
+
*
|
|
19
|
+
* The returned object can be serialised to `<project>/.cursor/hooks.json`
|
|
20
|
+
* (or merged into an existing one).
|
|
21
|
+
*
|
|
22
|
+
* @param apiUrl - Optional Memoire API URL baked into hook commands.
|
|
23
|
+
* When omitted, scripts read from env / config file at runtime.
|
|
24
|
+
*/
|
|
25
|
+
export declare function generateHooksJson(apiUrl?: string): CursorHooksConfig;
|
|
26
|
+
/**
|
|
27
|
+
* Return human-readable setup instructions for a given project path.
|
|
28
|
+
*/
|
|
29
|
+
export declare function generateSetupInstructions(projectPath: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Install Memoire Cursor hooks into a project directory.
|
|
32
|
+
*
|
|
33
|
+
* 1. Copies (or merges) `hooks.json` into `<project>/.cursor/hooks.json`
|
|
34
|
+
* 2. Copies shell scripts into `<project>/.cursor/hooks/`
|
|
35
|
+
* 3. Makes shell scripts executable (chmod +x)
|
|
36
|
+
* 4. Optionally writes `~/.memoire/config` with API credentials
|
|
37
|
+
*
|
|
38
|
+
* Safe to call repeatedly — existing hooks are preserved via merge.
|
|
39
|
+
*
|
|
40
|
+
* @param projectPath - Absolute or relative path to the project root
|
|
41
|
+
* @param apiUrl - Memoire API URL (written to config if provided)
|
|
42
|
+
* @param apiKey - Memoire API key (written to config if provided)
|
|
43
|
+
*/
|
|
44
|
+
export declare function installCursorHooks(projectPath: string, apiUrl?: string, apiKey?: string): void;
|
|
45
|
+
export {};
|
|
46
|
+
//# sourceMappingURL=cursor-hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cursor-hooks.d.ts","sourceRoot":"","sources":["../src/cursor-hooks.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,iBAAiB;IAChC,wDAAwD;IACxD,KAAK,EAAE;QACL,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAC;QACvC,IAAI,CAAC,EAAE,eAAe,EAAE,CAAC;QACzB,iBAAiB,CAAC,EAAE,eAAe,EAAE,CAAC;QACtC,mBAAmB,CAAC,EAAE,eAAe,EAAE,CAAC;QACxC,aAAa,CAAC,EAAE,eAAe,EAAE,CAAC;KACnC,CAAC;CACH;AAED,UAAU,eAAe;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAwCD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,iBAAiB,CA0CpE;AAMD;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA6BrE;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,GACd,IAAI,CAkDN"}
|