@ouro.bot/cli 0.1.0-alpha.30 → 0.1.0-alpha.300

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 (284) hide show
  1. package/README.md +188 -190
  2. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
  3. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +1 -1
  4. package/changelog.json +1808 -0
  5. package/dist/arc/attention-types.js +8 -0
  6. package/dist/arc/cares.js +140 -0
  7. package/dist/arc/episodes.js +117 -0
  8. package/dist/arc/intentions.js +133 -0
  9. package/dist/arc/json-store.js +117 -0
  10. package/dist/arc/obligations.js +237 -0
  11. package/dist/arc/packets.js +203 -0
  12. package/dist/arc/presence.js +185 -0
  13. package/dist/heart/active-work.js +832 -0
  14. package/dist/heart/agent-entry.js +37 -2
  15. package/dist/heart/attachments/image-normalize.js +194 -0
  16. package/dist/heart/attachments/materialize.js +230 -0
  17. package/dist/heart/attachments/render.js +29 -0
  18. package/dist/heart/attachments/store.js +103 -0
  19. package/dist/heart/attachments/types.js +138 -0
  20. package/dist/heart/auth/auth-flow.js +456 -0
  21. package/dist/heart/bridges/manager.js +358 -0
  22. package/dist/heart/bridges/state-machine.js +135 -0
  23. package/dist/heart/bridges/store.js +123 -0
  24. package/dist/heart/bundle-state.js +168 -0
  25. package/dist/heart/commitments.js +111 -0
  26. package/dist/heart/config-registry.js +304 -0
  27. package/dist/heart/config.js +63 -30
  28. package/dist/heart/core.js +669 -195
  29. package/dist/heart/cross-chat-delivery.js +131 -0
  30. package/dist/heart/daemon/agent-config-check.js +149 -0
  31. package/dist/heart/daemon/agent-discovery.js +79 -3
  32. package/dist/heart/daemon/agent-service.js +360 -0
  33. package/dist/heart/daemon/cadence.js +70 -0
  34. package/dist/heart/daemon/cli-defaults.js +574 -0
  35. package/dist/heart/daemon/cli-exec.js +1945 -0
  36. package/dist/heart/daemon/cli-parse.js +808 -0
  37. package/dist/heart/daemon/cli-render.js +503 -0
  38. package/dist/heart/daemon/cli-types.js +8 -0
  39. package/dist/heart/daemon/daemon-cli.js +29 -1171
  40. package/dist/heart/daemon/daemon-entry.js +245 -3
  41. package/dist/heart/daemon/daemon-health.js +136 -0
  42. package/dist/heart/daemon/daemon-runtime-sync.js +153 -12
  43. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  44. package/dist/heart/daemon/daemon.js +706 -57
  45. package/dist/heart/daemon/health-monitor.js +38 -0
  46. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  47. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  48. package/dist/heart/daemon/inner-status.js +89 -0
  49. package/dist/heart/daemon/launchd.js +46 -9
  50. package/dist/heart/daemon/log-tailer.js +82 -12
  51. package/dist/heart/daemon/logs-prune.js +105 -0
  52. package/dist/heart/daemon/message-router.js +17 -8
  53. package/dist/heart/daemon/os-cron-deps.js +134 -0
  54. package/dist/heart/daemon/ouro-bot-entry.js +1 -1
  55. package/dist/heart/daemon/process-manager.js +180 -0
  56. package/dist/heart/daemon/pulse.js +463 -0
  57. package/dist/heart/daemon/run-hooks.js +2 -0
  58. package/dist/heart/daemon/runtime-logging.js +67 -16
  59. package/dist/heart/daemon/runtime-metadata.js +101 -0
  60. package/dist/heart/daemon/runtime-mode.js +67 -0
  61. package/dist/heart/daemon/safe-mode.js +161 -0
  62. package/dist/heart/daemon/sense-manager.js +72 -3
  63. package/dist/heart/daemon/session-id-resolver.js +131 -0
  64. package/dist/heart/daemon/skill-management-installer.js +94 -0
  65. package/dist/heart/daemon/socket-client.js +307 -0
  66. package/dist/heart/daemon/task-scheduler.js +3 -25
  67. package/dist/heart/daemon/thoughts.js +510 -0
  68. package/dist/heart/delegation.js +62 -0
  69. package/dist/heart/habits/habit-migration.js +181 -0
  70. package/dist/heart/habits/habit-parser.js +140 -0
  71. package/dist/heart/habits/habit-scheduler.js +371 -0
  72. package/dist/heart/{daemon → hatch}/hatch-flow.js +30 -120
  73. package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
  74. package/dist/heart/{daemon → hatch}/specialist-prompt.js +10 -7
  75. package/dist/heart/{daemon → hatch}/specialist-tools.js +49 -3
  76. package/dist/heart/identity.js +163 -60
  77. package/dist/heart/kicks.js +2 -20
  78. package/dist/heart/mcp/mcp-server.js +653 -0
  79. package/dist/heart/migrate-config.js +127 -0
  80. package/dist/heart/model-capabilities.js +59 -0
  81. package/dist/heart/outlook/outlook-http.js +439 -0
  82. package/dist/heart/outlook/outlook-read.js +1618 -0
  83. package/dist/heart/outlook/outlook-render.js +1032 -0
  84. package/dist/heart/outlook/outlook-types.js +7 -0
  85. package/dist/heart/outlook/outlook-view.js +194 -0
  86. package/dist/heart/progress-story.js +42 -0
  87. package/dist/heart/provider-failover.js +88 -0
  88. package/dist/heart/provider-ping.js +162 -0
  89. package/dist/heart/providers/anthropic-token.js +163 -0
  90. package/dist/heart/providers/anthropic.js +169 -46
  91. package/dist/heart/providers/azure.js +98 -11
  92. package/dist/heart/providers/error-classification.js +63 -0
  93. package/dist/heart/providers/github-copilot.js +136 -0
  94. package/dist/heart/providers/minimax-vlm.js +189 -0
  95. package/dist/heart/providers/minimax.js +23 -5
  96. package/dist/heart/providers/openai-codex.js +33 -22
  97. package/dist/heart/session-activity.js +172 -0
  98. package/dist/heart/session-recall.js +216 -0
  99. package/dist/heart/start-of-turn-packet.js +339 -0
  100. package/dist/heart/streaming.js +36 -27
  101. package/dist/heart/sync.js +332 -0
  102. package/dist/heart/target-resolution.js +127 -0
  103. package/dist/heart/tempo.js +93 -0
  104. package/dist/heart/temporal-view.js +41 -0
  105. package/dist/heart/tool-activity-callbacks.js +36 -0
  106. package/dist/heart/tool-description.js +135 -0
  107. package/dist/heart/tool-friction.js +55 -0
  108. package/dist/heart/tool-loop.js +200 -0
  109. package/dist/heart/turn-context.js +358 -0
  110. package/dist/heart/turn-coordinator.js +28 -0
  111. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
  112. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  113. package/dist/heart/{daemon → versioning}/ouro-path-installer.js +78 -35
  114. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  115. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  116. package/dist/heart/{daemon → versioning}/update-checker.js +12 -2
  117. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  118. package/dist/mind/associative-recall.js +135 -66
  119. package/dist/mind/bundle-manifest.js +8 -1
  120. package/dist/mind/context.js +125 -14
  121. package/dist/mind/diary-integrity.js +60 -0
  122. package/dist/mind/{memory.js → diary.js} +84 -96
  123. package/dist/mind/embedding-provider.js +60 -0
  124. package/dist/mind/file-state.js +179 -0
  125. package/dist/mind/first-impressions.js +14 -1
  126. package/dist/mind/friends/channel.js +56 -0
  127. package/dist/mind/friends/group-context.js +144 -0
  128. package/dist/mind/friends/resolver.js +37 -0
  129. package/dist/mind/friends/store-file.js +58 -3
  130. package/dist/mind/friends/trust-explanation.js +74 -0
  131. package/dist/mind/friends/types.js +8 -0
  132. package/dist/mind/journal-index.js +161 -0
  133. package/dist/mind/obligation-steering.js +221 -0
  134. package/dist/mind/pending.js +76 -9
  135. package/dist/mind/prompt.js +922 -109
  136. package/dist/mind/scrutiny.js +173 -0
  137. package/dist/mind/token-estimate.js +8 -12
  138. package/dist/nerves/cli-logging.js +7 -1
  139. package/dist/nerves/coverage/audit.js +1 -1
  140. package/dist/nerves/coverage/file-completeness.js +59 -5
  141. package/dist/nerves/coverage/run-artifacts.js +1 -1
  142. package/dist/nerves/event-buffer.js +111 -0
  143. package/dist/nerves/index.js +224 -4
  144. package/dist/nerves/observation.js +20 -0
  145. package/dist/nerves/redact.js +79 -0
  146. package/dist/nerves/runtime.js +5 -1
  147. package/dist/outlook-ui/assets/index-Ck8agNeO.js +61 -0
  148. package/dist/outlook-ui/assets/index-LwChZTgL.css +1 -0
  149. package/dist/outlook-ui/index.html +15 -0
  150. package/dist/repertoire/ado-client.js +15 -56
  151. package/dist/repertoire/ado-semantic.js +11 -10
  152. package/dist/repertoire/api-client.js +97 -0
  153. package/dist/repertoire/bitwarden-store.js +319 -0
  154. package/dist/repertoire/bundle-templates.js +72 -0
  155. package/dist/repertoire/bw-installer.js +79 -0
  156. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  157. package/dist/repertoire/coding/context-pack.js +330 -0
  158. package/dist/repertoire/coding/feedback.js +197 -30
  159. package/dist/repertoire/coding/manager.js +159 -11
  160. package/dist/repertoire/coding/spawner.js +55 -9
  161. package/dist/repertoire/coding/tools.js +170 -7
  162. package/dist/repertoire/commerce-errors.js +109 -0
  163. package/dist/repertoire/commerce-self-test.js +156 -0
  164. package/dist/repertoire/credential-access.js +527 -0
  165. package/dist/repertoire/duffel-client.js +185 -0
  166. package/dist/repertoire/github-client.js +14 -55
  167. package/dist/repertoire/graph-client.js +11 -52
  168. package/dist/repertoire/guardrails.js +375 -0
  169. package/dist/repertoire/mcp-client.js +255 -0
  170. package/dist/repertoire/mcp-manager.js +305 -0
  171. package/dist/repertoire/mcp-tools.js +63 -0
  172. package/dist/repertoire/shell-sessions.js +133 -0
  173. package/dist/repertoire/skills.js +14 -23
  174. package/dist/repertoire/stripe-client.js +131 -0
  175. package/dist/repertoire/tasks/board.js +43 -5
  176. package/dist/repertoire/tasks/fix.js +182 -0
  177. package/dist/repertoire/tasks/index.js +28 -10
  178. package/dist/repertoire/tasks/lifecycle.js +2 -2
  179. package/dist/repertoire/tasks/parser.js +3 -2
  180. package/dist/repertoire/tasks/scanner.js +194 -37
  181. package/dist/repertoire/tasks/transitions.js +11 -28
  182. package/dist/repertoire/tool-results.js +29 -0
  183. package/dist/repertoire/tools-attachments.js +316 -0
  184. package/dist/repertoire/tools-base.js +45 -771
  185. package/dist/repertoire/tools-bluebubbles.js +94 -0
  186. package/dist/repertoire/tools-bridge.js +141 -0
  187. package/dist/repertoire/tools-bundle.js +984 -0
  188. package/dist/repertoire/tools-config.js +185 -0
  189. package/dist/repertoire/tools-continuity.js +248 -0
  190. package/dist/repertoire/tools-credential.js +182 -0
  191. package/dist/repertoire/tools-files.js +342 -0
  192. package/dist/repertoire/tools-flight.js +224 -0
  193. package/dist/repertoire/tools-flow.js +105 -0
  194. package/dist/repertoire/tools-github.js +1 -7
  195. package/dist/repertoire/tools-memory.js +374 -0
  196. package/dist/repertoire/tools-session.js +739 -0
  197. package/dist/repertoire/tools-shell.js +120 -0
  198. package/dist/repertoire/tools-stripe.js +180 -0
  199. package/dist/repertoire/tools-surface.js +243 -0
  200. package/dist/repertoire/tools-teams.js +12 -62
  201. package/dist/repertoire/tools-travel.js +125 -0
  202. package/dist/repertoire/tools-user-profile.js +144 -0
  203. package/dist/repertoire/tools-vault.js +110 -0
  204. package/dist/repertoire/tools.js +148 -130
  205. package/dist/repertoire/travel-api-client.js +360 -0
  206. package/dist/repertoire/user-profile.js +118 -0
  207. package/dist/repertoire/vault-setup.js +241 -0
  208. package/dist/scripts/claude-code-hook.js +41 -0
  209. package/dist/scripts/claude-code-stop-hook.js +47 -0
  210. package/dist/senses/attention-queue.js +116 -0
  211. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  212. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  213. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +143 -9
  214. package/dist/senses/bluebubbles/entry.js +13 -0
  215. package/dist/senses/bluebubbles/inbound-log.js +113 -0
  216. package/dist/senses/bluebubbles/index.js +1427 -0
  217. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +122 -70
  218. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +43 -12
  219. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +46 -6
  220. package/dist/senses/bluebubbles/replay.js +129 -0
  221. package/dist/senses/bluebubbles/runtime-state.js +109 -0
  222. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +12 -13
  223. package/dist/senses/cli/bracketed-paste.js +82 -0
  224. package/dist/senses/cli/image-paste.js +287 -0
  225. package/dist/senses/cli/image-ref-navigation.js +75 -0
  226. package/dist/senses/cli/ink-app.js +156 -0
  227. package/dist/senses/cli/inline-diff.js +64 -0
  228. package/dist/senses/cli/input-keys.js +174 -0
  229. package/dist/senses/cli/kill-ring.js +86 -0
  230. package/dist/senses/cli/message-list.js +51 -0
  231. package/dist/senses/cli/ouro-tui.js +595 -0
  232. package/dist/senses/cli/spinner-imperative.js +135 -0
  233. package/dist/senses/cli/spinner.js +101 -0
  234. package/dist/senses/cli/status-line.js +60 -0
  235. package/dist/senses/cli/streaming-markdown.js +526 -0
  236. package/dist/senses/cli/tool-display.js +83 -0
  237. package/dist/senses/cli/tool-render.js +85 -0
  238. package/dist/senses/cli/tui-store.js +240 -0
  239. package/dist/senses/cli/virtual-list.js +35 -0
  240. package/dist/senses/cli-entry.js +1 -1
  241. package/dist/senses/cli-layout.js +187 -0
  242. package/dist/senses/cli.js +588 -246
  243. package/dist/senses/commands.js +65 -1
  244. package/dist/senses/continuity.js +94 -0
  245. package/dist/senses/habit-turn-message.js +108 -0
  246. package/dist/senses/inner-dialog-worker.js +112 -19
  247. package/dist/senses/inner-dialog.js +633 -86
  248. package/dist/senses/pipeline.js +560 -0
  249. package/dist/senses/shared-turn.js +195 -0
  250. package/dist/senses/surface-tool.js +68 -0
  251. package/dist/senses/teams.js +664 -165
  252. package/dist/senses/trust-gate.js +112 -2
  253. package/package.json +14 -7
  254. package/skills/agent-commerce.md +106 -0
  255. package/skills/browser-navigation.md +110 -0
  256. package/skills/commerce-setup-guide.md +116 -0
  257. package/skills/commerce-setup.md +84 -0
  258. package/skills/configure-dev-tools.md +81 -0
  259. package/skills/travel-planning.md +138 -0
  260. package/dist/heart/daemon/subagent-installer.js +0 -134
  261. package/dist/senses/bluebubbles-entry.js +0 -11
  262. package/dist/senses/bluebubbles.js +0 -449
  263. package/dist/senses/debug-activity.js +0 -108
  264. package/subagents/README.md +0 -73
  265. package/subagents/work-doer.md +0 -235
  266. package/subagents/work-merger.md +0 -618
  267. package/subagents/work-planner.md +0 -382
  268. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  269. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  270. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  271. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  272. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  273. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  274. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  275. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  276. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  277. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  278. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  279. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +0 -0
  280. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  281. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  282. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  283. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  284. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,172 @@
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.listSessionActivity = listSessionActivity;
37
+ exports.findFreshestFriendSession = findFreshestFriendSession;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const runtime_1 = require("../nerves/runtime");
41
+ const config_1 = require("./config");
42
+ const DEFAULT_ACTIVE_THRESHOLD_MS = 24 * 60 * 60 * 1000;
43
+ function activityPriority(source) {
44
+ return source === "friend-facing" ? 0 : 1;
45
+ }
46
+ function resolveFriendName(friendId, friendsDir, agentName) {
47
+ if (friendId === "self")
48
+ return agentName;
49
+ try {
50
+ const raw = fs.readFileSync(path.join(friendsDir, `${friendId}.json`), "utf-8");
51
+ const parsed = JSON.parse(raw);
52
+ return parsed.name ?? friendId;
53
+ }
54
+ catch {
55
+ return friendId;
56
+ }
57
+ }
58
+ function parseFriendActivity(sessionPath) {
59
+ let mtimeMs;
60
+ try {
61
+ mtimeMs = fs.statSync(sessionPath).mtimeMs;
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ try {
67
+ const raw = fs.readFileSync(sessionPath, "utf-8");
68
+ const parsed = JSON.parse(raw);
69
+ const explicit = parsed?.state?.lastFriendActivityAt;
70
+ if (typeof explicit === "string") {
71
+ const parsedMs = Date.parse(explicit);
72
+ if (Number.isFinite(parsedMs)) {
73
+ return {
74
+ lastActivityMs: parsedMs,
75
+ lastActivityAt: new Date(parsedMs).toISOString(),
76
+ activitySource: "friend-facing",
77
+ };
78
+ }
79
+ }
80
+ }
81
+ catch {
82
+ // fall back to file mtime below
83
+ }
84
+ return {
85
+ lastActivityMs: mtimeMs,
86
+ lastActivityAt: new Date(mtimeMs).toISOString(),
87
+ activitySource: "mtime-fallback",
88
+ };
89
+ }
90
+ function listSessionActivity(query) {
91
+ const { sessionsDir, friendsDir, agentName, activeThresholdMs = DEFAULT_ACTIVE_THRESHOLD_MS, nowMs = Date.now(), currentSession = null, } = query;
92
+ (0, runtime_1.emitNervesEvent)({
93
+ component: "daemon",
94
+ event: "daemon.session_activity_scan",
95
+ message: "scanning session activity",
96
+ meta: {
97
+ sessionsDir,
98
+ currentSession: currentSession ? `${currentSession.friendId}/${currentSession.channel}/${currentSession.key}` : null,
99
+ },
100
+ });
101
+ if (!fs.existsSync(sessionsDir))
102
+ return [];
103
+ const results = [];
104
+ let friendDirs;
105
+ try {
106
+ friendDirs = fs.readdirSync(sessionsDir);
107
+ }
108
+ catch {
109
+ return [];
110
+ }
111
+ for (const friendId of friendDirs) {
112
+ const friendPath = path.join(sessionsDir, friendId);
113
+ let channels;
114
+ try {
115
+ channels = fs.readdirSync(friendPath);
116
+ }
117
+ catch {
118
+ continue;
119
+ }
120
+ for (const channel of channels) {
121
+ const channelPath = path.join(friendPath, channel);
122
+ let keys;
123
+ try {
124
+ keys = fs.readdirSync(channelPath);
125
+ }
126
+ catch {
127
+ continue;
128
+ }
129
+ for (const keyFile of keys) {
130
+ if (!keyFile.endsWith(".json"))
131
+ continue;
132
+ const key = keyFile.replace(/\.json$/, "");
133
+ // Compare with sanitizeKey on both sides — session keys from the filesystem
134
+ // are already sanitized (colons → underscores), but the canonical key from
135
+ // the pipeline may still have colons (e.g. "chat:any" vs "chat_any").
136
+ if (currentSession && friendId === currentSession.friendId && channel === currentSession.channel && (0, config_1.sanitizeKey)(key) === (0, config_1.sanitizeKey)(currentSession.key)) {
137
+ continue;
138
+ }
139
+ const sessionPath = path.join(channelPath, keyFile);
140
+ const activity = parseFriendActivity(sessionPath);
141
+ if (!activity)
142
+ continue;
143
+ if (nowMs - activity.lastActivityMs > activeThresholdMs)
144
+ continue;
145
+ results.push({
146
+ friendId,
147
+ friendName: resolveFriendName(friendId, friendsDir, agentName),
148
+ channel,
149
+ key,
150
+ sessionPath,
151
+ lastActivityAt: activity.lastActivityAt,
152
+ lastActivityMs: activity.lastActivityMs,
153
+ activitySource: activity.activitySource,
154
+ });
155
+ }
156
+ }
157
+ }
158
+ return results.sort((a, b) => {
159
+ const sourceDiff = activityPriority(a.activitySource) - activityPriority(b.activitySource);
160
+ if (sourceDiff !== 0)
161
+ return sourceDiff;
162
+ return b.lastActivityMs - a.lastActivityMs;
163
+ });
164
+ }
165
+ function findFreshestFriendSession(query) {
166
+ const { activeOnly = false, activeThresholdMs = DEFAULT_ACTIVE_THRESHOLD_MS, nowMs, ...rest } = query;
167
+ const currentSession = rest.currentSession ?? null;
168
+ const all = activeOnly
169
+ ? listSessionActivity({ ...rest, activeThresholdMs, nowMs, currentSession })
170
+ : listSessionActivity({ ...rest, activeThresholdMs: Number.MAX_SAFE_INTEGER, nowMs, currentSession });
171
+ return all.find((entry) => entry.friendId === query.friendId) ?? null;
172
+ }
@@ -0,0 +1,216 @@
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.recallSession = recallSession;
37
+ exports.searchSessionTranscript = searchSessionTranscript;
38
+ const fs = __importStar(require("fs"));
39
+ const runtime_1 = require("../nerves/runtime");
40
+ function normalizeContent(content) {
41
+ if (typeof content === "string")
42
+ return content;
43
+ if (!Array.isArray(content))
44
+ return "";
45
+ return content
46
+ .map((part) => (part && typeof part === "object" && "type" in part && part.type === "text" && "text" in part
47
+ ? String(part.text ?? "")
48
+ : ""))
49
+ .filter((text) => text.length > 0)
50
+ .join("");
51
+ }
52
+ function normalizeSessionMessages(messages) {
53
+ if (!Array.isArray(messages))
54
+ return [];
55
+ return messages
56
+ .map((message) => {
57
+ const record = message && typeof message === "object" ? message : {};
58
+ return {
59
+ role: typeof record.role === "string" ? record.role : "",
60
+ content: normalizeContent(record.content),
61
+ };
62
+ })
63
+ .filter((message) => message.role !== "system" && message.content.length > 0);
64
+ }
65
+ function buildSummaryInstruction(friendId, channel, trustLevel) {
66
+ if (friendId === "self" && channel === "inner") {
67
+ return "summarize this session transcript fully and transparently. this is my own inner dialog — include all details, decisions, and reasoning.";
68
+ }
69
+ return `summarize this session transcript. the person asking has trust level: ${trustLevel}. family=full transparency, friend=share work and general topics but protect other people's identities, acquaintance=very guarded minimal disclosure.`;
70
+ }
71
+ function clip(text, limit = 160) {
72
+ const compact = text.replace(/\s+/g, " ").trim();
73
+ return compact.length > limit ? compact.slice(0, limit - 1) + "…" : compact;
74
+ }
75
+ function buildSnapshot(summary, tailMessages) {
76
+ const lines = [`recent focus: ${clip(summary, 240)}`];
77
+ const latestUser = [...tailMessages].reverse().find((message) => message.role === "user")?.content;
78
+ const latestAssistant = [...tailMessages].reverse().find((message) => message.role === "assistant")?.content;
79
+ if (latestUser) {
80
+ lines.push(`latest user: ${clip(latestUser)}`);
81
+ }
82
+ if (latestAssistant) {
83
+ lines.push(`latest assistant: ${clip(latestAssistant)}`);
84
+ }
85
+ return lines.join("\n");
86
+ }
87
+ function buildSearchSnapshot(query, messages, includeLatestTurn = true) {
88
+ const lines = [`history query: "${clip(query, 120)}"`];
89
+ if (!includeLatestTurn) {
90
+ return lines.join("\n");
91
+ }
92
+ const latestUser = [...messages].reverse().find((message) => message.role === "user")?.content;
93
+ const latestAssistant = [...messages].reverse().find((message) => message.role === "assistant")?.content;
94
+ if (latestUser) {
95
+ lines.push(`latest user: ${clip(latestUser)}`);
96
+ }
97
+ if (latestAssistant) {
98
+ lines.push(`latest assistant: ${clip(latestAssistant)}`);
99
+ }
100
+ return lines.join("\n");
101
+ }
102
+ function buildSearchExcerpts(messages, query, maxMatches) {
103
+ const normalizedQuery = query.trim().toLowerCase();
104
+ if (!normalizedQuery)
105
+ return [];
106
+ const candidates = [];
107
+ let lastMatchIndex = -2;
108
+ for (let i = 0; i < messages.length; i++) {
109
+ if (!messages[i].content.toLowerCase().includes(normalizedQuery))
110
+ continue;
111
+ if (i <= lastMatchIndex + 1)
112
+ continue;
113
+ lastMatchIndex = i;
114
+ const start = Math.max(0, i - 1);
115
+ const end = Math.min(messages.length, i + 2);
116
+ const excerpt = messages
117
+ .slice(start, end)
118
+ .map((message) => `[${message.role}] ${clip(message.content, 200)}`)
119
+ .join("\n");
120
+ const score = messages
121
+ .slice(start, end)
122
+ .filter((message) => message.content.toLowerCase().includes(normalizedQuery))
123
+ .length;
124
+ candidates.push({ excerpt, score, index: i });
125
+ }
126
+ const seen = new Set();
127
+ return candidates
128
+ .sort((a, b) => b.score - a.score || a.index - b.index)
129
+ .filter((candidate) => {
130
+ if (seen.has(candidate.excerpt))
131
+ return false;
132
+ seen.add(candidate.excerpt);
133
+ return true;
134
+ })
135
+ .slice(0, maxMatches)
136
+ .map((candidate) => candidate.excerpt);
137
+ }
138
+ async function recallSession(options) {
139
+ (0, runtime_1.emitNervesEvent)({
140
+ component: "daemon",
141
+ event: "daemon.session_recall",
142
+ message: "recalling session transcript tail",
143
+ meta: {
144
+ friendId: options.friendId,
145
+ channel: options.channel,
146
+ key: options.key,
147
+ messageCount: options.messageCount,
148
+ },
149
+ });
150
+ let raw;
151
+ try {
152
+ raw = fs.readFileSync(options.sessionPath, "utf-8");
153
+ }
154
+ catch {
155
+ return { kind: "missing" };
156
+ }
157
+ const parsed = JSON.parse(raw);
158
+ const tailMessages = normalizeSessionMessages(parsed.messages).slice(-options.messageCount);
159
+ if (tailMessages.length === 0) {
160
+ return { kind: "empty" };
161
+ }
162
+ const transcript = tailMessages
163
+ .map((message) => `[${message.role}] ${message.content}`)
164
+ .join("\n");
165
+ const summary = options.summarize
166
+ ? await options.summarize(transcript, buildSummaryInstruction(options.friendId, options.channel, options.trustLevel ?? "family"))
167
+ : transcript;
168
+ return {
169
+ kind: "ok",
170
+ transcript,
171
+ summary,
172
+ snapshot: buildSnapshot(summary, tailMessages),
173
+ tailMessages,
174
+ };
175
+ }
176
+ async function searchSessionTranscript(options) {
177
+ (0, runtime_1.emitNervesEvent)({
178
+ component: "daemon",
179
+ event: "daemon.session_search",
180
+ message: "searching session transcript",
181
+ meta: {
182
+ friendId: options.friendId,
183
+ channel: options.channel,
184
+ key: options.key,
185
+ query: options.query,
186
+ maxMatches: options.maxMatches ?? 5,
187
+ },
188
+ });
189
+ let raw;
190
+ try {
191
+ raw = fs.readFileSync(options.sessionPath, "utf-8");
192
+ }
193
+ catch {
194
+ return { kind: "missing" };
195
+ }
196
+ const parsed = JSON.parse(raw);
197
+ const messages = normalizeSessionMessages(parsed.messages);
198
+ if (messages.length === 0) {
199
+ return { kind: "empty" };
200
+ }
201
+ const query = options.query.trim();
202
+ const matches = buildSearchExcerpts(messages, query, options.maxMatches ?? 5);
203
+ if (matches.length === 0) {
204
+ return {
205
+ kind: "no_match",
206
+ query,
207
+ snapshot: buildSearchSnapshot(query, messages),
208
+ };
209
+ }
210
+ return {
211
+ kind: "ok",
212
+ query,
213
+ snapshot: buildSearchSnapshot(query, messages, false),
214
+ matches,
215
+ };
216
+ }