@ouro.bot/cli 0.1.0-alpha.341 → 0.1.0-alpha.343

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 (56) hide show
  1. package/README.md +5 -5
  2. package/SerpentGuide.ouro/psyche/identities/the-serpent.md +1 -1
  3. package/changelog.json +13 -0
  4. package/dist/heart/attachments/sources/bluebubbles.js +1 -1
  5. package/dist/heart/attachments/store.js +2 -2
  6. package/dist/heart/bundle-state.js +1 -1
  7. package/dist/heart/config-registry.js +2 -2
  8. package/dist/heart/core.js +10 -2
  9. package/dist/heart/daemon/agent-service.js +18 -18
  10. package/dist/heart/daemon/daemon-tombstone.js +1 -1
  11. package/dist/heart/daemon/daemon.js +2 -2
  12. package/dist/heart/daemon/hooks/bundle-meta.js +4 -4
  13. package/dist/heart/hatch/hatch-flow.js +1 -1
  14. package/dist/heart/hatch/specialist-prompt.js +1 -1
  15. package/dist/heart/hatch/specialist-tools.js +7 -7
  16. package/dist/heart/kept-notes.js +357 -0
  17. package/dist/heart/mcp/mcp-server.js +10 -10
  18. package/dist/heart/outlook/outlook-http-hooks.js +2 -2
  19. package/dist/heart/outlook/outlook-http-routes.js +4 -4
  20. package/dist/heart/outlook/outlook-read.js +3 -3
  21. package/dist/heart/outlook/readers/continuity-readers.js +3 -3
  22. package/dist/heart/outlook/readers/runtime-readers.js +2 -2
  23. package/dist/heart/session-events.js +3 -2
  24. package/dist/heart/{session-recall.js → session-transcript.js} +4 -4
  25. package/dist/heart/target-resolution.js +5 -5
  26. package/dist/heart/tool-description.js +4 -4
  27. package/dist/mind/diary.js +3 -3
  28. package/dist/mind/embedding-provider.js +1 -1
  29. package/dist/mind/file-state.js +1 -1
  30. package/dist/mind/friends/resolver.js +1 -1
  31. package/dist/mind/friends/types.js +1 -1
  32. package/dist/mind/{associative-recall.js → note-search.js} +17 -17
  33. package/dist/mind/prompt.js +12 -12
  34. package/dist/nerves/coverage/audit-rules.js +15 -6
  35. package/dist/nerves/coverage/audit.js +27 -1
  36. package/dist/nerves/coverage/cli.js +1 -1
  37. package/dist/nerves/coverage/file-completeness.js +2 -2
  38. package/dist/outlook-ui/assets/{index-DC7sZefn.js → index-xTdv64BV.js} +2 -2
  39. package/dist/outlook-ui/index.html +1 -1
  40. package/dist/repertoire/bitwarden-store.js +1 -1
  41. package/dist/repertoire/bundle-templates.js +1 -1
  42. package/dist/repertoire/skills.js +1 -1
  43. package/dist/repertoire/tools-base.js +3 -3
  44. package/dist/repertoire/tools-bridge.js +9 -9
  45. package/dist/repertoire/tools-continuity.js +2 -2
  46. package/dist/repertoire/{tools-memory.js → tools-notes.js} +6 -6
  47. package/dist/repertoire/tools-session.js +12 -12
  48. package/dist/senses/bluebubbles/attachment-cache.js +3 -3
  49. package/dist/senses/bluebubbles/index.js +1 -1
  50. package/dist/senses/bluebubbles/media.js +1 -1
  51. package/dist/senses/cli/image-paste.js +4 -4
  52. package/dist/senses/inner-dialog.js +2 -2
  53. package/dist/senses/surface-tool.js +1 -1
  54. package/package.json +1 -1
  55. package/skills/agent-commerce.md +1 -1
  56. package/skills/configure-dev-tools.md +2 -2
@@ -0,0 +1,357 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.gatherKeptNotesCandidates = gatherKeptNotesCandidates;
37
+ exports.renderKeptNotesOutcome = renderKeptNotesOutcome;
38
+ exports.injectKeptNotes = injectKeptNotes;
39
+ exports.createKeptNotesJudge = createKeptNotesJudge;
40
+ const fs = __importStar(require("fs"));
41
+ const path = __importStar(require("path"));
42
+ const diary_1 = require("../mind/diary");
43
+ const runtime_1 = require("../nerves/runtime");
44
+ const DEFAULT_TIMEOUT_MS = 2500;
45
+ const MAX_CANDIDATES = 8;
46
+ const NOOP_CALLBACKS = {
47
+ onModelStart() { },
48
+ onModelStreamStart() { },
49
+ onTextChunk() { },
50
+ onReasoningChunk() { },
51
+ onToolStart() { },
52
+ onToolEnd() { },
53
+ onError() { },
54
+ };
55
+ function elapsedSince(startedAt) {
56
+ return Math.max(0, Date.now() - startedAt);
57
+ }
58
+ function latestUserText(messages) {
59
+ for (let i = messages.length - 1; i >= 0; i--) {
60
+ const message = messages[i];
61
+ if (message.role !== "user" || typeof message.content !== "string")
62
+ continue;
63
+ const text = message.content.trim();
64
+ if (text)
65
+ return text;
66
+ }
67
+ return "";
68
+ }
69
+ function tokenize(text) {
70
+ return new Set(text
71
+ .toLowerCase()
72
+ .split(/[^a-z0-9]+/g)
73
+ .map((token) => token.trim())
74
+ .filter((token) => token.length > 2));
75
+ }
76
+ function scoreText(queryTerms, text) {
77
+ const textTerms = tokenize(text);
78
+ let matches = 0;
79
+ for (const term of queryTerms) {
80
+ if (textTerms.has(term))
81
+ matches += 1;
82
+ }
83
+ return matches / queryTerms.size;
84
+ }
85
+ function readJournalIndex(journalDir) {
86
+ try {
87
+ const parsed = JSON.parse(fs.readFileSync(path.join(journalDir, ".index.json"), "utf8"));
88
+ if (!Array.isArray(parsed))
89
+ return [];
90
+ return parsed
91
+ .filter((entry) => (typeof entry === "object" &&
92
+ entry !== null &&
93
+ typeof entry.filename === "string" &&
94
+ typeof entry.preview === "string"));
95
+ }
96
+ catch {
97
+ return [];
98
+ }
99
+ }
100
+ function journalDirForDiaryRoot(diaryRoot, explicitJournalDir) {
101
+ if (explicitJournalDir)
102
+ return explicitJournalDir;
103
+ return path.join(path.dirname(diaryRoot), "journal");
104
+ }
105
+ function diaryCandidate(fact) {
106
+ return {
107
+ text: fact.text,
108
+ source: { kind: "diary", label: "diary", ref: fact.id },
109
+ };
110
+ }
111
+ function friendNoteCandidates(friend, queryTerms) {
112
+ if (!friend)
113
+ return [];
114
+ return Object.entries(friend.notes ?? {})
115
+ .map(([key, note]) => {
116
+ const text = `${friend.name} / ${key}: ${note.value}`;
117
+ return {
118
+ candidate: {
119
+ text,
120
+ source: { kind: "friend-note", label: `friend note: ${friend.name}`, ref: key },
121
+ },
122
+ score: scoreText(queryTerms, `${key} ${note.value}`),
123
+ };
124
+ })
125
+ .filter((entry) => entry.score > 0);
126
+ }
127
+ function gatherKeptNotesCandidates(query, options = {}) {
128
+ const queryTerms = tokenize(query);
129
+ if (queryTerms.size === 0)
130
+ return [];
131
+ const diaryRoot = (0, diary_1.resolveDiaryRoot)(options.diaryRoot);
132
+ const diaryEntries = (0, diary_1.readDiaryEntries)(diaryRoot);
133
+ const diaryCandidates = diaryEntries
134
+ .map((fact) => ({ candidate: diaryCandidate(fact), score: scoreText(queryTerms, fact.text) }))
135
+ .filter((entry) => entry.score > 0);
136
+ const journalDir = journalDirForDiaryRoot(diaryRoot, options.journalDir);
137
+ const journalCandidates = readJournalIndex(journalDir)
138
+ .map((entry) => ({
139
+ candidate: {
140
+ text: `${entry.filename}: ${entry.preview}`,
141
+ source: { kind: "journal", label: "journal", ref: entry.filename },
142
+ },
143
+ score: scoreText(queryTerms, `${entry.filename} ${entry.preview}`),
144
+ }))
145
+ .filter((entry) => entry.score > 0);
146
+ return [...diaryCandidates, ...journalCandidates, ...friendNoteCandidates(options.friend, queryTerms)]
147
+ .sort((left, right) => right.score - left.score)
148
+ .slice(0, MAX_CANDIDATES)
149
+ .map((entry) => entry.candidate);
150
+ }
151
+ function selectedSources(candidates, indexes) {
152
+ if (!indexes || indexes.length === 0)
153
+ return [];
154
+ const sources = [];
155
+ for (const index of indexes) {
156
+ if (!Number.isInteger(index))
157
+ continue;
158
+ const candidate = candidates[index];
159
+ if (candidate)
160
+ sources.push(candidate.source);
161
+ }
162
+ return sources;
163
+ }
164
+ function isFirstPerson(text) {
165
+ return /^(i|i'm|i’ve|i've|my|me)\b/i.test(text.trim());
166
+ }
167
+ function foundLine(text) {
168
+ const trimmed = text.trim();
169
+ if (isFirstPerson(trimmed))
170
+ return trimmed;
171
+ return `I kept this: ${trimmed}`;
172
+ }
173
+ function fuzzyLine(text) {
174
+ const trimmed = text.trim();
175
+ if (isFirstPerson(trimmed))
176
+ return trimmed;
177
+ return `I may have kept something related: ${trimmed}`;
178
+ }
179
+ const SOURCE_KIND_ORDER = ["diary", "journal", "friend-note"];
180
+ const SOURCE_KIND_LABELS = {
181
+ diary: "my diary",
182
+ journal: "my journal",
183
+ "friend-note": "my friend notes",
184
+ };
185
+ function joinLabels(labels) {
186
+ if (labels.length === 1)
187
+ return labels[0];
188
+ if (labels.length === 2)
189
+ return `${labels[0]} and ${labels[1]}`;
190
+ return `${labels.slice(0, -1).join(", ")}, and ${labels[labels.length - 1]}`;
191
+ }
192
+ function sourceHeading(sources) {
193
+ const sourceKinds = new Set(sources.map((source) => source.kind));
194
+ const labels = SOURCE_KIND_ORDER
195
+ .filter((kind) => sourceKinds.has(kind))
196
+ .map((kind) => SOURCE_KIND_LABELS[kind]);
197
+ if (labels.length === 0)
198
+ return "## from notes i chose to keep";
199
+ return `## from ${joinLabels(labels)}`;
200
+ }
201
+ function renderKeptNotesOutcome(outcome) {
202
+ if (outcome.status === "found") {
203
+ return `${sourceHeading(outcome.sources)}\nThis may matter now:\n${foundLine(outcome.note)}`;
204
+ }
205
+ if (outcome.status === "fuzzy") {
206
+ return `${sourceHeading(outcome.sources)}\nThis is only a possible match; I should verify it before relying on it:\n${fuzzyLine(outcome.hint)}`;
207
+ }
208
+ return null;
209
+ }
210
+ function finish(outcome, traceId) {
211
+ (0, runtime_1.emitNervesEvent)({
212
+ component: "mind",
213
+ event: "mind.kept_notes_end",
214
+ trace_id: traceId,
215
+ message: "kept notes completed",
216
+ meta: { status: outcome.status, elapsedMs: outcome.elapsedMs },
217
+ });
218
+ return outcome;
219
+ }
220
+ async function withTimeout(promise, timeoutMs) {
221
+ return await new Promise((resolve, reject) => {
222
+ const timeout = setTimeout(() => resolve("timeout"), timeoutMs);
223
+ promise
224
+ .then((value) => {
225
+ clearTimeout(timeout);
226
+ resolve(value);
227
+ })
228
+ .catch((error) => {
229
+ clearTimeout(timeout);
230
+ reject(error);
231
+ });
232
+ });
233
+ }
234
+ async function injectKeptNotes(messages, options = {}) {
235
+ const startedAt = Date.now();
236
+ const systemMessage = messages[0];
237
+ const query = latestUserText(messages);
238
+ if (systemMessage?.role !== "system" || typeof systemMessage.content !== "string" || !query) {
239
+ return { status: "none", elapsedMs: elapsedSince(startedAt), pressure: [] };
240
+ }
241
+ (0, runtime_1.emitNervesEvent)({
242
+ component: "mind",
243
+ event: "mind.kept_notes_start",
244
+ trace_id: options.traceId,
245
+ message: "kept notes started",
246
+ meta: { channel: options.channel ?? "unknown" },
247
+ });
248
+ try {
249
+ const candidates = gatherKeptNotesCandidates(query, options);
250
+ if (candidates.length === 0 || !options.judge) {
251
+ return finish({ status: "none", elapsedMs: elapsedSince(startedAt), pressure: [] }, options.traceId);
252
+ }
253
+ const judged = await withTimeout(options.judge({ query, candidates }), options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
254
+ if (judged === "timeout") {
255
+ return finish({ status: "timeout", elapsedMs: elapsedSince(startedAt) }, options.traceId);
256
+ }
257
+ const elapsedMs = elapsedSince(startedAt);
258
+ const outcome = judged.status === "found"
259
+ ? { status: "found", note: judged.note, sources: selectedSources(candidates, judged.sourceIndexes), elapsedMs }
260
+ : judged.status === "fuzzy"
261
+ ? { status: "fuzzy", hint: judged.hint, sources: selectedSources(candidates, judged.sourceIndexes), elapsedMs }
262
+ : { status: "none", pressure: judged.pressure, elapsedMs };
263
+ if (outcome.status === "found" || outcome.status === "fuzzy") {
264
+ const rendered = renderKeptNotesOutcome(outcome);
265
+ messages[0] = { role: "system", content: `${systemMessage.content}\n\n${rendered}` };
266
+ (0, runtime_1.emitNervesEvent)({
267
+ component: "mind",
268
+ event: "mind.kept_notes_injected",
269
+ trace_id: options.traceId,
270
+ message: "kept notes injected",
271
+ meta: { status: outcome.status, sourceCount: outcome.sources.length },
272
+ });
273
+ }
274
+ return finish(outcome, options.traceId);
275
+ }
276
+ catch (error) {
277
+ const reason = error instanceof Error ? error.message : String(error);
278
+ const outcome = { status: "error", reason, elapsedMs: elapsedSince(startedAt) };
279
+ (0, runtime_1.emitNervesEvent)({
280
+ level: "warn",
281
+ component: "mind",
282
+ event: "mind.kept_notes_error",
283
+ trace_id: options.traceId,
284
+ message: "kept notes failed",
285
+ meta: { reason },
286
+ });
287
+ return finish(outcome, options.traceId);
288
+ }
289
+ }
290
+ function parseJudgeResult(content) {
291
+ try {
292
+ const parsed = JSON.parse(content);
293
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
294
+ return { status: "none", pressure: ["invalid kept notes judge output"] };
295
+ }
296
+ const record = parsed;
297
+ if (record.status === "found" && typeof record.note === "string" && record.note.trim()) {
298
+ return {
299
+ status: "found",
300
+ note: record.note.trim(),
301
+ sourceIndexes: Array.isArray(record.sourceIndexes) ? record.sourceIndexes.filter((index) => typeof index === "number") : undefined,
302
+ };
303
+ }
304
+ if (record.status === "fuzzy" && typeof record.hint === "string" && record.hint.trim()) {
305
+ return {
306
+ status: "fuzzy",
307
+ hint: record.hint.trim(),
308
+ sourceIndexes: Array.isArray(record.sourceIndexes) ? record.sourceIndexes.filter((index) => typeof index === "number") : undefined,
309
+ };
310
+ }
311
+ if (record.status === "none") {
312
+ return {
313
+ status: "none",
314
+ pressure: Array.isArray(record.pressure) ? record.pressure.filter((value) => typeof value === "string") : [],
315
+ };
316
+ }
317
+ return { status: "none", pressure: ["invalid kept notes judge output"] };
318
+ }
319
+ catch {
320
+ return { status: "none", pressure: ["invalid kept notes judge output"] };
321
+ }
322
+ }
323
+ function createJudgePrompt(input) {
324
+ const candidates = input.candidates
325
+ .map((candidate, index) => `${index}. [${candidate.source.kind}] ${candidate.text}`)
326
+ .join("\n");
327
+ return [
328
+ {
329
+ role: "system",
330
+ content: [
331
+ "Decide whether these intentionally kept notes matter to the user's current turn.",
332
+ "Return only JSON.",
333
+ "Use found when a note clearly helps, fuzzy when a note is close but uncertain, and none when nothing should be surfaced.",
334
+ "Shapes: {\"status\":\"found\",\"note\":\"...\",\"sourceIndexes\":[0]}, {\"status\":\"fuzzy\",\"hint\":\"...\",\"sourceIndexes\":[0]}, or {\"status\":\"none\",\"pressure\":[]}.",
335
+ ].join("\n"),
336
+ },
337
+ {
338
+ role: "user",
339
+ content: `Current turn:\n${input.query}\n\nCandidates:\n${candidates}`,
340
+ },
341
+ ];
342
+ }
343
+ function createKeptNotesJudge(runtime, signal) {
344
+ return async (input) => {
345
+ const messages = createJudgePrompt(input);
346
+ runtime.resetTurnState?.(messages);
347
+ const result = await runtime.streamTurn({
348
+ messages,
349
+ activeTools: [],
350
+ callbacks: NOOP_CALLBACKS,
351
+ signal,
352
+ toolChoiceRequired: false,
353
+ reasoningEffort: "low",
354
+ });
355
+ return parseJudgeResult(result.content ?? "");
356
+ };
357
+ }
@@ -92,7 +92,7 @@ const TOOL_TO_COMMAND = {
92
92
  catchup: "agent.catchup",
93
93
  delegate: "agent.delegate",
94
94
  get_context: "agent.getContext",
95
- search_memory: "agent.searchMemory",
95
+ search_notes: "agent.searchNotes",
96
96
  get_task: "agent.getTask",
97
97
  check_scope: "agent.checkScope",
98
98
  request_decision: "agent.requestDecision",
@@ -270,7 +270,7 @@ function createMcpServer(options) {
270
270
  catchup: "handleAgentCatchup",
271
271
  delegate: "handleAgentDelegate",
272
272
  get_context: "handleAgentGetContext",
273
- search_memory: "handleAgentSearchMemory",
273
+ search_notes: "handleAgentSearchNotes",
274
274
  get_task: "handleAgentGetTask",
275
275
  check_scope: "handleAgentCheckScope",
276
276
  request_decision: "handleAgentRequestDecision",
@@ -498,7 +498,7 @@ function getToolSchemas() {
498
498
  return [
499
499
  {
500
500
  name: "ask",
501
- description: "Ask the agent a question. The agent uses its memory and recent session context to provide a useful answer.",
501
+ description: "Ask the agent a question. The agent uses its diary, journal, and recent session context to provide a useful answer.",
502
502
  inputSchema: {
503
503
  type: "object",
504
504
  properties: {
@@ -509,7 +509,7 @@ function getToolSchemas() {
509
509
  },
510
510
  {
511
511
  name: "status",
512
- description: "Get the agent's current status including active sessions, memory state, and activity level.",
512
+ description: "Get the agent's current status including active sessions, diary and journal state, and activity level.",
513
513
  inputSchema: {
514
514
  type: "object",
515
515
  properties: {},
@@ -537,19 +537,19 @@ function getToolSchemas() {
537
537
  },
538
538
  {
539
539
  name: "get_context",
540
- description: "Get the agent's current working context including memory summary, active tasks, and relevant state.",
540
+ description: "Get the agent's current working context including note summary, active tasks, and relevant state.",
541
541
  inputSchema: {
542
542
  type: "object",
543
543
  properties: {},
544
544
  },
545
545
  },
546
546
  {
547
- name: "search_memory",
548
- description: "Search the agent's memory for information about a specific topic. Returns matching lines from the agent's memory file.",
547
+ name: "search_notes",
548
+ description: "Search the agent's diary for information about a specific topic. Returns matching diary lines.",
549
549
  inputSchema: {
550
550
  type: "object",
551
551
  properties: {
552
- query: { type: "string", description: "Search term to look for in agent memory" },
552
+ query: { type: "string", description: "Search term to look for in agent notes" },
553
553
  },
554
554
  required: ["query"],
555
555
  },
@@ -587,7 +587,7 @@ function getToolSchemas() {
587
587
  },
588
588
  {
589
589
  name: "check_guidance",
590
- description: "Get guidance from the agent on how to approach a topic. The agent searches its memory for relevant guidance.",
590
+ description: "Get guidance from the agent on how to approach a topic. The agent searches its diary, journal, and session context for relevant guidance.",
591
591
  inputSchema: {
592
592
  type: "object",
593
593
  properties: {
@@ -631,7 +631,7 @@ function getToolSchemas() {
631
631
  },
632
632
  {
633
633
  name: "send_message",
634
- description: "Send a message to the agent and get a synchronous response. This runs a full agent turn — the agent can use tools, think, and respond. For multi-turn conversations, call repeatedly — the agent remembers prior messages in this session.",
634
+ description: "Send a message to the agent and get a synchronous response. This runs a full agent turn — the agent can use tools, think, and respond. For multi-turn conversations, call repeatedly — the agent keeps prior turns in this session.",
635
635
  inputSchema: {
636
636
  type: "object",
637
637
  properties: {
@@ -47,14 +47,14 @@ function createOutlookHttpReadHooks(options) {
47
47
  readAgentCoding: options.readAgentCoding ?? ((agentName) => (0, outlook_read_1.readCodingDeep)(agentRoot(agentName))),
48
48
  readAgentAttention: options.readAgentAttention ?? ((agentName) => (0, outlook_read_1.readAttentionView)(agentName, readOptions)),
49
49
  readAgentBridges: options.readAgentBridges ?? ((agentName) => (0, outlook_read_1.readBridgeInventory)(agentRoot(agentName))),
50
- readAgentMemory: options.readAgentMemory ?? ((agentName) => (0, outlook_read_1.readMemoryView)(agentRoot(agentName))),
50
+ readAgentNotes: options.readAgentNotes ?? ((agentName) => (0, outlook_read_1.readNotesView)(agentRoot(agentName))),
51
51
  readAgentFriends: options.readAgentFriends ?? ((agentName) => (0, outlook_read_1.readFriendView)(agentName, readOptions)),
52
52
  readAgentContinuity: options.readAgentContinuity ?? ((agentName) => (0, outlook_read_1.readOutlookContinuity)(agentRoot(agentName), agentName)),
53
53
  readAgentOrientation: options.readAgentOrientation ?? ((agentName) => (0, outlook_read_1.readOrientationView)(agentRoot(agentName), agentName)),
54
54
  readAgentObligations: options.readAgentObligations ?? ((agentName) => (0, outlook_read_1.readObligationDetailView)(agentRoot(agentName))),
55
55
  readAgentChanges: options.readAgentChanges ?? ((agentName) => (0, outlook_read_1.readChangesView)(agentRoot(agentName))),
56
56
  readAgentSelfFix: options.readAgentSelfFix ?? ((agentName) => (0, outlook_read_1.readSelfFixView)(agentRoot(agentName))),
57
- readAgentMemoryDecisions: options.readAgentMemoryDecisions ?? ((agentName) => (0, outlook_read_1.readMemoryDecisionView)(agentRoot(agentName))),
57
+ readAgentNoteDecisions: options.readAgentNoteDecisions ?? ((agentName) => (0, outlook_read_1.readNoteDecisionView)(agentRoot(agentName))),
58
58
  readAgentHabits: options.readAgentHabits ?? ((agentName) => (0, outlook_read_1.readHabitView)(agentRoot(agentName))),
59
59
  readDaemonHealth: options.readDaemonHealth ?? (() => (0, outlook_read_1.readDaemonHealthDeep)(options.healthPath)),
60
60
  readLogs: options.readLogs ?? (() => (0, outlook_read_1.readLogView)(options.logPath ?? null)),
@@ -142,8 +142,8 @@ function handleAgentRoute(request, response, context) {
142
142
  (0, outlook_http_response_1.writeJson)(response, 200, options.hooks.readAgentBridges(agent));
143
143
  return;
144
144
  }
145
- if (surface === "memory") {
146
- (0, outlook_http_response_1.writeJson)(response, 200, options.hooks.readAgentMemory(agent));
145
+ if (surface === "notes") {
146
+ (0, outlook_http_response_1.writeJson)(response, 200, options.hooks.readAgentNotes(agent));
147
147
  return;
148
148
  }
149
149
  if (surface === "friends") {
@@ -170,8 +170,8 @@ function handleAgentRoute(request, response, context) {
170
170
  (0, outlook_http_response_1.writeJson)(response, 200, options.hooks.readAgentSelfFix(agent));
171
171
  return;
172
172
  }
173
- if (surface === "memory-decisions") {
174
- (0, outlook_http_response_1.writeJson)(response, 200, options.hooks.readAgentMemoryDecisions(agent));
173
+ if (surface === "note-decisions") {
174
+ (0, outlook_http_response_1.writeJson)(response, 200, options.hooks.readAgentNoteDecisions(agent));
175
175
  return;
176
176
  }
177
177
  if (surface === "dismiss-obligation" && request.method === "POST") {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readSelfFixView = exports.readOutlookContinuity = exports.readOrientationView = exports.readObligationDetailView = exports.readMemoryDecisionView = exports.readChangesView = exports.readNeedsMeView = exports.readMemoryView = exports.readLogView = exports.readHabitView = exports.readFriendView = exports.readDeskPrefs = exports.readDaemonHealthDeep = exports.readCodingDeep = exports.readBridgeInventory = exports.readAttentionView = exports.readSessionTranscript = exports.readSessionInventory = exports.readOutlookMachineState = exports.readOutlookAgentState = exports.readObligationSummary = void 0;
3
+ exports.readSelfFixView = exports.readOutlookContinuity = exports.readOrientationView = exports.readObligationDetailView = exports.readNoteDecisionView = exports.readChangesView = exports.readNeedsMeView = exports.readNotesView = exports.readLogView = exports.readHabitView = exports.readFriendView = exports.readDeskPrefs = exports.readDaemonHealthDeep = exports.readCodingDeep = exports.readBridgeInventory = exports.readAttentionView = exports.readSessionTranscript = exports.readSessionInventory = exports.readOutlookMachineState = exports.readOutlookAgentState = exports.readObligationSummary = void 0;
4
4
  var agent_machine_1 = require("./readers/agent-machine");
5
5
  Object.defineProperty(exports, "readObligationSummary", { enumerable: true, get: function () { return agent_machine_1.readObligationSummary; } });
6
6
  Object.defineProperty(exports, "readOutlookAgentState", { enumerable: true, get: function () { return agent_machine_1.readOutlookAgentState; } });
@@ -17,11 +17,11 @@ Object.defineProperty(exports, "readDeskPrefs", { enumerable: true, get: functio
17
17
  Object.defineProperty(exports, "readFriendView", { enumerable: true, get: function () { return runtime_readers_1.readFriendView; } });
18
18
  Object.defineProperty(exports, "readHabitView", { enumerable: true, get: function () { return runtime_readers_1.readHabitView; } });
19
19
  Object.defineProperty(exports, "readLogView", { enumerable: true, get: function () { return runtime_readers_1.readLogView; } });
20
- Object.defineProperty(exports, "readMemoryView", { enumerable: true, get: function () { return runtime_readers_1.readMemoryView; } });
20
+ Object.defineProperty(exports, "readNotesView", { enumerable: true, get: function () { return runtime_readers_1.readNotesView; } });
21
21
  Object.defineProperty(exports, "readNeedsMeView", { enumerable: true, get: function () { return runtime_readers_1.readNeedsMeView; } });
22
22
  var continuity_readers_1 = require("./readers/continuity-readers");
23
23
  Object.defineProperty(exports, "readChangesView", { enumerable: true, get: function () { return continuity_readers_1.readChangesView; } });
24
- Object.defineProperty(exports, "readMemoryDecisionView", { enumerable: true, get: function () { return continuity_readers_1.readMemoryDecisionView; } });
24
+ Object.defineProperty(exports, "readNoteDecisionView", { enumerable: true, get: function () { return continuity_readers_1.readNoteDecisionView; } });
25
25
  Object.defineProperty(exports, "readObligationDetailView", { enumerable: true, get: function () { return continuity_readers_1.readObligationDetailView; } });
26
26
  Object.defineProperty(exports, "readOrientationView", { enumerable: true, get: function () { return continuity_readers_1.readOrientationView; } });
27
27
  Object.defineProperty(exports, "readOutlookContinuity", { enumerable: true, get: function () { return continuity_readers_1.readOutlookContinuity; } });
@@ -38,7 +38,7 @@ exports.readOrientationView = readOrientationView;
38
38
  exports.readObligationDetailView = readObligationDetailView;
39
39
  exports.readChangesView = readChangesView;
40
40
  exports.readSelfFixView = readSelfFixView;
41
- exports.readMemoryDecisionView = readMemoryDecisionView;
41
+ exports.readNoteDecisionView = readNoteDecisionView;
42
42
  const fs = __importStar(require("fs"));
43
43
  const path = __importStar(require("path"));
44
44
  const runtime_1 = require("../../../nerves/runtime");
@@ -304,8 +304,8 @@ function readSelfFixView(agentRoot) {
304
304
  steps,
305
305
  };
306
306
  }
307
- function readMemoryDecisionView(agentRoot, limit = 50) {
308
- const logPath = path.join(agentRoot, "state", "outlook", "memory-decisions.jsonl");
307
+ function readNoteDecisionView(agentRoot, limit = 50) {
308
+ const logPath = path.join(agentRoot, "state", "outlook", "note-decisions.jsonl");
309
309
  let lines = [];
310
310
  try {
311
311
  const raw = fs.readFileSync(logPath, "utf-8");
@@ -37,7 +37,7 @@ exports.readCodingDeep = readCodingDeep;
37
37
  exports.readAttentionView = readAttentionView;
38
38
  exports.readBridgeInventory = readBridgeInventory;
39
39
  exports.readDaemonHealthDeep = readDaemonHealthDeep;
40
- exports.readMemoryView = readMemoryView;
40
+ exports.readNotesView = readNotesView;
41
41
  exports.readFriendView = readFriendView;
42
42
  exports.readLogView = readLogView;
43
43
  exports.readHabitView = readHabitView;
@@ -314,7 +314,7 @@ function readDaemonHealthDeep(healthPath) {
314
314
  }
315
315
  }
316
316
  /* v8 ignore stop */
317
- function readMemoryView(agentRoot) {
317
+ function readNotesView(agentRoot) {
318
318
  const diaryRoot = path.join(agentRoot, "diary");
319
319
  const effectiveDiaryRoot = fs.existsSync(diaryRoot) ? diaryRoot : null;
320
320
  const diaryEntries = [];
@@ -64,13 +64,14 @@ function formatElapsed(ms) {
64
64
  const days = Math.floor(hours / 24);
65
65
  return `${days}d ago`;
66
66
  }
67
+ const LEGACY_WRITTEN_NOTE_PREFIX = "mem" + "ory";
67
68
  const TOOL_NAME_MIGRATIONS = {
68
69
  final_answer: "settle",
69
70
  no_response: "observe",
70
71
  go_inward: "ponder",
71
72
  descend: "ponder",
72
- memory_save: "diary_write",
73
- memory_search: "recall",
73
+ [`${LEGACY_WRITTEN_NOTE_PREFIX}_save`]: "diary_write",
74
+ [`${LEGACY_WRITTEN_NOTE_PREFIX}_search`]: "search_notes",
74
75
  };
75
76
  function normalizeUsage(usage) {
76
77
  if (!usage || typeof usage !== "object")
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.recallSession = recallSession;
3
+ exports.summarizeSessionTail = summarizeSessionTail;
4
4
  exports.searchSessionTranscript = searchSessionTranscript;
5
5
  const runtime_1 = require("../nerves/runtime");
6
6
  const session_events_1 = require("./session-events");
@@ -91,11 +91,11 @@ function buildSearchExcerpts(messages, query, maxMatches) {
91
91
  .slice(0, maxMatches)
92
92
  .map((candidate) => candidate.excerpt);
93
93
  }
94
- async function recallSession(options) {
94
+ async function summarizeSessionTail(options) {
95
95
  (0, runtime_1.emitNervesEvent)({
96
96
  component: "daemon",
97
- event: "daemon.session_recall",
98
- message: "recalling session transcript tail",
97
+ event: "daemon.session_tail_summary",
98
+ message: "summarizing session transcript tail",
99
99
  meta: {
100
100
  friendId: options.friendId,
101
101
  channel: options.channel,
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.listTargetSessionCandidates = listTargetSessionCandidates;
4
4
  exports.formatTargetSessionCandidates = formatTargetSessionCandidates;
5
- const session_recall_1 = require("./session-recall");
5
+ const session_transcript_1 = require("./session-transcript");
6
6
  const session_activity_1 = require("./session-activity");
7
7
  const trust_explanation_1 = require("../mind/friends/trust-explanation");
8
8
  const runtime_1 = require("../nerves/runtime");
@@ -71,7 +71,7 @@ async function listTargetSessionCandidates(input) {
71
71
  friend,
72
72
  channel: entry.channel,
73
73
  });
74
- const recall = await (0, session_recall_1.recallSession)({
74
+ const sessionTail = await (0, session_transcript_1.summarizeSessionTail)({
75
75
  sessionPath: entry.sessionPath,
76
76
  friendId: entry.friendId,
77
77
  channel: entry.channel,
@@ -80,9 +80,9 @@ async function listTargetSessionCandidates(input) {
80
80
  summarize: input.summarize,
81
81
  trustLevel: trust.level,
82
82
  });
83
- const snapshot = recall.kind === "ok"
84
- ? recall.snapshot
85
- : recall.kind === "empty"
83
+ const snapshot = sessionTail.kind === "ok"
84
+ ? sessionTail.snapshot
85
+ : sessionTail.kind === "empty"
86
86
  ? "recent focus: no recent visible messages"
87
87
  : "recent focus: session transcript unavailable";
88
88
  const delivery = describeDelivery({
@@ -55,12 +55,12 @@ const TOOL_DESCRIPTIONS = {
55
55
  return "searching code...";
56
56
  return `searching code for '${truncate(p, 40)}'...`;
57
57
  },
58
- // Memory and knowledge
59
- recall: (args) => {
58
+ // Notes and knowledge
59
+ search_notes: (args) => {
60
60
  const q = args.query;
61
61
  if (!q)
62
- return "searching memory...";
63
- return `searching memory for '${truncate(q, 40)}'...`;
62
+ return "searching notes...";
63
+ return `searching notes for '${truncate(q, 40)}'...`;
64
64
  },
65
65
  diary_write: (args) => {
66
66
  const about = args.about;
@@ -45,7 +45,7 @@ const path = __importStar(require("path"));
45
45
  const crypto_1 = require("crypto");
46
46
  const identity_1 = require("../heart/identity");
47
47
  const runtime_1 = require("../nerves/runtime");
48
- const associative_recall_1 = require("./associative-recall");
48
+ const note_search_1 = require("./note-search");
49
49
  const diary_integrity_1 = require("./diary-integrity");
50
50
  const embedding_provider_1 = require("./embedding-provider");
51
51
  const DEDUP_THRESHOLD = 0.6;
@@ -164,7 +164,7 @@ function appendEntriesWithDedup(stores, incoming, options) {
164
164
  Array.isArray(fact.embedding) && fact.embedding.length > 0 &&
165
165
  Array.isArray(prior.embedding) && prior.embedding.length > 0 &&
166
166
  fact.embedding.length === prior.embedding.length) {
167
- return (0, associative_recall_1.cosineSimilarity)(fact.embedding, prior.embedding) > semanticThreshold;
167
+ return (0, note_search_1.cosineSimilarity)(fact.embedding, prior.embedding) > semanticThreshold;
168
168
  }
169
169
  return false;
170
170
  });
@@ -353,7 +353,7 @@ async function searchDiaryEntries(query, facts, embeddingProvider) {
353
353
  .filter((fact) => fact.embedding.length === queryEmbedding.length)
354
354
  .map((fact) => ({
355
355
  fact,
356
- score: (0, associative_recall_1.cosineSimilarity)(queryEmbedding, fact.embedding),
356
+ score: (0, note_search_1.cosineSimilarity)(queryEmbedding, fact.embedding),
357
357
  }))
358
358
  .filter((entry) => entry.score > 0)
359
359
  .sort((left, right) => right.score - left.score)