@mono-agent/agent-app 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/README.md +24 -10
  2. package/dist/adapter-send-tools-main.d.ts +3 -0
  3. package/dist/adapter-send-tools-main.d.ts.map +1 -0
  4. package/dist/adapter-send-tools-main.js +20 -0
  5. package/dist/adapter-send-tools-main.js.map +1 -0
  6. package/dist/adapter-send-tools.d.ts +125 -0
  7. package/dist/adapter-send-tools.d.ts.map +1 -0
  8. package/dist/adapter-send-tools.js +629 -0
  9. package/dist/adapter-send-tools.js.map +1 -0
  10. package/dist/app-config.d.ts +86 -26
  11. package/dist/app-config.d.ts.map +1 -1
  12. package/dist/app-config.js +284 -90
  13. package/dist/app-config.js.map +1 -1
  14. package/dist/app.d.ts +51 -20
  15. package/dist/app.d.ts.map +1 -1
  16. package/dist/app.js +889 -119
  17. package/dist/app.js.map +1 -1
  18. package/dist/artifact-retention.d.ts +32 -0
  19. package/dist/artifact-retention.d.ts.map +1 -0
  20. package/dist/artifact-retention.js +111 -0
  21. package/dist/artifact-retention.js.map +1 -0
  22. package/dist/audit-runs.d.ts +12 -0
  23. package/dist/audit-runs.d.ts.map +1 -0
  24. package/dist/audit-runs.js +68 -0
  25. package/dist/audit-runs.js.map +1 -0
  26. package/dist/backfill.d.ts +75 -0
  27. package/dist/backfill.d.ts.map +1 -0
  28. package/dist/backfill.js +350 -0
  29. package/dist/backfill.js.map +1 -0
  30. package/dist/background.d.ts +8 -5
  31. package/dist/background.d.ts.map +1 -1
  32. package/dist/background.js +279 -53
  33. package/dist/background.js.map +1 -1
  34. package/dist/broadcast-recorder.d.ts +27 -0
  35. package/dist/broadcast-recorder.d.ts.map +1 -0
  36. package/dist/broadcast-recorder.js +82 -0
  37. package/dist/broadcast-recorder.js.map +1 -0
  38. package/dist/channel-config-view.d.ts +28 -0
  39. package/dist/channel-config-view.d.ts.map +1 -0
  40. package/dist/channel-config-view.js +79 -0
  41. package/dist/channel-config-view.js.map +1 -0
  42. package/dist/channel-gate.d.ts +22 -0
  43. package/dist/channel-gate.d.ts.map +1 -0
  44. package/dist/channel-gate.js +35 -0
  45. package/dist/channel-gate.js.map +1 -0
  46. package/dist/channel-plugins.d.ts +39 -0
  47. package/dist/channel-plugins.d.ts.map +1 -0
  48. package/dist/channel-plugins.js +346 -0
  49. package/dist/channel-plugins.js.map +1 -0
  50. package/dist/channels.d.ts +62 -66
  51. package/dist/channels.d.ts.map +1 -1
  52. package/dist/channels.js +850 -120
  53. package/dist/channels.js.map +1 -1
  54. package/dist/cli.d.ts +103 -4
  55. package/dist/cli.d.ts.map +1 -1
  56. package/dist/cli.js +984 -112
  57. package/dist/cli.js.map +1 -1
  58. package/dist/config-reference.d.ts +24 -0
  59. package/dist/config-reference.d.ts.map +1 -0
  60. package/dist/config-reference.js +580 -0
  61. package/dist/config-reference.js.map +1 -0
  62. package/dist/configured-agent.d.ts +104 -0
  63. package/dist/configured-agent.d.ts.map +1 -0
  64. package/dist/configured-agent.js +578 -0
  65. package/dist/configured-agent.js.map +1 -0
  66. package/dist/consumer-contract.d.ts +36 -0
  67. package/dist/consumer-contract.d.ts.map +1 -0
  68. package/dist/consumer-contract.js +290 -0
  69. package/dist/consumer-contract.js.map +1 -0
  70. package/dist/doctor.d.ts +17 -0
  71. package/dist/doctor.d.ts.map +1 -1
  72. package/dist/doctor.js +392 -95
  73. package/dist/doctor.js.map +1 -1
  74. package/dist/index.d.ts +14 -6
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +7 -3
  77. package/dist/index.js.map +1 -1
  78. package/dist/init.d.ts +23 -7
  79. package/dist/init.d.ts.map +1 -1
  80. package/dist/init.js +91 -26
  81. package/dist/init.js.map +1 -1
  82. package/dist/install-skill.d.ts +1 -1
  83. package/dist/install-skill.js +2 -2
  84. package/dist/install-skill.js.map +1 -1
  85. package/dist/interaction-bridge.d.ts +72 -0
  86. package/dist/interaction-bridge.d.ts.map +1 -0
  87. package/dist/interaction-bridge.js +354 -0
  88. package/dist/interaction-bridge.js.map +1 -0
  89. package/dist/launchd.d.ts +0 -2
  90. package/dist/launchd.d.ts.map +1 -1
  91. package/dist/launchd.js +0 -2
  92. package/dist/launchd.js.map +1 -1
  93. package/dist/memory-command.d.ts +10 -0
  94. package/dist/memory-command.d.ts.map +1 -0
  95. package/dist/memory-command.js +649 -0
  96. package/dist/memory-command.js.map +1 -0
  97. package/dist/memory-recall-main.d.ts +3 -0
  98. package/dist/memory-recall-main.d.ts.map +1 -0
  99. package/dist/memory-recall-main.js +30 -0
  100. package/dist/memory-recall-main.js.map +1 -0
  101. package/dist/memory-recall.d.ts +147 -0
  102. package/dist/memory-recall.d.ts.map +1 -0
  103. package/dist/memory-recall.js +345 -0
  104. package/dist/memory-recall.js.map +1 -0
  105. package/dist/memory-rituals.d.ts +8 -11
  106. package/dist/memory-rituals.d.ts.map +1 -1
  107. package/dist/memory-rituals.js +26 -25
  108. package/dist/memory-rituals.js.map +1 -1
  109. package/dist/metrics.d.ts +13 -0
  110. package/dist/metrics.d.ts.map +1 -0
  111. package/dist/metrics.js +105 -0
  112. package/dist/metrics.js.map +1 -0
  113. package/dist/notify-destinations.d.ts +23 -0
  114. package/dist/notify-destinations.d.ts.map +1 -0
  115. package/dist/notify-destinations.js +79 -0
  116. package/dist/notify-destinations.js.map +1 -0
  117. package/dist/posted-message-index.d.ts +61 -0
  118. package/dist/posted-message-index.d.ts.map +1 -0
  119. package/dist/posted-message-index.js +178 -0
  120. package/dist/posted-message-index.js.map +1 -0
  121. package/dist/proactive-notify.d.ts +32 -0
  122. package/dist/proactive-notify.d.ts.map +1 -0
  123. package/dist/proactive-notify.js +62 -0
  124. package/dist/proactive-notify.js.map +1 -0
  125. package/dist/recipes/base.d.ts +15 -0
  126. package/dist/recipes/base.d.ts.map +1 -0
  127. package/dist/recipes/base.js +51 -0
  128. package/dist/recipes/base.js.map +1 -0
  129. package/dist/recipes/catalog.d.ts +4 -0
  130. package/dist/recipes/catalog.d.ts.map +1 -0
  131. package/dist/recipes/catalog.js +509 -0
  132. package/dist/recipes/catalog.js.map +1 -0
  133. package/dist/recipes/index.d.ts +11 -0
  134. package/dist/recipes/index.d.ts.map +1 -0
  135. package/dist/recipes/index.js +14 -0
  136. package/dist/recipes/index.js.map +1 -0
  137. package/dist/recipes/types.d.ts +70 -0
  138. package/dist/recipes/types.d.ts.map +1 -0
  139. package/dist/recipes/types.js +15 -0
  140. package/dist/recipes/types.js.map +1 -0
  141. package/dist/request-model-override.d.ts +67 -0
  142. package/dist/request-model-override.d.ts.map +1 -0
  143. package/dist/request-model-override.js +96 -0
  144. package/dist/request-model-override.js.map +1 -0
  145. package/dist/runs-health.d.ts +22 -0
  146. package/dist/runs-health.d.ts.map +1 -0
  147. package/dist/runs-health.js +144 -0
  148. package/dist/runs-health.js.map +1 -0
  149. package/dist/seen-conversations.d.ts +22 -0
  150. package/dist/seen-conversations.d.ts.map +1 -0
  151. package/dist/seen-conversations.js +120 -0
  152. package/dist/seen-conversations.js.map +1 -0
  153. package/dist/sessions.d.ts +21 -0
  154. package/dist/sessions.d.ts.map +1 -0
  155. package/dist/sessions.js +45 -0
  156. package/dist/sessions.js.map +1 -0
  157. package/dist/setup.d.ts +29 -0
  158. package/dist/setup.d.ts.map +1 -0
  159. package/dist/setup.js +97 -0
  160. package/dist/setup.js.map +1 -0
  161. package/dist/trigger-overrides.d.ts +17 -0
  162. package/dist/trigger-overrides.d.ts.map +1 -0
  163. package/dist/trigger-overrides.js +30 -0
  164. package/dist/trigger-overrides.js.map +1 -0
  165. package/dist/tui-command.d.ts +56 -0
  166. package/dist/tui-command.d.ts.map +1 -0
  167. package/dist/tui-command.js +160 -0
  168. package/dist/tui-command.js.map +1 -0
  169. package/dist/ui.d.ts +54 -0
  170. package/dist/ui.d.ts.map +1 -0
  171. package/dist/ui.js +157 -0
  172. package/dist/ui.js.map +1 -0
  173. package/dist/web-command.d.ts +39 -0
  174. package/dist/web-command.d.ts.map +1 -0
  175. package/dist/web-command.js +151 -0
  176. package/dist/web-command.js.map +1 -0
  177. package/package.json +22 -17
  178. package/schema/mono-agent.config.schema.json +1686 -0
  179. package/skills/mono-agent-composer/SKILL.md +38 -12
  180. package/skills/mono-agent-composer/agents/openai.yaml +4 -0
  181. package/skills/mono-agent-composer/references/config-blueprint.md +84 -31
  182. package/skills/mono-agent-composer/references/discovery-questions.md +49 -36
  183. package/skills/mono-agent-composer/references/feature-coverage.md +26 -19
  184. package/skills/mono-agent-composer/references/package-map.md +20 -22
  185. package/skills/mono-agent-composer/references/playbooks.md +209 -0
  186. package/skills/mono-agent-composer/references/validation.md +14 -5
@@ -0,0 +1,649 @@
1
+ import { readdir, readFile, stat } from "node:fs/promises";
2
+ import { basename, isAbsolute, join, relative, resolve } from "node:path";
3
+ import { resolveSupermemoryContainer } from "@mono-agent/config";
4
+ import { openMemoryDb } from "@mono-agent/memory/store";
5
+ import { parseDailyFile } from "@mono-agent/memory/bujo";
6
+ import { isAppCoreConfigError, loadAppCoreConfig } from "./app-config.js";
7
+ import { createRecallStore, resolveMemoryRecallSettings, } from "./memory-recall.js";
8
+ import * as ui from "./ui.js";
9
+ const DEFAULT_SEARCH_LIMIT = 8;
10
+ const DEFAULT_TOP_LIMIT = 10;
11
+ const DEFAULT_ENTITY_LIMIT = 8;
12
+ const DATE_RE = /^\d{4}-\d{2}-\d{2}$/u;
13
+ export async function runMemoryCommand(input) {
14
+ const context = await loadMemoryCommandContext(input);
15
+ if ("code" in context) {
16
+ return context.code;
17
+ }
18
+ const [rawSubcommand, ...rest] = input.positionals;
19
+ const subcommand = rawSubcommand ?? "stats";
20
+ if (context.config.memory === undefined) {
21
+ writeNoMemory(context.configPath, input.json);
22
+ return 0;
23
+ }
24
+ switch (subcommand) {
25
+ case "stats":
26
+ return await runStats(context, input);
27
+ case "today":
28
+ return await runShow(context, todayKey(), input.json);
29
+ case "show": {
30
+ const date = rest[0];
31
+ if (date === undefined || !DATE_RE.test(date)) {
32
+ process.stderr.write(ui.errorLine("Usage: mono-agent memory show <YYYY-MM-DD>."));
33
+ return 2;
34
+ }
35
+ return await runShow(context, date, input.json);
36
+ }
37
+ case "search": {
38
+ const query = rest.join(" ").trim();
39
+ if (query.length === 0) {
40
+ process.stderr.write(ui.errorLine("Usage: mono-agent memory search <query>."));
41
+ return 2;
42
+ }
43
+ return await runSearch(context, query, input);
44
+ }
45
+ case "top":
46
+ return await runTop(context, input);
47
+ default:
48
+ process.stderr.write(ui.errorLine(`Unknown memory subcommand \`${subcommand}\`.`));
49
+ process.stderr.write(ui.hint("Expected stats, today, show <date>, search <query>, or top."));
50
+ return 2;
51
+ }
52
+ }
53
+ async function loadMemoryCommandContext(input) {
54
+ const cwd = input.cwd;
55
+ const configPath = resolve(cwd, input.configPath ?? "mono-agent.config.json");
56
+ try {
57
+ return {
58
+ cwd,
59
+ configPath,
60
+ config: await loadAppCoreConfig({ env: input.env, cwd, configPath }),
61
+ };
62
+ }
63
+ catch (error) {
64
+ if (isAppCoreConfigError(error)) {
65
+ process.stderr.write(ui.errorLine(error.message));
66
+ process.stderr.write(ui.hint(`Fix ${configPath}, then re-run \`mono-agent memory\`.`));
67
+ return { code: 1 };
68
+ }
69
+ throw error;
70
+ }
71
+ }
72
+ async function runStats(context, input) {
73
+ const memory = context.config.memory;
74
+ if (memory === undefined) {
75
+ writeNoMemory(context.configPath, input.json);
76
+ return 0;
77
+ }
78
+ if ((memory.backend ?? "bujo") === "supermemory") {
79
+ const supermemory = supermemoryStats(context.config);
80
+ write(input.json, supermemory, () => renderSupermemoryStats(supermemory));
81
+ return 0;
82
+ }
83
+ const root = memory.path;
84
+ const dbPath = join(root, "memory.db");
85
+ const rootExists = await exists(root);
86
+ const dbExists = await exists(dbPath);
87
+ const size = rootExists ? await collectStoreSize(root) : emptySize();
88
+ const lastConsolidation = await mtimeIso(join(root, "index.md"));
89
+ const lastDailyWrite = rootExists ? await latestDailyMtime(root) : undefined;
90
+ let stats;
91
+ let entityCount = 0;
92
+ let topMemories = [];
93
+ if (dbExists) {
94
+ const db = openMemoryDb({ path: dbPath });
95
+ try {
96
+ stats = readLocalStats(db, input.limit ?? DEFAULT_ENTITY_LIMIT);
97
+ entityCount = db.countEntities();
98
+ topMemories = db.topSalient(input.limit ?? DEFAULT_TOP_LIMIT);
99
+ }
100
+ finally {
101
+ db.close();
102
+ }
103
+ }
104
+ const lastCapture = stats?.latestCreatedMemory?.createdAt ?? lastDailyWrite;
105
+ const lastAccess = stats?.latestAccessedMemory?.lastAccessedAt;
106
+ const result = {
107
+ configured: true,
108
+ backend: "bujo",
109
+ mode: memory.mode,
110
+ effectiveTier: effectiveLocalTier(memory),
111
+ writeMode: memory.writeMode,
112
+ recallToolEnabled: memory.recallTool?.enabled === true,
113
+ root,
114
+ ...(dbExists ? { database: dbPath } : {}),
115
+ counts: stats === undefined
116
+ ? { total: 0, live: 0, byStatus: {}, byType: {}, entities: 0 }
117
+ : {
118
+ total: stats.totalMemories,
119
+ live: stats.liveMemories,
120
+ byStatus: stats.countsByStatus,
121
+ byType: stats.countsByType,
122
+ entities: entityCount,
123
+ },
124
+ size,
125
+ ...(lastCapture === undefined ? {} : { lastCapture }),
126
+ ...(lastAccess === undefined ? {} : { lastAccess }),
127
+ ...(lastConsolidation === undefined ? {} : { lastConsolidation }),
128
+ topEntities: stats?.topEntities ?? [],
129
+ topMemories,
130
+ notes: [
131
+ ...(rootExists ? [] : [`Memory root does not exist yet: ${root}`]),
132
+ ...(dbExists ? [] : [`No SQLite index found at ${dbPath}; search/top need an indexed store.`]),
133
+ ],
134
+ };
135
+ write(input.json, result, () => renderLocalStats(result));
136
+ return 0;
137
+ }
138
+ async function runShow(context, date, json) {
139
+ const memory = context.config.memory;
140
+ if (memory === undefined) {
141
+ writeNoMemory(context.configPath, json);
142
+ return 0;
143
+ }
144
+ if ((memory.backend ?? "bujo") === "supermemory") {
145
+ const result = {
146
+ configured: true,
147
+ backend: "supermemory",
148
+ available: false,
149
+ message: "Supermemory stores memories remotely; local daily logs are not available.",
150
+ };
151
+ write(json, result, () => `${ui.banner("mono-agent memory", "daily log")}\n${result.message}\n`);
152
+ return 0;
153
+ }
154
+ const found = await findDailyFile(memory.path, date);
155
+ if (found === undefined) {
156
+ const result = {
157
+ configured: true,
158
+ backend: "bujo",
159
+ date,
160
+ found: false,
161
+ checked: [join(memory.path, "daily", `${date}.md`), join(memory.path, `${date}.md`)],
162
+ };
163
+ write(json, result, () => `${ui.banner("mono-agent memory", date)}\nNo daily log found for ${date}.\n`);
164
+ return 0;
165
+ }
166
+ const content = await readFile(found, "utf8");
167
+ const parsed = parseDailyFile(content);
168
+ const result = {
169
+ configured: true,
170
+ backend: "bujo",
171
+ date,
172
+ found: true,
173
+ path: found,
174
+ bullets: parsed.bullets.map((bullet) => ({
175
+ id: bullet.id,
176
+ type: bullet.type,
177
+ status: bullet.status,
178
+ text: bullet.text,
179
+ salience: bullet.salience,
180
+ createdAt: bullet.createdAt,
181
+ })),
182
+ content,
183
+ };
184
+ write(json, result, () => renderDaily(result));
185
+ return 0;
186
+ }
187
+ async function runSearch(context, query, input) {
188
+ const settings = previewRecallSettings(context.config);
189
+ if (settings === undefined) {
190
+ writeNoMemory(context.configPath, input.json);
191
+ return 0;
192
+ }
193
+ if (!("supermemory" in settings) && !(await exists(join(settings.root, "memory.db")))) {
194
+ const result = {
195
+ configured: true,
196
+ backend: "bujo",
197
+ query,
198
+ hits: [],
199
+ notes: [`No SQLite index found at ${join(settings.root, "memory.db")}; run memory-bujo rebuild or wait for capture.`],
200
+ };
201
+ write(input.json, result, () => renderSearch(result));
202
+ return 0;
203
+ }
204
+ const limit = input.limit ?? DEFAULT_SEARCH_LIMIT;
205
+ let degraded;
206
+ const hits = await recallWithFtsFallback(settings, query, limit)
207
+ .then((result) => {
208
+ degraded = result.degraded;
209
+ return result.hits;
210
+ })
211
+ .catch((error) => {
212
+ process.stderr.write(ui.errorLine(`memory search failed: ${reasonOf(error)}`));
213
+ return undefined;
214
+ });
215
+ if (hits === undefined) {
216
+ return 1;
217
+ }
218
+ const result = {
219
+ configured: true,
220
+ backend: "supermemory" in settings ? "supermemory" : "bujo",
221
+ query,
222
+ ...(degraded === undefined ? {} : { degraded }),
223
+ hits: hits.map((hit) => ({
224
+ id: hit.record.id,
225
+ score: hit.score,
226
+ text: hit.record.text,
227
+ source: sourceOf(hit),
228
+ ...(hit.record.salience === undefined ? {} : { salience: hit.record.salience }),
229
+ ...(hit.record.createdAt === undefined ? {} : { createdAt: hit.record.createdAt }),
230
+ })),
231
+ };
232
+ write(input.json, result, () => renderSearch(result));
233
+ return 0;
234
+ }
235
+ async function runTop(context, input) {
236
+ const memory = context.config.memory;
237
+ if (memory === undefined) {
238
+ writeNoMemory(context.configPath, input.json);
239
+ return 0;
240
+ }
241
+ if ((memory.backend ?? "bujo") === "supermemory") {
242
+ const result = {
243
+ configured: true,
244
+ backend: "supermemory",
245
+ available: false,
246
+ message: "Supermemory does not expose a local salience ranking; use memory search instead.",
247
+ };
248
+ write(input.json, result, () => `${ui.banner("mono-agent memory", "top")}\n${result.message}\n`);
249
+ return 0;
250
+ }
251
+ const dbPath = join(memory.path, "memory.db");
252
+ if (!(await exists(dbPath))) {
253
+ const result = {
254
+ configured: true,
255
+ backend: "bujo",
256
+ hits: [],
257
+ notes: [`No SQLite index found at ${dbPath}; run memory-bujo rebuild or wait for capture.`],
258
+ };
259
+ write(input.json, result, () => renderTop(result));
260
+ return 0;
261
+ }
262
+ const db = openMemoryDb({ path: dbPath });
263
+ try {
264
+ const hits = db.topSalient(input.limit ?? DEFAULT_TOP_LIMIT).map((record) => ({
265
+ id: record.id,
266
+ text: record.text,
267
+ salience: record.salience,
268
+ status: record.status,
269
+ type: record.type,
270
+ source: sourceOfRecord(record),
271
+ createdAt: record.createdAt,
272
+ }));
273
+ const result = { configured: true, backend: "bujo", hits, notes: [] };
274
+ write(input.json, result, () => renderTop(result));
275
+ }
276
+ finally {
277
+ db.close();
278
+ }
279
+ return 0;
280
+ }
281
+ function previewRecallSettings(config) {
282
+ const fromTool = resolveMemoryRecallSettings(config);
283
+ if (fromTool !== undefined) {
284
+ return fromTool;
285
+ }
286
+ const memory = config.memory;
287
+ if (memory === undefined) {
288
+ return undefined;
289
+ }
290
+ if ((memory.backend ?? "bujo") === "supermemory") {
291
+ const sm = memory.supermemory;
292
+ if (sm === undefined) {
293
+ return undefined;
294
+ }
295
+ return {
296
+ supermemory: {
297
+ baseUrl: sm.baseUrl,
298
+ container: resolveSupermemoryContainer(config),
299
+ ...(sm.apiKey === undefined ? {} : { apiKey: sm.apiKey }),
300
+ ...(sm.timeoutMs === undefined ? {} : { timeoutMs: sm.timeoutMs }),
301
+ },
302
+ };
303
+ }
304
+ const embeddings = memory.embeddings;
305
+ if (embeddings === undefined) {
306
+ return { root: memory.path };
307
+ }
308
+ return {
309
+ root: memory.path,
310
+ embeddings: {
311
+ provider: embeddings.provider,
312
+ model: embeddings.model,
313
+ ...(embeddings.endpoint === undefined ? {} : { endpoint: embeddings.endpoint }),
314
+ ...(embeddings.apiKey === undefined ? {} : { apiKey: embeddings.apiKey }),
315
+ ...(embeddings.apiKeyEnv === undefined ? {} : { apiKeyEnv: embeddings.apiKeyEnv }),
316
+ ...(embeddings.dim === undefined ? {} : { dim: embeddings.dim }),
317
+ ...(embeddings.timeoutMs === undefined ? {} : { timeoutMs: embeddings.timeoutMs }),
318
+ ...(embeddings.circuitBreaker === undefined ? {} : { circuitBreaker: embeddings.circuitBreaker }),
319
+ },
320
+ };
321
+ }
322
+ async function recallWithFtsFallback(settings, query, limit) {
323
+ const store = await createRecallStore(settings);
324
+ try {
325
+ return { hits: await store.recall(query, { topK: limit, trackAccess: false }) };
326
+ }
327
+ catch (error) {
328
+ if (!isFtsFallbackEligible(settings, error)) {
329
+ throw error;
330
+ }
331
+ await store.close().catch(() => undefined);
332
+ const fallback = { root: settings.root };
333
+ const ftsStore = await createRecallStore(fallback);
334
+ try {
335
+ return {
336
+ hits: await ftsStore.recall(query, { topK: limit, trackAccess: false }),
337
+ degraded: `Semantic embeddings unavailable (${reasonOf(error)}); showing FTS-only results.`,
338
+ };
339
+ }
340
+ finally {
341
+ await ftsStore.close();
342
+ }
343
+ }
344
+ finally {
345
+ await store.close().catch(() => undefined);
346
+ }
347
+ }
348
+ function isFtsFallbackEligible(settings, error) {
349
+ if ("supermemory" in settings || settings.embeddings === undefined) {
350
+ return false;
351
+ }
352
+ const record = typeof error === "object" && error !== null ? error : {};
353
+ const code = typeof record.code === "string" ? record.code : "";
354
+ if (code.startsWith("embedding_") || code === "invalid_embedding_options") {
355
+ return true;
356
+ }
357
+ const name = error instanceof Error ? error.name : "";
358
+ const message = reasonOf(error).toLocaleLowerCase("en-US");
359
+ return name === "AbortError" ||
360
+ name === "TypeError" ||
361
+ message.includes("fetch failed") ||
362
+ message.includes("embedding") ||
363
+ message.includes("econnrefused") ||
364
+ message.includes("enotfound");
365
+ }
366
+ function readLocalStats(db, topEntitiesLimit) {
367
+ return db.stats({ topEntitiesLimit });
368
+ }
369
+ function effectiveLocalTier(memory) {
370
+ if (memory.mode === "lite") {
371
+ return "lite";
372
+ }
373
+ if (memory.mode === "journal") {
374
+ return "journal";
375
+ }
376
+ return memory.llm === undefined ? "journal" : "bujo";
377
+ }
378
+ function supermemoryStats(config) {
379
+ return {
380
+ configured: true,
381
+ backend: "supermemory",
382
+ baseUrl: config.memory?.supermemory?.baseUrl,
383
+ container: config.memory === undefined ? undefined : resolveSupermemoryContainer(config),
384
+ known: ["backend", "baseUrl", "container"],
385
+ unavailable: [
386
+ "local counts",
387
+ "local size",
388
+ "last capture",
389
+ "last consolidation",
390
+ "top entities",
391
+ "highest-salience memories",
392
+ "daily markdown logs",
393
+ ],
394
+ };
395
+ }
396
+ async function findDailyFile(root, date) {
397
+ const candidates = [join(root, "daily", `${date}.md`), join(root, `${date}.md`)];
398
+ for (const candidate of candidates) {
399
+ if (await exists(candidate)) {
400
+ return candidate;
401
+ }
402
+ }
403
+ return undefined;
404
+ }
405
+ async function latestDailyMtime(root) {
406
+ const files = await dailyMarkdownFiles(root);
407
+ const mtimes = await Promise.all(files.map((file) => mtimeIso(file)));
408
+ return newest(mtimes.flatMap((mtime) => mtime === undefined ? [] : [mtime]));
409
+ }
410
+ async function dailyMarkdownFiles(root) {
411
+ const files = [];
412
+ for (const dir of [root, join(root, "daily")]) {
413
+ let entries;
414
+ try {
415
+ entries = await readdir(dir, { withFileTypes: true });
416
+ }
417
+ catch {
418
+ continue;
419
+ }
420
+ for (const entry of entries) {
421
+ if (entry.isFile() && DATE_RE.test(basename(entry.name, ".md")) && entry.name.endsWith(".md")) {
422
+ files.push(join(dir, entry.name));
423
+ }
424
+ }
425
+ }
426
+ return files;
427
+ }
428
+ async function collectStoreSize(root) {
429
+ let rootBytes = 0;
430
+ let dailyBytes = 0;
431
+ let databaseBytes = 0;
432
+ let fileCount = 0;
433
+ async function walk(dir) {
434
+ let entries;
435
+ try {
436
+ entries = await readdir(dir, { withFileTypes: true });
437
+ }
438
+ catch {
439
+ return;
440
+ }
441
+ for (const entry of entries) {
442
+ const filePath = join(dir, entry.name);
443
+ if (entry.isDirectory()) {
444
+ await walk(filePath);
445
+ continue;
446
+ }
447
+ if (!entry.isFile()) {
448
+ continue;
449
+ }
450
+ const s = await stat(filePath).catch(() => undefined);
451
+ if (s === undefined) {
452
+ continue;
453
+ }
454
+ fileCount += 1;
455
+ rootBytes += s.size;
456
+ if ((entry.name.endsWith(".md") && DATE_RE.test(basename(entry.name, ".md"))) || isUnderDirectory(join(root, "daily"), filePath)) {
457
+ dailyBytes += s.size;
458
+ }
459
+ if (entry.name === "memory.db" || entry.name.startsWith("memory.db-")) {
460
+ databaseBytes += s.size;
461
+ }
462
+ }
463
+ }
464
+ await walk(root);
465
+ return { rootBytes, dailyBytes, databaseBytes, fileCount };
466
+ }
467
+ function isUnderDirectory(parent, child) {
468
+ const rel = relative(parent, child);
469
+ return rel.length > 0 && !rel.startsWith("..") && !isAbsolute(rel);
470
+ }
471
+ function emptySize() {
472
+ return { rootBytes: 0, dailyBytes: 0, databaseBytes: 0, fileCount: 0 };
473
+ }
474
+ async function mtimeIso(path) {
475
+ const s = await stat(path).catch(() => undefined);
476
+ return s === undefined ? undefined : s.mtime.toISOString();
477
+ }
478
+ async function exists(path) {
479
+ try {
480
+ await stat(path);
481
+ return true;
482
+ }
483
+ catch {
484
+ return false;
485
+ }
486
+ }
487
+ function newest(values) {
488
+ let best;
489
+ let bestMs = Number.NEGATIVE_INFINITY;
490
+ for (const value of values) {
491
+ const ms = Date.parse(value);
492
+ if (Number.isFinite(ms) && ms > bestMs) {
493
+ best = value;
494
+ bestMs = ms;
495
+ }
496
+ }
497
+ return best;
498
+ }
499
+ function todayKey() {
500
+ return new Date().toISOString().slice(0, 10);
501
+ }
502
+ function sourceOf(hit) {
503
+ const source = hit.record.source;
504
+ if (source?.file !== undefined) {
505
+ return source.line === undefined ? source.file : `${source.file}:${source.line}`;
506
+ }
507
+ if (source?.session !== undefined) {
508
+ return `session:${source.session}`;
509
+ }
510
+ return hit.record.id;
511
+ }
512
+ function sourceOfRecord(record) {
513
+ if (record.source.file !== undefined) {
514
+ return record.source.line === undefined ? record.source.file : `${record.source.file}:${record.source.line}`;
515
+ }
516
+ if (record.source.session !== undefined) {
517
+ return `session:${record.source.session}`;
518
+ }
519
+ return record.id;
520
+ }
521
+ function writeNoMemory(configPath, json) {
522
+ const result = {
523
+ configured: false,
524
+ message: `No memory configured in ${configPath}.`,
525
+ };
526
+ write(json, result, () => `${ui.banner("mono-agent memory", "not configured")}\n${result.message}\n`);
527
+ }
528
+ function write(json, value, human) {
529
+ process.stdout.write(json ? `${JSON.stringify(value, null, 2)}\n` : human());
530
+ }
531
+ function renderSupermemoryStats(stats) {
532
+ return [
533
+ ui.banner("mono-agent memory", "stats"),
534
+ ui.keyValue([
535
+ ["backend", "supermemory"],
536
+ ["base URL", stats.baseUrl ?? "unknown"],
537
+ ["container", stats.container ?? "unknown"],
538
+ ], 2),
539
+ "Remote-only fields not known locally:\n",
540
+ ...stats.unavailable.map((item) => ` - ${item}\n`),
541
+ ].join("");
542
+ }
543
+ function renderLocalStats(stats) {
544
+ let out = ui.banner("mono-agent memory", "stats") + "\n";
545
+ out += ui.keyValue([
546
+ ["backend", "bujo"],
547
+ ["configured tier", stats.mode],
548
+ ["effective tier", stats.effectiveTier],
549
+ ["write mode", stats.writeMode],
550
+ ["recall tool", stats.recallToolEnabled ? "enabled" : "disabled"],
551
+ ["root", stats.root],
552
+ ["database", stats.database ?? "missing"],
553
+ ["memories", `${stats.counts.total} total, ${stats.counts.live} live`],
554
+ ["entities", String(stats.counts.entities)],
555
+ ["size", `${formatBytes(stats.size.rootBytes)} (${stats.size.fileCount} files)`],
556
+ ["daily logs", formatBytes(stats.size.dailyBytes)],
557
+ ["database files", formatBytes(stats.size.databaseBytes)],
558
+ ["last capture", stats.lastCapture ?? "unknown"],
559
+ ["last access", stats.lastAccess ?? "unknown"],
560
+ ["last consolidation", stats.lastConsolidation ?? "unknown"],
561
+ ], 2);
562
+ out += renderCounts("Status counts", stats.counts.byStatus);
563
+ out += renderCounts("Type counts", stats.counts.byType);
564
+ if (stats.topEntities.length > 0) {
565
+ out += "\n" + ui.heading("Top Entities");
566
+ for (const entity of stats.topEntities) {
567
+ out += ` - ${entity.name}${entity.type === undefined ? "" : ` (${entity.type})`}`;
568
+ if (entity.summary !== undefined) {
569
+ out += `: ${entity.summary}`;
570
+ }
571
+ out += "\n";
572
+ }
573
+ }
574
+ for (const note of stats.notes) {
575
+ out += ui.style.yellow(`[WARN] ${note}`) + "\n";
576
+ }
577
+ return out;
578
+ }
579
+ function renderDaily(result) {
580
+ return [
581
+ ui.banner("mono-agent memory", result.date),
582
+ ui.keyValue([["source", result.path]], 2),
583
+ "\n",
584
+ result.content.endsWith("\n") ? result.content : `${result.content}\n`,
585
+ ].join("");
586
+ }
587
+ function renderSearch(result) {
588
+ let out = ui.banner("mono-agent memory", `search: ${result.query}`) + "\n";
589
+ if (result.degraded !== undefined) {
590
+ out += ui.style.yellow(`[WARN] ${result.degraded}`) + "\n";
591
+ }
592
+ for (const note of result.notes ?? []) {
593
+ out += ui.style.yellow(`[WARN] ${note}`) + "\n";
594
+ }
595
+ if (result.hits.length === 0) {
596
+ return out + "No memories matched.\n";
597
+ }
598
+ for (const hit of result.hits) {
599
+ out += `${hit.score.toFixed(3)} ${hit.text}\n`;
600
+ if (hit.source !== undefined) {
601
+ out += ` source: ${hit.source}\n`;
602
+ }
603
+ }
604
+ return out;
605
+ }
606
+ function renderTop(result) {
607
+ let out = ui.banner("mono-agent memory", "top") + "\n";
608
+ for (const note of result.notes ?? []) {
609
+ out += ui.style.yellow(`[WARN] ${note}`) + "\n";
610
+ }
611
+ if (result.hits.length === 0) {
612
+ return out + "No memories indexed.\n";
613
+ }
614
+ for (const hit of result.hits) {
615
+ const meta = [
616
+ `salience ${hit.salience.toFixed(3)}`,
617
+ ...(hit.type === undefined ? [] : [hit.type]),
618
+ ...(hit.status === undefined ? [] : [hit.status]),
619
+ ...(hit.source === undefined ? [] : [`source ${hit.source}`]),
620
+ ].join("; ");
621
+ out += `${hit.text}\n`;
622
+ out += ` ${meta}\n`;
623
+ }
624
+ return out;
625
+ }
626
+ function renderCounts(label, counts) {
627
+ const entries = Object.entries(counts).sort(([a], [b]) => a.localeCompare(b));
628
+ if (entries.length === 0) {
629
+ return "";
630
+ }
631
+ return "\n" + ui.heading(label) + entries.map(([key, value]) => ` ${key}: ${value}\n`).join("");
632
+ }
633
+ function formatBytes(bytes) {
634
+ if (bytes < 1024) {
635
+ return `${bytes} B`;
636
+ }
637
+ const units = ["KB", "MB", "GB", "TB"];
638
+ let value = bytes / 1024;
639
+ let unit = units[0] ?? "KB";
640
+ for (let i = 1; i < units.length && value >= 1024; i += 1) {
641
+ value /= 1024;
642
+ unit = units[i] ?? unit;
643
+ }
644
+ return `${value >= 10 ? value.toFixed(1) : value.toFixed(2)} ${unit}`;
645
+ }
646
+ function reasonOf(error) {
647
+ return error instanceof Error ? error.message : String(error);
648
+ }
649
+ //# sourceMappingURL=memory-command.js.map