super-memory-pro 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 (107) hide show
  1. package/README.md +247 -0
  2. package/dist/config.d.ts +6 -0
  3. package/dist/config.d.ts.map +1 -0
  4. package/dist/config.js +25 -0
  5. package/dist/config.js.map +1 -0
  6. package/dist/db/connection.d.ts +20 -0
  7. package/dist/db/connection.d.ts.map +1 -0
  8. package/dist/db/connection.js +66 -0
  9. package/dist/db/connection.js.map +1 -0
  10. package/dist/db/migrations/001_initial.sql +102 -0
  11. package/dist/db/migrations.d.ts +14 -0
  12. package/dist/db/migrations.d.ts.map +1 -0
  13. package/dist/db/migrations.js +86 -0
  14. package/dist/db/migrations.js.map +1 -0
  15. package/dist/db/queries.d.ts +24 -0
  16. package/dist/db/queries.d.ts.map +1 -0
  17. package/dist/db/queries.js +179 -0
  18. package/dist/db/queries.js.map +1 -0
  19. package/dist/hooks/event-handler.d.ts +13 -0
  20. package/dist/hooks/event-handler.d.ts.map +1 -0
  21. package/dist/hooks/event-handler.js +80 -0
  22. package/dist/hooks/event-handler.js.map +1 -0
  23. package/dist/hooks/index.d.ts +4 -0
  24. package/dist/hooks/index.d.ts.map +1 -0
  25. package/dist/hooks/index.js +7 -0
  26. package/dist/hooks/index.js.map +1 -0
  27. package/dist/hooks/message-handler.d.ts +13 -0
  28. package/dist/hooks/message-handler.d.ts.map +1 -0
  29. package/dist/hooks/message-handler.js +47 -0
  30. package/dist/hooks/message-handler.js.map +1 -0
  31. package/dist/hooks/session-compactor.d.ts +15 -0
  32. package/dist/hooks/session-compactor.d.ts.map +1 -0
  33. package/dist/hooks/session-compactor.js +40 -0
  34. package/dist/hooks/session-compactor.js.map +1 -0
  35. package/dist/hooks/system-transform.d.ts +27 -0
  36. package/dist/hooks/system-transform.d.ts.map +1 -0
  37. package/dist/hooks/system-transform.js +76 -0
  38. package/dist/hooks/system-transform.js.map +1 -0
  39. package/dist/hooks/tool-handler.d.ts +14 -0
  40. package/dist/hooks/tool-handler.d.ts.map +1 -0
  41. package/dist/hooks/tool-handler.js +94 -0
  42. package/dist/hooks/tool-handler.js.map +1 -0
  43. package/dist/index.d.ts +4 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +152 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/installer/index.d.ts +19 -0
  48. package/dist/installer/index.d.ts.map +1 -0
  49. package/dist/installer/index.js +553 -0
  50. package/dist/installer/index.js.map +1 -0
  51. package/dist/memory/extractor.d.ts +29 -0
  52. package/dist/memory/extractor.d.ts.map +1 -0
  53. package/dist/memory/extractor.js +426 -0
  54. package/dist/memory/extractor.js.map +1 -0
  55. package/dist/memory/index.d.ts +7 -0
  56. package/dist/memory/index.d.ts.map +1 -0
  57. package/dist/memory/index.js +7 -0
  58. package/dist/memory/index.js.map +1 -0
  59. package/dist/memory/processor.d.ts +50 -0
  60. package/dist/memory/processor.d.ts.map +1 -0
  61. package/dist/memory/processor.js +199 -0
  62. package/dist/memory/processor.js.map +1 -0
  63. package/dist/memory/search.d.ts +35 -0
  64. package/dist/memory/search.d.ts.map +1 -0
  65. package/dist/memory/search.js +170 -0
  66. package/dist/memory/search.js.map +1 -0
  67. package/dist/memory/store.d.ts +32 -0
  68. package/dist/memory/store.d.ts.map +1 -0
  69. package/dist/memory/store.js +112 -0
  70. package/dist/memory/store.js.map +1 -0
  71. package/dist/server/index.d.ts +16 -0
  72. package/dist/server/index.d.ts.map +1 -0
  73. package/dist/server/index.js +49 -0
  74. package/dist/server/index.js.map +1 -0
  75. package/dist/server/middleware/async-handler.d.ts +11 -0
  76. package/dist/server/middleware/async-handler.d.ts.map +1 -0
  77. package/dist/server/middleware/async-handler.js +14 -0
  78. package/dist/server/middleware/async-handler.js.map +1 -0
  79. package/dist/server/middleware/error-handler.d.ts +11 -0
  80. package/dist/server/middleware/error-handler.d.ts.map +1 -0
  81. package/dist/server/middleware/error-handler.js +18 -0
  82. package/dist/server/middleware/error-handler.js.map +1 -0
  83. package/dist/server/routes/health.d.ts +2 -0
  84. package/dist/server/routes/health.d.ts.map +1 -0
  85. package/dist/server/routes/health.js +25 -0
  86. package/dist/server/routes/health.js.map +1 -0
  87. package/dist/server/routes/memory.d.ts +2 -0
  88. package/dist/server/routes/memory.d.ts.map +1 -0
  89. package/dist/server/routes/memory.js +139 -0
  90. package/dist/server/routes/memory.js.map +1 -0
  91. package/dist/server/schemas.d.ts +51 -0
  92. package/dist/server/schemas.d.ts.map +1 -0
  93. package/dist/server/schemas.js +23 -0
  94. package/dist/server/schemas.js.map +1 -0
  95. package/dist/tools/definitions.d.ts +130 -0
  96. package/dist/tools/definitions.d.ts.map +1 -0
  97. package/dist/tools/definitions.js +78 -0
  98. package/dist/tools/definitions.js.map +1 -0
  99. package/dist/tools/index.d.ts +32 -0
  100. package/dist/tools/index.d.ts.map +1 -0
  101. package/dist/tools/index.js +148 -0
  102. package/dist/tools/index.js.map +1 -0
  103. package/dist/types.d.ts +108 -0
  104. package/dist/types.d.ts.map +1 -0
  105. package/dist/types.js +12 -0
  106. package/dist/types.js.map +1 -0
  107. package/package.json +70 -0
@@ -0,0 +1,179 @@
1
+ import { getPool } from './connection.js';
2
+ // ─── Memories ───────────────────────────────────────────────────────────────
3
+ export async function createMemory(data) {
4
+ const pool = getPool();
5
+ const result = await pool.query(`INSERT INTO memories (memory_type, project_id, session_id, key, value, content, importance, source, metadata)
6
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
7
+ ON CONFLICT (memory_type, project_id, key)
8
+ DO UPDATE SET content = EXCLUDED.content, importance = EXCLUDED.importance, updated_at = NOW()
9
+ RETURNING *`, [
10
+ data.memory_type,
11
+ data.project_id ?? null,
12
+ data.session_id ?? null,
13
+ data.key,
14
+ JSON.stringify(data.value ?? {}),
15
+ data.content,
16
+ data.importance ?? 3,
17
+ data.source ?? 'auto',
18
+ JSON.stringify(data.metadata ?? {}),
19
+ ]);
20
+ return result.rows[0];
21
+ }
22
+ export async function getMemory(id) {
23
+ const pool = getPool();
24
+ const result = await pool.query('SELECT * FROM memories WHERE id = $1', [id]);
25
+ return result.rows[0] ?? null;
26
+ }
27
+ export async function searchMemories(query) {
28
+ const pool = getPool();
29
+ const { query: searchText, types, project_id, limit = 10, offset = 0 } = query;
30
+ const conditions = [];
31
+ const params = [];
32
+ // $1 is always reserved for the search text (used in CASE and tsquery)
33
+ let paramIdx = 2;
34
+ // Full-text search
35
+ if (searchText) {
36
+ conditions.push(`search_vector @@ plainto_tsquery('english', $1)`);
37
+ }
38
+ // Type filter
39
+ if (types && types.length > 0) {
40
+ conditions.push(`memory_type = ANY($${paramIdx}::text[])`);
41
+ params.push(types);
42
+ paramIdx++;
43
+ }
44
+ // Project filter
45
+ if (project_id) {
46
+ conditions.push(`project_id = $${paramIdx}`);
47
+ params.push(project_id);
48
+ paramIdx++;
49
+ }
50
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
51
+ const sql = `
52
+ SELECT *,
53
+ CASE WHEN $1::text IS NOT NULL AND $1::text != ''
54
+ THEN ts_rank(search_vector, plainto_tsquery('english', $1::text))
55
+ ELSE importance::float / 5.0
56
+ END AS relevance
57
+ FROM memories
58
+ ${where}
59
+ ORDER BY relevance DESC, importance DESC, last_accessed_at DESC NULLS LAST
60
+ LIMIT $${paramIdx} OFFSET $${paramIdx + 1}
61
+ `;
62
+ const allParams = [searchText ?? '', ...params, limit, offset];
63
+ const result = await pool.query(sql, allParams);
64
+ return result.rows.map((row) => ({
65
+ memory: row,
66
+ relevance: row.relevance,
67
+ }));
68
+ }
69
+ export async function updateMemory(id, data) {
70
+ const pool = getPool();
71
+ const sets = [];
72
+ const params = [];
73
+ let idx = 1;
74
+ if (data.content !== undefined) {
75
+ sets.push(`content = $${idx++}`);
76
+ params.push(data.content);
77
+ }
78
+ if (data.value !== undefined) {
79
+ sets.push(`value = $${idx++}`);
80
+ params.push(JSON.stringify(data.value));
81
+ }
82
+ if (data.importance !== undefined) {
83
+ sets.push(`importance = $${idx++}`);
84
+ params.push(data.importance);
85
+ }
86
+ if (data.metadata !== undefined) {
87
+ sets.push(`metadata = $${idx++}`);
88
+ params.push(JSON.stringify(data.metadata));
89
+ }
90
+ if (sets.length === 0)
91
+ return getMemory(id);
92
+ params.push(id);
93
+ const sql = `UPDATE memories SET ${sets.join(', ')} WHERE id = $${idx} RETURNING *`;
94
+ const result = await pool.query(sql, params);
95
+ return result.rows[0] ?? null;
96
+ }
97
+ export async function deleteMemory(id) {
98
+ const pool = getPool();
99
+ const result = await pool.query('DELETE FROM memories WHERE id = $1', [id]);
100
+ return (result.rowCount ?? 0) > 0;
101
+ }
102
+ export async function recordMemoryAccess(id) {
103
+ const pool = getPool();
104
+ await pool.query(`UPDATE memories SET access_count = access_count + 1, last_accessed_at = NOW() WHERE id = $1`, [id]);
105
+ }
106
+ export async function getMemoryStats() {
107
+ const pool = getPool();
108
+ const result = await pool.query('SELECT memory_type AS type, COUNT(*)::int AS count FROM memories GROUP BY memory_type ORDER BY count DESC');
109
+ return result.rows;
110
+ }
111
+ // ─── Sessions ───────────────────────────────────────────────────────────────
112
+ export async function createSession(id, projectId) {
113
+ const pool = getPool();
114
+ const result = await pool.query('INSERT INTO sessions (id, project_id) VALUES ($1, $2) RETURNING *', [id, projectId ?? null]);
115
+ return result.rows[0];
116
+ }
117
+ export async function getSession(id) {
118
+ const pool = getPool();
119
+ const result = await pool.query('SELECT * FROM sessions WHERE id = $1', [id]);
120
+ return result.rows[0] ?? null;
121
+ }
122
+ export async function updateSession(id, data) {
123
+ const pool = getPool();
124
+ const sets = [];
125
+ const params = [];
126
+ let idx = 1;
127
+ if (data.summary !== undefined) {
128
+ sets.push(`summary = $${idx++}`);
129
+ params.push(data.summary);
130
+ }
131
+ if (data.message_count !== undefined) {
132
+ sets.push(`message_count = $${idx++}`);
133
+ params.push(data.message_count);
134
+ }
135
+ if (data.tokens_used !== undefined) {
136
+ sets.push(`tokens_used = $${idx++}`);
137
+ params.push(data.tokens_used);
138
+ }
139
+ if (data.ended_at !== undefined) {
140
+ sets.push(`ended_at = $${idx++}`);
141
+ params.push(data.ended_at);
142
+ }
143
+ if (data.metadata !== undefined) {
144
+ sets.push(`metadata = $${idx++}`);
145
+ params.push(JSON.stringify(data.metadata));
146
+ }
147
+ if (sets.length === 0)
148
+ return getSession(id);
149
+ params.push(id);
150
+ const sql = `UPDATE sessions SET ${sets.join(', ')} WHERE id = $${idx} RETURNING *`;
151
+ const result = await pool.query(sql, params);
152
+ return result.rows[0] ?? null;
153
+ }
154
+ // ─── Projects ───────────────────────────────────────────────────────────────
155
+ export async function createProject(data) {
156
+ const pool = getPool();
157
+ const result = await pool.query(`INSERT INTO projects (id, name, path, description)
158
+ VALUES ($1, $2, $3, $4)
159
+ ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, updated_at = NOW()
160
+ RETURNING *`, [data.id, data.name, data.path ?? null, data.description ?? null]);
161
+ return result.rows[0];
162
+ }
163
+ export async function getProject(id) {
164
+ const pool = getPool();
165
+ const result = await pool.query('SELECT * FROM projects WHERE id = $1', [id]);
166
+ return result.rows[0] ?? null;
167
+ }
168
+ export async function updateProjectTechStack(projectId, tech) {
169
+ const pool = getPool();
170
+ await pool.query(`UPDATE projects SET tech_stack = (
171
+ SELECT jsonb_agg(DISTINCT value) FROM jsonb_array_elements_text(tech_stack || $2::jsonb) AS value
172
+ ), updated_at = NOW() WHERE id = $1`, [projectId, JSON.stringify(tech)]);
173
+ }
174
+ export async function getAllProjects() {
175
+ const pool = getPool();
176
+ const result = await pool.query('SELECT * FROM projects ORDER BY updated_at DESC');
177
+ return result.rows;
178
+ }
179
+ //# sourceMappingURL=queries.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queries.js","sourceRoot":"","sources":["../../src/db/queries.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import type { Hooks } from '@opencode-ai/plugin';
2
+ /**
3
+ * Create a handler for the `event` hook.
4
+ *
5
+ * Filters for relevant event types and triggers memory processing:
6
+ * - On message completion: extracts text and stores via the processor
7
+ * - On session lifecycle: logs and updates session context
8
+ *
9
+ * The handler is fire-and-forget — it returns immediately without awaiting
10
+ * any memory operations.
11
+ */
12
+ export declare function createEventHandler(): Hooks['event'];
13
+ //# sourceMappingURL=event-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-handler.d.ts","sourceRoot":"","sources":["../../src/hooks/event-handler.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAIjD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,KAAK,CAAC,OAAO,CAAC,CAsDnD"}
@@ -0,0 +1,80 @@
1
+ // ─── Event Handler ───────────────────────────────────────────────────────────
2
+ // Handles the `event` hook — listens for relevant lifecycle events and
3
+ // updates the memory system accordingly. Fire-and-forget to never block.
4
+ // ──────────────────────────────────────────────────────────────────────────────
5
+ import { processMessage } from '../memory/processor.js';
6
+ /**
7
+ * Create a handler for the `event` hook.
8
+ *
9
+ * Filters for relevant event types and triggers memory processing:
10
+ * - On message completion: extracts text and stores via the processor
11
+ * - On session lifecycle: logs and updates session context
12
+ *
13
+ * The handler is fire-and-forget — it returns immediately without awaiting
14
+ * any memory operations.
15
+ */
16
+ export function createEventHandler() {
17
+ return async ({ event }) => {
18
+ // Fire-and-forget: kick off async work without awaiting
19
+ const run = async () => {
20
+ try {
21
+ if (!isRelevantEvent(event))
22
+ return;
23
+ switch (event.type) {
24
+ case 'message.updated': {
25
+ const { info } = event.properties;
26
+ // Only process assistant messages (completions) that have text
27
+ if (info.role !== 'assistant')
28
+ return;
29
+ // Record that an assistant interaction occurred
30
+ const summaryLine = `Assistant responded (model: ${info.modelID})`;
31
+ await processMessage(summaryLine, {
32
+ sessionId: info.sessionID,
33
+ source: 'event',
34
+ });
35
+ break;
36
+ }
37
+ case 'session.created': {
38
+ const sessionInfo = event.properties.info;
39
+ console.log(`[UltraMemory] Session created: ${sessionInfo.id} (${sessionInfo.title})`);
40
+ break;
41
+ }
42
+ case 'session.updated': {
43
+ const sessionInfo = event.properties.info;
44
+ console.log(`[UltraMemory] Session updated: ${sessionInfo.id}`);
45
+ break;
46
+ }
47
+ case 'session.compacted': {
48
+ const { sessionID } = event.properties;
49
+ console.log(`[UltraMemory] Session compacted: ${sessionID}`);
50
+ break;
51
+ }
52
+ default:
53
+ break;
54
+ }
55
+ }
56
+ catch (err) {
57
+ console.error('[UltraMemory] event-handler error:', err);
58
+ }
59
+ };
60
+ // Kick off but don't await — fire-and-forget
61
+ void run();
62
+ };
63
+ }
64
+ // ─── Helpers ─────────────────────────────────────────────────────────────────
65
+ /**
66
+ * Event types that the memory system cares about.
67
+ */
68
+ const RELEVANT_EVENT_TYPES = new Set([
69
+ 'message.updated',
70
+ 'session.created',
71
+ 'session.updated',
72
+ 'session.compacted',
73
+ ]);
74
+ /**
75
+ * Check whether an event is relevant to the memory system.
76
+ */
77
+ function isRelevantEvent(event) {
78
+ return RELEVANT_EVENT_TYPES.has(event.type);
79
+ }
80
+ //# sourceMappingURL=event-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-handler.js","sourceRoot":"","sources":["../../src/hooks/event-handler.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,uEAAuE;AACvE,yEAAyE;AACzE,iFAAiF;AAIjF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QACzB,wDAAwD;QACxD,MAAM,GAAG,GAAG,KAAK,IAAmB,EAAE;YACpC,IAAI,CAAC;gBACH,IAAI,CAAC,eAAe,CAAC,KAAK,CAAC;oBAAE,OAAO;gBAEpC,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;oBACnB,KAAK,iBAAiB,CAAC,CAAC,CAAC;wBACvB,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC;wBAClC,+DAA+D;wBAC/D,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;4BAAE,OAAO;wBAEtC,gDAAgD;wBAChD,MAAM,WAAW,GAAG,+BAA+B,IAAI,CAAC,OAAO,GAAG,CAAC;wBAEnE,MAAM,cAAc,CAAC,WAAW,EAAE;4BAChC,SAAS,EAAE,IAAI,CAAC,SAAS;4BACzB,MAAM,EAAE,OAAO;yBAChB,CAAC,CAAC;wBACH,MAAM;oBACR,CAAC;oBAED,KAAK,iBAAiB,CAAC,CAAC,CAAC;wBACvB,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;wBAC1C,OAAO,CAAC,GAAG,CACT,kCAAkC,WAAW,CAAC,EAAE,KAAK,WAAW,CAAC,KAAK,GAAG,CAC1E,CAAC;wBACF,MAAM;oBACR,CAAC;oBAED,KAAK,iBAAiB,CAAC,CAAC,CAAC;wBACvB,MAAM,WAAW,GAAG,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;wBAC1C,OAAO,CAAC,GAAG,CAAC,kCAAkC,WAAW,CAAC,EAAE,EAAE,CAAC,CAAC;wBAChE,MAAM;oBACR,CAAC;oBAED,KAAK,mBAAmB,CAAC,CAAC,CAAC;wBACzB,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC;wBACvC,OAAO,CAAC,GAAG,CAAC,oCAAoC,SAAS,EAAE,CAAC,CAAC;wBAC7D,MAAM;oBACR,CAAC;oBAED;wBACE,MAAM;gBACV,CAAC;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC,CAAC;QAEF,6CAA6C;QAC7C,KAAK,GAAG,EAAE,CAAC;IACb,CAAC,CAAC;AACJ,CAAC;AAED,gFAAgF;AAEhF;;GAEG;AACH,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC;IACnC,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,mBAAmB;CACpB,CAAC,CAAC;AAEH;;GAEG;AACH,SAAS,eAAe,CAAC,KAAY;IACnC,OAAO,oBAAoB,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { createMessageHandler } from './message-handler.js';
2
+ export { createEventHandler } from './event-handler.js';
3
+ export { createToolAfterHandler } from './tool-handler.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,7 @@
1
+ // ─── Hooks Barrel ────────────────────────────────────────────────────────────
2
+ // Re-exports all hook handler factories for use by the plugin entry point.
3
+ // ──────────────────────────────────────────────────────────────────────────────
4
+ export { createMessageHandler } from './message-handler.js';
5
+ export { createEventHandler } from './event-handler.js';
6
+ export { createToolAfterHandler } from './tool-handler.js';
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,2EAA2E;AAC3E,iFAAiF;AAEjF,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import type { Hooks } from '@opencode-ai/plugin';
2
+ /**
3
+ * Create a handler for the `chat.message` hook.
4
+ *
5
+ * Extracts message text from text-type parts and feeds it into the memory
6
+ * processor for automatic extraction of tech stack, decisions, preferences,
7
+ * patterns, and content classification.
8
+ *
9
+ * The handler is fire-and-forget — it returns immediately without awaiting
10
+ * the memory processor, ensuring it never blocks message flow.
11
+ */
12
+ export declare function createMessageHandler(): Hooks['chat.message'];
13
+ //# sourceMappingURL=message-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-handler.d.ts","sourceRoot":"","sources":["../../src/hooks/message-handler.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAWjD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,IAAI,KAAK,CAAC,cAAc,CAAC,CA0B5D"}
@@ -0,0 +1,47 @@
1
+ // ─── Message Handler ─────────────────────────────────────────────────────────
2
+ // Handles the `chat.message` hook — extracts text from messages and stores
3
+ // them as memories via the memory processor. Fire-and-forget to never block.
4
+ // ──────────────────────────────────────────────────────────────────────────────
5
+ import { processMessage } from '../memory/processor.js';
6
+ /**
7
+ * Narrow a `Part` to a `TextPart` by discriminating on the `type` field.
8
+ */
9
+ function isTextPart(part) {
10
+ return part.type === 'text';
11
+ }
12
+ /**
13
+ * Create a handler for the `chat.message` hook.
14
+ *
15
+ * Extracts message text from text-type parts and feeds it into the memory
16
+ * processor for automatic extraction of tech stack, decisions, preferences,
17
+ * patterns, and content classification.
18
+ *
19
+ * The handler is fire-and-forget — it returns immediately without awaiting
20
+ * the memory processor, ensuring it never blocks message flow.
21
+ */
22
+ export function createMessageHandler() {
23
+ return async (input, output) => {
24
+ // Fire-and-forget: kick off async work without awaiting
25
+ const run = async () => {
26
+ try {
27
+ const { sessionID } = input;
28
+ const { parts } = output;
29
+ // Filter for text-type parts and extract their content
30
+ const textParts = parts.filter(isTextPart);
31
+ const content = textParts.map((p) => p.text).join('\n').trim();
32
+ if (!content)
33
+ return;
34
+ await processMessage(content, {
35
+ sessionId: sessionID,
36
+ source: 'chat',
37
+ });
38
+ }
39
+ catch (err) {
40
+ console.error('[UltraMemory] message-handler error:', err);
41
+ }
42
+ };
43
+ // Kick off but don't await — fire-and-forget
44
+ void run();
45
+ };
46
+ }
47
+ //# sourceMappingURL=message-handler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-handler.js","sourceRoot":"","sources":["../../src/hooks/message-handler.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,2EAA2E;AAC3E,6EAA6E;AAC7E,iFAAiF;AAIjF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD;;GAEG;AACH,SAAS,UAAU,CAAC,IAAU;IAC5B,OAAO,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;AAC9B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,oBAAoB;IAClC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QAC7B,wDAAwD;QACxD,MAAM,GAAG,GAAG,KAAK,IAAmB,EAAE;YACpC,IAAI,CAAC;gBACH,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;gBAC5B,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;gBAEzB,uDAAuD;gBACvD,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC3C,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;gBAE/D,IAAI,CAAC,OAAO;oBAAE,OAAO;gBAErB,MAAM,cAAc,CAAC,OAAO,EAAE;oBAC5B,SAAS,EAAE,SAAS;oBACpB,MAAM,EAAE,MAAM;iBACf,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,sCAAsC,EAAE,GAAG,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC,CAAC;QAEF,6CAA6C;QAC7C,KAAK,GAAG,EAAE,CAAC;IACb,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { Hooks } from '@opencode-ai/plugin';
2
+ /**
3
+ * Create a session compaction hook for the Ultra Memory plugin.
4
+ *
5
+ * Hooks into `experimental.session.compacting` to add context hints
6
+ * that tell the compactor to preserve important memory-related information
7
+ * (tech stack, decisions, preferences, patterns, conventions).
8
+ *
9
+ * The hook does NOT override the default compaction prompt — it only
10
+ * appends additional context strings to guide what should be retained.
11
+ *
12
+ * @returns The hook function to assign to `experimental.session.compacting`
13
+ */
14
+ export declare function createSessionCompactor(): NonNullable<Hooks['experimental.session.compacting']>;
15
+ //# sourceMappingURL=session-compactor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-compactor.d.ts","sourceRoot":"","sources":["../../src/hooks/session-compactor.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAYjD;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,IAAI,WAAW,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAiB9F"}
@@ -0,0 +1,40 @@
1
+ // ─── Session Compactor Hook ────────────────────────────────────────────────
2
+ // Preserves important context during session compaction.
3
+ // Tells the compactor which information types to retain.
4
+ /**
5
+ * Context strings added to the compaction prompt.
6
+ * These instruct the compactor to preserve memory-related information.
7
+ */
8
+ const COMPACTION_CONTEXT_HINTS = [
9
+ 'Preserve any tech stack, decisions, and user preferences mentioned',
10
+ 'Keep architectural decisions and their rationale',
11
+ 'Retain project-specific conventions and patterns',
12
+ ];
13
+ /**
14
+ * Create a session compaction hook for the Ultra Memory plugin.
15
+ *
16
+ * Hooks into `experimental.session.compacting` to add context hints
17
+ * that tell the compactor to preserve important memory-related information
18
+ * (tech stack, decisions, preferences, patterns, conventions).
19
+ *
20
+ * The hook does NOT override the default compaction prompt — it only
21
+ * appends additional context strings to guide what should be retained.
22
+ *
23
+ * @returns The hook function to assign to `experimental.session.compacting`
24
+ */
25
+ export function createSessionCompactor() {
26
+ return async (_input, output) => {
27
+ try {
28
+ // Append compaction context hints — these tell the compactor what
29
+ // information is important to preserve for Ultra Memory.
30
+ output.context.push(...COMPACTION_CONTEXT_HINTS);
31
+ // Do NOT override the prompt — leave it as undefined so the
32
+ // default compaction prompt is used.
33
+ }
34
+ catch (err) {
35
+ // Fire-and-forget: never let a compaction hook crash the session.
36
+ console.error('[UltraMemory] Session compaction hook failed:', err instanceof Error ? err.message : String(err));
37
+ }
38
+ };
39
+ }
40
+ //# sourceMappingURL=session-compactor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-compactor.js","sourceRoot":"","sources":["../../src/hooks/session-compactor.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,yDAAyD;AACzD,yDAAyD;AAIzD;;;GAGG;AACH,MAAM,wBAAwB,GAAG;IAC/B,oEAAoE;IACpE,kDAAkD;IAClD,kDAAkD;CACnD,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB;IACpC,OAAO,KAAK,EACV,MAA6B,EAC7B,MAA8C,EAC/B,EAAE;QACjB,IAAI,CAAC;YACH,kEAAkE;YAClE,yDAAyD;YACzD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,wBAAwB,CAAC,CAAC;YAEjD,4DAA4D;YAC5D,qCAAqC;QACvC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,kEAAkE;YAClE,OAAO,CAAC,KAAK,CAAC,+CAA+C,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACnH,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { Hooks } from '@opencode-ai/plugin';
2
+ import type { PluginConfig } from '../types.js';
3
+ /**
4
+ * Create the system prompt transform hook.
5
+ *
6
+ * This hook appends relevant memories to the LLM system prompt so the
7
+ * AI has cross-session context about the user, project, and preferences.
8
+ *
9
+ * **Strategy:**
10
+ * - The hook input does **not** include the current user message, so we
11
+ * use a broad search query (`DEFAULT_SEARCH_QUERY`) to fetch high-
12
+ * importance memories across all types.
13
+ * - The `model` parameter is ignored — memories are injected regardless
14
+ * of which LLM is being used.
15
+ * - Respects `config.memory.maxInjections` and `config.memory.minImportance`
16
+ * to control how many memories are injected and their quality floor.
17
+ * - If a Super Memory section already exists in the system prompt array
18
+ * (e.g. from a previous invocation), it is replaced **in-place** rather
19
+ * than duplicated.
20
+ * - All errors are caught and logged — the hook **never throws**, so it
21
+ * cannot crash OpenCode.
22
+ *
23
+ * @param config - Resolved plugin configuration
24
+ * @returns - The system transform hook function
25
+ */
26
+ export declare function createSystemTransform(config: PluginConfig): NonNullable<Hooks['experimental.chat.system.transform']>;
27
+ //# sourceMappingURL=system-transform.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-transform.d.ts","sourceRoot":"","sources":["../../src/hooks/system-transform.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAkBhD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,YAAY,GACnB,WAAW,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAwC1D"}
@@ -0,0 +1,76 @@
1
+ // ─── System Prompt Transform Hook ───────────────────────────────────────
2
+ // Injects relevant memories into the system prompt so the AI can recall
3
+ // past context across sessions.
4
+ //
5
+ // This is the recall mechanism that makes the memory plugin useful — it
6
+ // retrieves the most relevant stored memories and appends them as context
7
+ // to every LLM request.
8
+ import { getContextForQuery } from '../memory/processor.js';
9
+ // ─── Constants ────────────────────────────────────────────────────────────
10
+ const MEMORY_HEADER = '[Super Memory - Relevant Context]';
11
+ const MEMORY_FOOTER = '[End Super Memory]';
12
+ /**
13
+ * Broad search query used to fetch general high-importance memories.
14
+ * Uses broad, inclusive terms to match across all memory types without
15
+ * requiring the current user message (which is not available in this hook).
16
+ */
17
+ const DEFAULT_SEARCH_QUERY = 'project context preferences decisions tech stack patterns workflow conventions';
18
+ // ─── Hook Factory ─────────────────────────────────────────────────────────
19
+ /**
20
+ * Create the system prompt transform hook.
21
+ *
22
+ * This hook appends relevant memories to the LLM system prompt so the
23
+ * AI has cross-session context about the user, project, and preferences.
24
+ *
25
+ * **Strategy:**
26
+ * - The hook input does **not** include the current user message, so we
27
+ * use a broad search query (`DEFAULT_SEARCH_QUERY`) to fetch high-
28
+ * importance memories across all types.
29
+ * - The `model` parameter is ignored — memories are injected regardless
30
+ * of which LLM is being used.
31
+ * - Respects `config.memory.maxInjections` and `config.memory.minImportance`
32
+ * to control how many memories are injected and their quality floor.
33
+ * - If a Super Memory section already exists in the system prompt array
34
+ * (e.g. from a previous invocation), it is replaced **in-place** rather
35
+ * than duplicated.
36
+ * - All errors are caught and logged — the hook **never throws**, so it
37
+ * cannot crash OpenCode.
38
+ *
39
+ * @param config - Resolved plugin configuration
40
+ * @returns - The system transform hook function
41
+ */
42
+ export function createSystemTransform(config) {
43
+ return async (_input, output) => {
44
+ try {
45
+ // Fetch relevant memories using a broad query. This ensures the AI
46
+ // always receives context about the project, user preferences, tech
47
+ // stack, decisions, and workflows regardless of the current message.
48
+ const context = await getContextForQuery(DEFAULT_SEARCH_QUERY, {
49
+ maxInjections: config.memory.maxInjections,
50
+ minImportance: config.memory.minImportance,
51
+ });
52
+ // No relevant memories found — leave the system prompt unchanged.
53
+ if (!context || context.trim().length === 0) {
54
+ return;
55
+ }
56
+ // Build the memory section as a single, clean markdown block.
57
+ const memorySection = `\n${MEMORY_HEADER}\n${context}\n${MEMORY_FOOTER}`;
58
+ // Check if there is already a Super Memory section in the prompt
59
+ // array. If so, replace it in-place to prevent duplication across
60
+ // multiple hook invocations (defensive — should not happen in
61
+ // normal OpenCode operation but guards against edge cases).
62
+ const existingIdx = output.system.findIndex((s) => s.includes(MEMORY_HEADER));
63
+ if (existingIdx >= 0) {
64
+ output.system[existingIdx] = memorySection;
65
+ }
66
+ else {
67
+ output.system.push(memorySection);
68
+ }
69
+ }
70
+ catch (err) {
71
+ // Never throw — a hook error must never crash OpenCode.
72
+ console.error('[UltraMemory] system-transform: failed to inject memories', err);
73
+ }
74
+ };
75
+ }
76
+ //# sourceMappingURL=system-transform.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-transform.js","sourceRoot":"","sources":["../../src/hooks/system-transform.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,wEAAwE;AACxE,gCAAgC;AAChC,EAAE;AACF,wEAAwE;AACxE,0EAA0E;AAC1E,wBAAwB;AAIxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,6EAA6E;AAE7E,MAAM,aAAa,GAAG,mCAAmC,CAAC;AAC1D,MAAM,aAAa,GAAG,oBAAoB,CAAC;AAE3C;;;;GAIG;AACH,MAAM,oBAAoB,GACxB,gFAAgF,CAAC;AAEnF,6EAA6E;AAE7E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,qBAAqB,CACnC,MAAoB;IAEpB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;QAC9B,IAAI,CAAC;YACH,mEAAmE;YACnE,oEAAoE;YACpE,qEAAqE;YACrE,MAAM,OAAO,GAAG,MAAM,kBAAkB,CAAC,oBAAoB,EAAE;gBAC7D,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa;gBAC1C,aAAa,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa;aAC3C,CAAC,CAAC;YAEH,kEAAkE;YAClE,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC5C,OAAO;YACT,CAAC;YAED,8DAA8D;YAC9D,MAAM,aAAa,GAAG,KAAK,aAAa,KAAK,OAAO,KAAK,aAAa,EAAE,CAAC;YAEzE,iEAAiE;YACjE,kEAAkE;YAClE,8DAA8D;YAC9D,4DAA4D;YAC5D,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAChD,CAAC,CAAC,QAAQ,CAAC,aAAa,CAAC,CAC1B,CAAC;YAEF,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;gBACrB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,aAAa,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,wDAAwD;YACxD,OAAO,CAAC,KAAK,CACX,2DAA2D,EAC3D,GAAG,CACJ,CAAC;QACJ,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Hooks } from '@opencode-ai/plugin';
2
+ /**
3
+ * Create a handler for the `tool.execute.after` hook.
4
+ *
5
+ * When a tool executes successfully, the handler extracts meaningful
6
+ * patterns from the tool output and stores them as `pattern`-type
7
+ * memories. This enables the memory system to learn from tool usage
8
+ * over time.
9
+ *
10
+ * The handler is fire-and-forget — it returns immediately without awaiting
11
+ * any memory operations.
12
+ */
13
+ export declare function createToolAfterHandler(): Hooks['tool.execute.after'];
14
+ //# sourceMappingURL=tool-handler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-handler.d.ts","sourceRoot":"","sources":["../../src/hooks/tool-handler.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAGjD;;;;;;;;;;GAUG;AACH,wBAAgB,sBAAsB,IAAI,KAAK,CAAC,oBAAoB,CAAC,CA2CpE"}