@ouro.bot/cli 0.1.0-alpha.290 → 0.1.0-alpha.292

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/changelog.json CHANGED
@@ -1,6 +1,18 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.292",
6
+ "changes": [
7
+ "feat(mind): add structured provenance tracking to diary entries. New DiaryEntryProvenance interface records tool, channel (cli/teams/bluebubbles/inner/mcp), friend identity (id + name), and trust level (family/friend/acquaintance/stranger) at write time. diary_write handler automatically extracts provenance from ToolContext. Associative recall and recall tool render provenance fields when present. Fully backwards compatible — existing entries without provenance parse and display normally. 19 tests across 4 test files with 100% coverage on new code."
8
+ ]
9
+ },
10
+ {
11
+ "version": "0.1.0-alpha.291",
12
+ "changes": [
13
+ "fix(coding): eliminate silent `~/AgentBundles/default.ouro` real-fs leak in the coding session manager. Root cause: `src/repertoire/coding/manager.ts` had a `safeAgentName()` helper that caught `getAgentName()` throws (which happens in vitest because there's no `--agent` in argv) and silently fell back to `\"default\"`. Combined with `src/repertoire/coding/index.ts:8` constructing the singleton as `new CodingSessionManager({})` (no options — real fs, no agentName), every vitest run that called `getCodingSessionManager()` followed by `resetCodingSessionManager()` triggered `shutdown()` → `persistState()` → `fs.mkdirSync('~/AgentBundles/default.ouro/state/coding', { recursive: true })` + `fs.writeFileSync('.../sessions.json', ...)`. This wrote real files under the developer's home directory on every coverage-gate run. The observable symptom was `~/AgentBundles/default.ouro/` reappearing minutes after `rm -rf` — PR B's housekeeping cleanup couldn't stick. Fix: deleted `safeAgentName()` and made the constructor's `agentName` default call `getAgentName()` directly, so construction fails loudly in vitest when identity isn't mocked. Updated `index.test.ts` to mock both `../../../heart/identity` and `fs` so the singleton can be tested without touching real disk. Updated `session-manager.test.ts`, `session-manager-branches.test.ts`, and `session-manager-persistence.test.ts` to either inline `agentName: \"test-coding-agent\"` in `noPersistence` or mock `../../../heart/identity` at file top. One persistence test assertion updated from `parentAgent === \"default\"` to `\"test-coding-agent\"`. Full coverage gate passes, 171 coding tests pass, `~/AgentBundles/default.ouro` stays deleted across 3 consecutive coverage-gate runs."
14
+ ]
15
+ },
4
16
  {
5
17
  "version": "0.1.0-alpha.290",
6
18
  "changes": [
@@ -197,8 +197,17 @@ async function injectAssociativeRecall(messages, options) {
197
197
  }
198
198
  }
199
199
  for (const fact of recalled) {
200
+ let meta = `score=${fact.score.toFixed(3)} source=${fact.source}`;
201
+ if (fact.provenance) {
202
+ if (fact.provenance.channel)
203
+ meta += ` channel=${fact.provenance.channel}`;
204
+ if (fact.provenance.friendName)
205
+ meta += ` friend=${fact.provenance.friendName}`;
206
+ if (fact.provenance.trust)
207
+ meta += ` trust=${fact.provenance.trust}`;
208
+ }
200
209
  resultLines.push({
201
- text: `[diary] ${fact.text} [score=${fact.score.toFixed(3)} source=${fact.source}]`,
210
+ text: `[diary] ${fact.text} [${meta}]`,
202
211
  score: fact.score,
203
212
  });
204
213
  }
@@ -235,6 +235,7 @@ async function saveDiaryEntry(options) {
235
235
  about: options.about?.trim() || undefined,
236
236
  createdAt: (options.now ?? (() => new Date()))().toISOString(),
237
237
  embedding,
238
+ ...(options.provenance ? { provenance: options.provenance } : {}),
238
239
  };
239
240
  return appendEntriesWithDedup(stores, [fact], { semanticThreshold: SEMANTIC_DEDUP_THRESHOLD });
240
241
  }
@@ -39,14 +39,6 @@ const path = __importStar(require("path"));
39
39
  const identity_1 = require("../../heart/identity");
40
40
  const runtime_1 = require("../../nerves/runtime");
41
41
  const spawner_1 = require("./spawner");
42
- function safeAgentName() {
43
- try {
44
- return (0, identity_1.getAgentName)();
45
- }
46
- catch {
47
- return "default";
48
- }
49
- }
50
42
  function defaultStateFilePath(agentName) {
51
43
  return path.join((0, identity_1.getAgentRoot)(agentName), "state", "coding", "sessions.json");
52
44
  }
@@ -186,7 +178,16 @@ class CodingSessionManager {
186
178
  this.writeFileSync = options.writeFileSync ?? fs.writeFileSync;
187
179
  this.mkdirSync = options.mkdirSync ?? fs.mkdirSync;
188
180
  this.pidAlive = options.pidAlive ?? isPidAlive;
189
- this.agentName = options.agentName ?? safeAgentName();
181
+ // No silent fallback to "default" — if there's no agentName and no
182
+ // explicit option, getAgentName() throws. The previous `safeAgentName`
183
+ // helper fell back to "default" and ended up writing coding session
184
+ // state to `~/AgentBundles/default.ouro/state/coding/sessions.json` on
185
+ // every vitest run because the coding manager singleton constructs with
186
+ // `{}`. That leaked real-fs state into the developer's home directory
187
+ // on every coverage run. Production callers always pass via argv (see
188
+ // getAgentName); test callers must either pass `agentName` explicitly
189
+ // or mock `../../heart/identity`.
190
+ this.agentName = options.agentName ?? (0, identity_1.getAgentName)();
190
191
  this.stateFilePath = options.stateFilePath ?? defaultStateFilePath(this.agentName);
191
192
  this.artifactDirPath = options.artifactDirPath
192
193
  ?? (options.stateFilePath ? path.dirname(options.stateFilePath) : defaultArtifactDirPath(this.agentName));
@@ -172,7 +172,16 @@ exports.memoryToolDefinitions = [
172
172
  // Search diary entries
173
173
  const hits = await (0, diary_1.searchDiaryEntries)(query, (0, diary_1.readDiaryEntries)());
174
174
  for (const fact of hits) {
175
- resultLines.push(`[diary] ${fact.text} (source=${fact.source}, createdAt=${fact.createdAt})`);
175
+ let meta = `source=${fact.source}, createdAt=${fact.createdAt}`;
176
+ if (fact.provenance) {
177
+ if (fact.provenance.channel)
178
+ meta += `, channel=${fact.provenance.channel}`;
179
+ if (fact.provenance.friendName)
180
+ meta += `, friend=${fact.provenance.friendName}`;
181
+ if (fact.provenance.trust)
182
+ meta += `, trust=${fact.provenance.trust}`;
183
+ }
184
+ resultLines.push(`[diary] ${fact.text} (${meta})`);
176
185
  }
177
186
  // Search journal index
178
187
  const agentRoot = (0, identity_1.getAgentRoot)();
@@ -219,14 +228,32 @@ exports.memoryToolDefinitions = [
219
228
  },
220
229
  },
221
230
  },
222
- handler: async (a) => {
231
+ handler: async (a, ctx) => {
223
232
  const entry = (a.entry || "").trim();
224
233
  if (!entry)
225
234
  return "entry is required";
235
+ let provenance;
236
+ if (ctx?.context) {
237
+ const p = { tool: "diary_write" };
238
+ const channel = ctx.context.channel?.channel;
239
+ if (channel)
240
+ p.channel = channel;
241
+ const friendId = ctx.context.friend?.id;
242
+ if (friendId)
243
+ p.friendId = friendId;
244
+ const friendName = ctx.context.friend?.name;
245
+ if (friendName)
246
+ p.friendName = friendName;
247
+ const trust = ctx.context.friend?.trustLevel;
248
+ if (trust)
249
+ p.trust = trust;
250
+ provenance = p;
251
+ }
226
252
  const result = await (0, diary_1.saveDiaryEntry)({
227
253
  text: entry,
228
254
  source: "tool:diary_write",
229
255
  about: typeof a.about === "string" ? a.about : undefined,
256
+ provenance,
230
257
  });
231
258
  return `saved diary entry (added=${result.added}, skipped=${result.skipped})`;
232
259
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.290",
3
+ "version": "0.1.0-alpha.292",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",