@ouro.bot/cli 0.1.0-alpha.27 → 0.1.0-alpha.271

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 (265) hide show
  1. package/README.md +187 -191
  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 +1637 -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/presence.js +185 -0
  12. package/dist/heart/active-work.js +832 -0
  13. package/dist/heart/agent-entry.js +37 -2
  14. package/dist/heart/auth/auth-flow.js +447 -0
  15. package/dist/heart/bridges/manager.js +358 -0
  16. package/dist/heart/bridges/state-machine.js +135 -0
  17. package/dist/heart/bridges/store.js +123 -0
  18. package/dist/heart/commitments.js +111 -0
  19. package/dist/heart/config-registry.js +304 -0
  20. package/dist/heart/config.js +63 -30
  21. package/dist/heart/core.js +644 -196
  22. package/dist/heart/cross-chat-delivery.js +131 -0
  23. package/dist/heart/daemon/agent-config-check.js +149 -0
  24. package/dist/heart/daemon/agent-discovery.js +79 -3
  25. package/dist/heart/daemon/agent-service.js +360 -0
  26. package/dist/heart/daemon/cadence.js +70 -0
  27. package/dist/heart/daemon/cli-defaults.js +557 -0
  28. package/dist/heart/daemon/cli-exec.js +1877 -0
  29. package/dist/heart/daemon/cli-parse.js +759 -0
  30. package/dist/heart/daemon/cli-render.js +503 -0
  31. package/dist/heart/daemon/cli-types.js +8 -0
  32. package/dist/heart/daemon/daemon-cli.js +29 -1155
  33. package/dist/heart/daemon/daemon-entry.js +214 -3
  34. package/dist/heart/daemon/daemon-health.js +136 -0
  35. package/dist/heart/daemon/daemon-runtime-sync.js +153 -12
  36. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  37. package/dist/heart/daemon/daemon.js +664 -57
  38. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  39. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  40. package/dist/heart/daemon/inner-status.js +89 -0
  41. package/dist/heart/daemon/launchd.js +39 -8
  42. package/dist/heart/daemon/log-tailer.js +4 -3
  43. package/dist/heart/daemon/message-router.js +17 -8
  44. package/dist/heart/daemon/os-cron-deps.js +134 -0
  45. package/dist/heart/daemon/ouro-bot-entry.js +1 -1
  46. package/dist/heart/daemon/process-manager.js +123 -0
  47. package/dist/heart/daemon/run-hooks.js +2 -0
  48. package/dist/heart/daemon/runtime-logging.js +58 -15
  49. package/dist/heart/daemon/runtime-metadata.js +101 -0
  50. package/dist/heart/daemon/runtime-mode.js +67 -0
  51. package/dist/heart/daemon/safe-mode.js +161 -0
  52. package/dist/heart/daemon/sense-manager.js +72 -3
  53. package/dist/heart/daemon/session-id-resolver.js +131 -0
  54. package/dist/heart/daemon/skill-management-installer.js +94 -0
  55. package/dist/heart/daemon/socket-client.js +307 -0
  56. package/dist/heart/daemon/task-scheduler.js +3 -25
  57. package/dist/heart/daemon/thoughts.js +510 -0
  58. package/dist/heart/delegation.js +62 -0
  59. package/dist/heart/habits/habit-migration.js +181 -0
  60. package/dist/heart/habits/habit-parser.js +119 -0
  61. package/dist/heart/habits/habit-scheduler.js +371 -0
  62. package/dist/heart/{daemon → hatch}/hatch-flow.js +30 -120
  63. package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
  64. package/dist/heart/{daemon → hatch}/specialist-prompt.js +10 -7
  65. package/dist/heart/{daemon → hatch}/specialist-tools.js +49 -3
  66. package/dist/heart/identity.js +160 -58
  67. package/dist/heart/kicks.js +2 -20
  68. package/dist/heart/mcp/mcp-server.js +653 -0
  69. package/dist/heart/migrate-config.js +127 -0
  70. package/dist/heart/model-capabilities.js +59 -0
  71. package/dist/heart/outlook/outlook-http.js +439 -0
  72. package/dist/heart/outlook/outlook-read.js +1618 -0
  73. package/dist/heart/outlook/outlook-render.js +1032 -0
  74. package/dist/heart/outlook/outlook-types.js +7 -0
  75. package/dist/heart/outlook/outlook-view.js +194 -0
  76. package/dist/heart/progress-story.js +42 -0
  77. package/dist/heart/provider-failover.js +88 -0
  78. package/dist/heart/provider-ping.js +162 -0
  79. package/dist/heart/providers/anthropic-token.js +163 -0
  80. package/dist/heart/providers/anthropic.js +169 -46
  81. package/dist/heart/providers/azure.js +98 -11
  82. package/dist/heart/providers/error-classification.js +63 -0
  83. package/dist/heart/providers/github-copilot.js +136 -0
  84. package/dist/heart/providers/minimax-vlm.js +189 -0
  85. package/dist/heart/providers/minimax.js +23 -5
  86. package/dist/heart/providers/openai-codex.js +33 -22
  87. package/dist/heart/session-activity.js +172 -0
  88. package/dist/heart/session-recall.js +216 -0
  89. package/dist/heart/start-of-turn-packet.js +330 -0
  90. package/dist/heart/streaming.js +36 -27
  91. package/dist/heart/sync.js +277 -0
  92. package/dist/heart/target-resolution.js +127 -0
  93. package/dist/heart/tempo.js +93 -0
  94. package/dist/heart/temporal-view.js +41 -0
  95. package/dist/heart/tool-activity-callbacks.js +36 -0
  96. package/dist/heart/tool-description.js +135 -0
  97. package/dist/heart/tool-loop.js +200 -0
  98. package/dist/heart/turn-context.js +358 -0
  99. package/dist/heart/turn-coordinator.js +28 -0
  100. package/dist/heart/versioning/ouro-bot-global-installer.js +128 -0
  101. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  102. package/dist/heart/{daemon → versioning}/ouro-path-installer.js +78 -35
  103. package/dist/heart/versioning/ouro-version-manager.js +171 -0
  104. package/dist/heart/{daemon → versioning}/staged-restart.js +30 -6
  105. package/dist/heart/{daemon → versioning}/update-checker.js +12 -2
  106. package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +41 -3
  107. package/dist/mind/associative-recall.js +126 -66
  108. package/dist/mind/bundle-manifest.js +8 -1
  109. package/dist/mind/context.js +125 -14
  110. package/dist/mind/{memory.js → diary.js} +68 -96
  111. package/dist/mind/embedding-provider.js +60 -0
  112. package/dist/mind/file-state.js +179 -0
  113. package/dist/mind/first-impressions.js +16 -2
  114. package/dist/mind/friends/channel.js +56 -0
  115. package/dist/mind/friends/group-context.js +144 -0
  116. package/dist/mind/friends/resolver.js +37 -0
  117. package/dist/mind/friends/store-file.js +58 -3
  118. package/dist/mind/friends/trust-explanation.js +74 -0
  119. package/dist/mind/friends/types.js +8 -0
  120. package/dist/mind/journal-index.js +161 -0
  121. package/dist/mind/obligation-steering.js +221 -0
  122. package/dist/mind/pending.js +76 -9
  123. package/dist/mind/prompt.js +777 -109
  124. package/dist/mind/scrutiny.js +173 -0
  125. package/dist/mind/token-estimate.js +8 -12
  126. package/dist/nerves/coverage/audit.js +1 -1
  127. package/dist/nerves/coverage/file-completeness.js +50 -5
  128. package/dist/nerves/coverage/run-artifacts.js +1 -1
  129. package/dist/nerves/event-buffer.js +111 -0
  130. package/dist/nerves/index.js +64 -4
  131. package/dist/nerves/observation.js +20 -0
  132. package/dist/nerves/runtime.js +5 -1
  133. package/dist/outlook-ui/assets/index-Ck8agNeO.js +61 -0
  134. package/dist/outlook-ui/assets/index-LwChZTgL.css +1 -0
  135. package/dist/outlook-ui/index.html +15 -0
  136. package/dist/repertoire/ado-client.js +15 -56
  137. package/dist/repertoire/ado-semantic.js +11 -10
  138. package/dist/repertoire/api-client.js +97 -0
  139. package/dist/repertoire/bitwarden-store.js +319 -0
  140. package/dist/repertoire/bw-installer.js +79 -0
  141. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  142. package/dist/repertoire/coding/context-pack.js +330 -0
  143. package/dist/repertoire/coding/feedback.js +197 -30
  144. package/dist/repertoire/coding/manager.js +149 -2
  145. package/dist/repertoire/coding/spawner.js +55 -9
  146. package/dist/repertoire/coding/tools.js +170 -7
  147. package/dist/repertoire/commerce-errors.js +109 -0
  148. package/dist/repertoire/commerce-self-test.js +156 -0
  149. package/dist/repertoire/credential-access.js +515 -0
  150. package/dist/repertoire/duffel-client.js +185 -0
  151. package/dist/repertoire/github-client.js +14 -55
  152. package/dist/repertoire/graph-client.js +11 -52
  153. package/dist/repertoire/guardrails.js +369 -0
  154. package/dist/repertoire/mcp-client.js +255 -0
  155. package/dist/repertoire/mcp-manager.js +305 -0
  156. package/dist/repertoire/mcp-tools.js +63 -0
  157. package/dist/repertoire/shell-sessions.js +133 -0
  158. package/dist/repertoire/skills.js +14 -23
  159. package/dist/repertoire/stripe-client.js +131 -0
  160. package/dist/repertoire/tasks/board.js +43 -5
  161. package/dist/repertoire/tasks/fix.js +182 -0
  162. package/dist/repertoire/tasks/index.js +28 -10
  163. package/dist/repertoire/tasks/lifecycle.js +2 -2
  164. package/dist/repertoire/tasks/parser.js +3 -2
  165. package/dist/repertoire/tasks/scanner.js +194 -37
  166. package/dist/repertoire/tasks/transitions.js +11 -28
  167. package/dist/repertoire/tools-base.js +43 -771
  168. package/dist/repertoire/tools-bluebubbles.js +201 -0
  169. package/dist/repertoire/tools-bridge.js +141 -0
  170. package/dist/repertoire/tools-config.js +185 -0
  171. package/dist/repertoire/tools-continuity.js +248 -0
  172. package/dist/repertoire/tools-credential.js +182 -0
  173. package/dist/repertoire/tools-files.js +342 -0
  174. package/dist/repertoire/tools-flight.js +224 -0
  175. package/dist/repertoire/tools-flow.js +62 -0
  176. package/dist/repertoire/tools-github.js +1 -7
  177. package/dist/repertoire/tools-memory.js +347 -0
  178. package/dist/repertoire/tools-session.js +739 -0
  179. package/dist/repertoire/tools-shell.js +120 -0
  180. package/dist/repertoire/tools-stripe.js +180 -0
  181. package/dist/repertoire/tools-surface.js +243 -0
  182. package/dist/repertoire/tools-teams.js +12 -62
  183. package/dist/repertoire/tools-travel.js +125 -0
  184. package/dist/repertoire/tools-user-profile.js +144 -0
  185. package/dist/repertoire/tools-vault.js +110 -0
  186. package/dist/repertoire/tools.js +155 -130
  187. package/dist/repertoire/travel-api-client.js +360 -0
  188. package/dist/repertoire/user-profile.js +118 -0
  189. package/dist/repertoire/vault-setup.js +241 -0
  190. package/dist/scripts/claude-code-hook.js +41 -0
  191. package/dist/scripts/claude-code-stop-hook.js +47 -0
  192. package/dist/senses/attention-queue.js +97 -0
  193. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  194. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +145 -10
  195. package/dist/senses/bluebubbles/entry.js +13 -0
  196. package/dist/senses/bluebubbles/inbound-log.js +110 -0
  197. package/dist/senses/bluebubbles/index.js +1410 -0
  198. package/dist/senses/bluebubbles/media.js +455 -0
  199. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +20 -5
  200. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +46 -6
  201. package/dist/senses/bluebubbles/runtime-state.js +109 -0
  202. package/dist/senses/bluebubbles/session-cleanup.js +72 -0
  203. package/dist/senses/cli/bracketed-paste.js +82 -0
  204. package/dist/senses/cli/image-paste.js +211 -0
  205. package/dist/senses/cli/image-ref-navigation.js +75 -0
  206. package/dist/senses/cli/ink-app.js +156 -0
  207. package/dist/senses/cli/inline-diff.js +64 -0
  208. package/dist/senses/cli/input-keys.js +174 -0
  209. package/dist/senses/cli/kill-ring.js +86 -0
  210. package/dist/senses/cli/message-list.js +51 -0
  211. package/dist/senses/cli/ouro-tui.js +578 -0
  212. package/dist/senses/cli/spinner-imperative.js +135 -0
  213. package/dist/senses/cli/spinner.js +101 -0
  214. package/dist/senses/cli/status-line.js +60 -0
  215. package/dist/senses/cli/streaming-markdown.js +526 -0
  216. package/dist/senses/cli/tool-display.js +83 -0
  217. package/dist/senses/cli/tool-render.js +85 -0
  218. package/dist/senses/cli/tui-store.js +240 -0
  219. package/dist/senses/cli/virtual-list.js +35 -0
  220. package/dist/senses/cli-entry.js +1 -1
  221. package/dist/senses/cli-layout.js +187 -0
  222. package/dist/senses/cli.js +569 -246
  223. package/dist/senses/commands.js +65 -1
  224. package/dist/senses/continuity.js +94 -0
  225. package/dist/senses/habit-turn-message.js +108 -0
  226. package/dist/senses/inner-dialog-worker.js +112 -19
  227. package/dist/senses/inner-dialog.js +593 -85
  228. package/dist/senses/pipeline.js +552 -0
  229. package/dist/senses/shared-turn.js +199 -0
  230. package/dist/senses/surface-tool.js +68 -0
  231. package/dist/senses/teams.js +664 -165
  232. package/dist/senses/trust-gate.js +112 -2
  233. package/package.json +14 -7
  234. package/skills/agent-commerce.md +106 -0
  235. package/skills/browser-navigation.md +110 -0
  236. package/skills/commerce-setup-guide.md +116 -0
  237. package/skills/commerce-setup.md +84 -0
  238. package/skills/configure-dev-tools.md +81 -0
  239. package/skills/travel-planning.md +138 -0
  240. package/dist/heart/daemon/subagent-installer.js +0 -134
  241. package/dist/senses/bluebubbles-entry.js +0 -11
  242. package/dist/senses/bluebubbles-media.js +0 -244
  243. package/dist/senses/bluebubbles.js +0 -421
  244. package/dist/senses/debug-activity.js +0 -108
  245. package/subagents/README.md +0 -73
  246. package/subagents/work-doer.md +0 -235
  247. package/subagents/work-merger.md +0 -618
  248. package/subagents/work-planner.md +0 -382
  249. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  250. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  251. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  252. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  253. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  254. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  255. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  256. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  257. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  258. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  259. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  260. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +0 -0
  261. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  262. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  263. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  264. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  265. /package/dist/heart/{daemon → versioning}/update-hooks.js +0 -0
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.humanReadableToolDescription = humanReadableToolDescription;
4
+ const runtime_1 = require("../nerves/runtime");
5
+ function basename(filePath) {
6
+ const idx = filePath.lastIndexOf("/");
7
+ return idx >= 0 ? filePath.slice(idx + 1) : filePath;
8
+ }
9
+ function truncate(text, max) {
10
+ if (text.length <= max)
11
+ return text;
12
+ // Cut at last space before maxLen to avoid mid-word truncation
13
+ const slice = text.slice(0, max - 1);
14
+ const lastSpace = slice.lastIndexOf(" ");
15
+ if (lastSpace > 0)
16
+ return text.slice(0, lastSpace) + "\u2026";
17
+ // No space found (single long word) — hard truncate
18
+ return slice + "\u2026";
19
+ }
20
+ const TOOL_DESCRIPTIONS = {
21
+ // File operations
22
+ shell: (args) => {
23
+ const cmd = args.command;
24
+ if (!cmd)
25
+ return "running a command...";
26
+ return `running ${truncate(cmd, 50)}...`;
27
+ },
28
+ read_file: (args) => {
29
+ const fp = args.path || args.file_path;
30
+ if (!fp)
31
+ return "reading a file...";
32
+ return `reading ${basename(fp)}...`;
33
+ },
34
+ write_file: (args) => {
35
+ const fp = args.path || args.file_path;
36
+ if (!fp)
37
+ return "writing a file...";
38
+ return `writing ${basename(fp)}...`;
39
+ },
40
+ edit_file: (args) => {
41
+ const fp = args.path || args.file_path;
42
+ if (!fp)
43
+ return "editing a file...";
44
+ return `editing ${basename(fp)}...`;
45
+ },
46
+ glob: (args) => {
47
+ const p = args.pattern;
48
+ if (!p)
49
+ return "searching for files...";
50
+ return `searching for ${truncate(p, 40)}...`;
51
+ },
52
+ grep: (args) => {
53
+ const p = args.pattern;
54
+ if (!p)
55
+ return "searching code...";
56
+ return `searching code for '${truncate(p, 40)}'...`;
57
+ },
58
+ // Memory and knowledge
59
+ recall: (args) => {
60
+ const q = args.query;
61
+ if (!q)
62
+ return "searching memory...";
63
+ return `searching memory for '${truncate(q, 40)}'...`;
64
+ },
65
+ diary_write: (args) => {
66
+ const about = args.about;
67
+ return about ? `noting something about ${truncate(about, 30)}...` : "noting something down...";
68
+ },
69
+ save_friend_note: () => "making a note about you...",
70
+ get_friend_note: () => "checking my notes...",
71
+ load_skill: (args) => {
72
+ const name = args.name || args.skill;
73
+ return name ? `loading ${name} skill...` : "loading a skill...";
74
+ },
75
+ // Session and context
76
+ query_session: (args) => {
77
+ const mode = args.mode;
78
+ if (mode === "search")
79
+ return `searching session for '${truncate(args.query || "", 30)}'...`;
80
+ if (mode === "status")
81
+ return "checking inner dialog status...";
82
+ return "checking session history...";
83
+ },
84
+ web_search: (args) => {
85
+ const q = args.query;
86
+ return q ? `searching the web for '${truncate(q, 35)}'...` : "searching the web...";
87
+ },
88
+ coding_spawn: (args) => {
89
+ const runner = args.runner;
90
+ return runner ? `starting ${runner} coding session...` : "starting coding session...";
91
+ },
92
+ coding_status: () => "checking coding sessions...",
93
+ coding_tail: () => "reading coding output...",
94
+ coding_kill: () => "stopping coding session...",
95
+ bridge_manage: () => "managing conversation bridge...",
96
+ // Communication
97
+ send_message: (args) => {
98
+ const to = args.to;
99
+ return to ? `sending a message to ${to}...` : "sending a message...";
100
+ },
101
+ surface: () => "sharing a thought...",
102
+ // Metacognitive (agent's inner life)
103
+ ponder: (args) => {
104
+ const thought = args.thought;
105
+ return thought ? `thinking about ${truncate(thought, 40)}...` : "thinking deeper...";
106
+ },
107
+ observe: () => null,
108
+ claude: () => "reasoning...",
109
+ set_reasoning_effort: (args) => {
110
+ const level = args.level;
111
+ return level ? `setting thinking depth to ${level}...` : "adjusting thinking depth...";
112
+ },
113
+ // Hidden — these ARE the response or end-of-turn
114
+ settle: () => null,
115
+ rest: () => null,
116
+ descend: () => null,
117
+ };
118
+ function humanReadableToolDescription(name, args) {
119
+ (0, runtime_1.emitNervesEvent)({
120
+ component: "engine",
121
+ event: "engine.tool_description",
122
+ message: "generated human-readable tool description",
123
+ meta: { tool: name },
124
+ });
125
+ const builder = TOOL_DESCRIPTIONS[name];
126
+ if (builder)
127
+ return builder(args);
128
+ // MCP tools: mcp__server__toolname — extract last segment
129
+ if (name.startsWith("mcp__")) {
130
+ const parts = name.split("__");
131
+ const toolName = parts[parts.length - 1];
132
+ return `using ${toolName}...`;
133
+ }
134
+ return `using ${name}...`;
135
+ }
@@ -0,0 +1,200 @@
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.GLOBAL_CIRCUIT_BREAKER_LIMIT = exports.PING_PONG_WINDOW = exports.GENERIC_REPEAT_LIMIT = exports.POLL_NO_PROGRESS_LIMIT = exports.TOOL_LOOP_HISTORY_LIMIT = void 0;
37
+ exports.createToolLoopState = createToolLoopState;
38
+ exports.recordToolOutcome = recordToolOutcome;
39
+ exports.detectToolLoop = detectToolLoop;
40
+ const crypto = __importStar(require("crypto"));
41
+ const runtime_1 = require("../nerves/runtime");
42
+ exports.TOOL_LOOP_HISTORY_LIMIT = 30;
43
+ exports.POLL_NO_PROGRESS_LIMIT = 3;
44
+ exports.GENERIC_REPEAT_LIMIT = 4;
45
+ exports.PING_PONG_WINDOW = 6;
46
+ exports.GLOBAL_CIRCUIT_BREAKER_LIMIT = 24;
47
+ function stableStringify(value) {
48
+ if (value === null || typeof value !== "object") {
49
+ return JSON.stringify(value);
50
+ }
51
+ /* v8 ignore next -- stableStringify currently receives only objects/strings from normalized loop inputs @preserve */
52
+ if (Array.isArray(value)) {
53
+ return `[${value.map((entry) => stableStringify(entry)).join(",")}]`;
54
+ }
55
+ const record = value;
56
+ return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`).join(",")}}`;
57
+ }
58
+ function digest(value) {
59
+ return crypto.createHash("sha256").update(stableStringify(value)).digest("hex");
60
+ }
61
+ function normalizeArgs(toolName, args) {
62
+ if (toolName === "query_active_work") {
63
+ return { toolName };
64
+ }
65
+ if (toolName === "coding_status" || toolName === "coding_tail") {
66
+ return {
67
+ toolName,
68
+ sessionId: args.sessionId ?? "",
69
+ };
70
+ }
71
+ if (toolName === "query_session") {
72
+ return {
73
+ toolName,
74
+ mode: args.mode ?? "",
75
+ friendId: args.friendId ?? "",
76
+ channel: args.channel ?? "",
77
+ key: args.key ?? "",
78
+ query: args.query ?? "",
79
+ };
80
+ }
81
+ return {
82
+ toolName,
83
+ args,
84
+ };
85
+ }
86
+ function normalizeOutcome(result, success) {
87
+ return {
88
+ success,
89
+ result: result.replace(/\s+/g, " ").trim(),
90
+ };
91
+ }
92
+ function isKnownPollTool(toolName, args) {
93
+ return toolName === "query_active_work"
94
+ || toolName === "coding_status"
95
+ || toolName === "coding_tail"
96
+ || (toolName === "query_session" && (args.mode ?? "").trim() === "status");
97
+ }
98
+ function emitDetection(detector, toolName, count, message, pairedToolName) {
99
+ (0, runtime_1.emitNervesEvent)({
100
+ level: "warn",
101
+ component: "engine",
102
+ event: "engine.tool_loop_detected",
103
+ message: "tool loop guard detected repeated non-progress work",
104
+ meta: {
105
+ detector,
106
+ toolName,
107
+ count,
108
+ pairedToolName: pairedToolName ?? null,
109
+ },
110
+ });
111
+ return {
112
+ stuck: true,
113
+ detector,
114
+ count,
115
+ message,
116
+ pairedToolName,
117
+ };
118
+ }
119
+ function countTrailingRepeats(history, toolName, callHash) {
120
+ let count = 0;
121
+ let outcomeHash;
122
+ for (let index = history.length - 1; index >= 0; index--) {
123
+ const record = history[index];
124
+ if (record.toolName !== toolName || record.callHash !== callHash) {
125
+ break;
126
+ }
127
+ if (!outcomeHash) {
128
+ outcomeHash = record.outcomeHash;
129
+ }
130
+ if (record.outcomeHash !== outcomeHash) {
131
+ break;
132
+ }
133
+ count += 1;
134
+ }
135
+ return { count, outcomeHash };
136
+ }
137
+ function detectPingPong(history, toolName, callHash) {
138
+ if (history.length < exports.PING_PONG_WINDOW) {
139
+ return { stuck: false };
140
+ }
141
+ const recent = history.slice(-exports.PING_PONG_WINDOW);
142
+ const first = recent[0];
143
+ const second = recent[1];
144
+ if (!first.isKnownPoll || !second.isKnownPoll) {
145
+ return { stuck: false };
146
+ }
147
+ if (first.toolName === second.toolName && first.callHash === second.callHash) {
148
+ return { stuck: false };
149
+ }
150
+ for (let index = 0; index < recent.length; index++) {
151
+ const expected = index % 2 === 0 ? first : second;
152
+ const actual = recent[index];
153
+ if (actual.toolName !== expected.toolName
154
+ || actual.callHash !== expected.callHash
155
+ || actual.outcomeHash !== expected.outcomeHash) {
156
+ return { stuck: false };
157
+ }
158
+ }
159
+ const matchesPair = (toolName === first.toolName && callHash === first.callHash)
160
+ || (toolName === second.toolName && callHash === second.callHash);
161
+ if (!matchesPair) {
162
+ return { stuck: false };
163
+ }
164
+ const pairedToolName = toolName === first.toolName ? second.toolName : first.toolName;
165
+ return emitDetection("ping_pong", toolName, exports.PING_PONG_WINDOW, `repeated ${first.toolName}/${second.toolName} polling is not changing. stop cycling between status checks and either act on the current state, change approach, or answer truthfully with what is known.`, pairedToolName);
166
+ }
167
+ function createToolLoopState() {
168
+ return { history: [] };
169
+ }
170
+ function recordToolOutcome(state, toolName, args, result, success) {
171
+ state.history.push({
172
+ toolName,
173
+ callHash: digest(normalizeArgs(toolName, args)),
174
+ outcomeHash: digest(normalizeOutcome(result, success)),
175
+ isKnownPoll: isKnownPollTool(toolName, args),
176
+ });
177
+ if (state.history.length > exports.TOOL_LOOP_HISTORY_LIMIT) {
178
+ state.history.splice(0, state.history.length - exports.TOOL_LOOP_HISTORY_LIMIT);
179
+ }
180
+ }
181
+ // Tools that must never be blocked by the circuit breaker.
182
+ // settle = end the turn, surface = deliver results outward.
183
+ // ponder = continue thinking (inner dialog) or hand off to inner dialog (outer).
184
+ // rest = end inner dialog turn (added in Unit 8b).
185
+ // Blocking these traps the agent: it can think all it wants but can never speak or stop.
186
+ const CIRCUIT_BREAKER_EXEMPT = new Set(["settle", "surface", "ponder", "rest"]);
187
+ function detectToolLoop(state, toolName, args) {
188
+ if (state.history.length >= exports.GLOBAL_CIRCUIT_BREAKER_LIMIT && !CIRCUIT_BREAKER_EXEMPT.has(toolName)) {
189
+ return emitDetection("global_circuit_breaker", toolName, state.history.length, `this turn has already made ${state.history.length} tool calls. stop thrashing, use the current evidence, and either change approach or answer truthfully with the best grounded status.`);
190
+ }
191
+ const callHash = digest(normalizeArgs(toolName, args));
192
+ const trailing = countTrailingRepeats(state.history, toolName, callHash);
193
+ if (isKnownPollTool(toolName, args) && trailing.count >= exports.POLL_NO_PROGRESS_LIMIT) {
194
+ return emitDetection("known_poll_no_progress", toolName, trailing.count, `repeated ${toolName} calls have returned the same state ${trailing.count} times. stop polling and either act on the current state, wait for a meaningful change, or answer truthfully with what is known.`);
195
+ }
196
+ if (trailing.count >= exports.GENERIC_REPEAT_LIMIT) {
197
+ return emitDetection("generic_repeat", toolName, trailing.count, `repeating ${toolName} with the same inputs is not producing new information. change approach, use the evidence already gathered, or answer truthfully with what is known.`);
198
+ }
199
+ return detectPingPong(state.history, toolName, callHash);
200
+ }
@@ -0,0 +1,358 @@
1
+ "use strict";
2
+ /**
3
+ * TurnContext: a single pre-read snapshot of all state sources needed
4
+ * by the inbound-turn pipeline and prompt assembly.
5
+ *
6
+ * Before this module existed, pipeline.ts read ~10 state sources inline
7
+ * and prompt.ts did several ad-hoc filesystem reads. This centralizes
8
+ * all reads into one place so the rest of the turn is pure derivation.
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.buildTurnContext = buildTurnContext;
45
+ const fs = __importStar(require("fs"));
46
+ const path = __importStar(require("path"));
47
+ const runtime_1 = require("../nerves/runtime");
48
+ const manager_1 = require("./bridges/manager");
49
+ const identity_1 = require("./identity");
50
+ const tasks_1 = require("../repertoire/tasks");
51
+ const coding_1 = require("../repertoire/coding");
52
+ const session_activity_1 = require("./session-activity");
53
+ const thoughts_1 = require("./daemon/thoughts");
54
+ const pending_1 = require("../mind/pending");
55
+ const obligations_1 = require("../arc/obligations");
56
+ const target_resolution_1 = require("./target-resolution");
57
+ const episodes_1 = require("../arc/episodes");
58
+ const cares_1 = require("../arc/cares");
59
+ const config_1 = require("./config");
60
+ const daemon_health_1 = require("./daemon/daemon-health");
61
+ const prompt_1 = require("../mind/prompt");
62
+ // ── Helpers ─────────────────────────────────────────────────────────
63
+ const DAEMON_SOCKET_PATH = "/tmp/ouroboros-daemon.sock";
64
+ function isLiveCodingSessionStatus(status) {
65
+ return status === "spawning"
66
+ || status === "running"
67
+ || status === "waiting_input"
68
+ || status === "stalled";
69
+ }
70
+ function emptyTaskBoard() {
71
+ return {
72
+ compact: "",
73
+ full: "",
74
+ byStatus: {
75
+ drafting: [],
76
+ processing: [],
77
+ validating: [],
78
+ collaborating: [],
79
+ paused: [],
80
+ blocked: [],
81
+ done: [],
82
+ cancelled: [],
83
+ },
84
+ issues: [],
85
+ actionRequired: [],
86
+ unresolvedDependencies: [],
87
+ activeSessions: [],
88
+ activeBridges: [],
89
+ };
90
+ }
91
+ function readInnerWorkState() {
92
+ const defaultJob = {
93
+ status: "idle",
94
+ content: null,
95
+ origin: null,
96
+ mode: "reflect",
97
+ obligationStatus: null,
98
+ surfacedResult: null,
99
+ queuedAt: null,
100
+ startedAt: null,
101
+ surfacedAt: null,
102
+ };
103
+ try {
104
+ const agentRoot = (0, identity_1.getAgentRoot)();
105
+ const pendingDir = (0, pending_1.getInnerDialogPendingDir)((0, identity_1.getAgentName)());
106
+ const sessionPath = (0, thoughts_1.getInnerDialogSessionPath)(agentRoot);
107
+ const { pendingMessages, turns, runtimeState } = (0, thoughts_1.readInnerDialogRawData)(sessionPath, pendingDir);
108
+ const dialogStatus = (0, thoughts_1.deriveInnerDialogStatus)(pendingMessages, turns, runtimeState);
109
+ const job = (0, thoughts_1.deriveInnerJob)(pendingMessages, turns, runtimeState);
110
+ const storeObligationPending = (0, obligations_1.readPendingObligations)(agentRoot).length > 0;
111
+ return {
112
+ status: dialogStatus.processing === "started" ? "running" : "idle",
113
+ hasPending: dialogStatus.queue !== "clear",
114
+ origin: dialogStatus.origin,
115
+ contentSnippet: dialogStatus.contentSnippet,
116
+ obligationPending: dialogStatus.obligationPending || storeObligationPending,
117
+ job,
118
+ };
119
+ }
120
+ catch { /* v8 ignore start -- defensive: fallback on read failure @preserve */
121
+ return {
122
+ status: "idle",
123
+ hasPending: false,
124
+ job: defaultJob,
125
+ /* v8 ignore stop */
126
+ };
127
+ }
128
+ }
129
+ function checkDaemonRunning() {
130
+ try {
131
+ return fs.existsSync(DAEMON_SOCKET_PATH);
132
+ }
133
+ catch { /* v8 ignore start -- defensive: fallback on read failure @preserve */
134
+ return false;
135
+ /* v8 ignore stop */
136
+ }
137
+ }
138
+ function hasTextField(record, key) {
139
+ return typeof record?.[key] === "string" && record[key].trim().length > 0;
140
+ }
141
+ function readSenseStatusLines() {
142
+ const config = (0, identity_1.loadAgentConfig)();
143
+ const senses = config.senses ?? {
144
+ cli: { enabled: true },
145
+ teams: { enabled: false },
146
+ bluebubbles: { enabled: false },
147
+ };
148
+ let payload = {};
149
+ try {
150
+ const raw = fs.readFileSync((0, identity_1.getAgentSecretsPath)(), "utf-8");
151
+ const parsed = JSON.parse(raw);
152
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
153
+ payload = parsed;
154
+ }
155
+ }
156
+ catch { /* v8 ignore start -- defensive: fallback on read failure @preserve */
157
+ payload = {};
158
+ /* v8 ignore stop */
159
+ }
160
+ const teams = payload.teams;
161
+ const bluebubbles = payload.bluebubbles;
162
+ const configured = {
163
+ cli: true,
164
+ teams: hasTextField(teams, "clientId") && hasTextField(teams, "clientSecret") && hasTextField(teams, "tenantId"),
165
+ bluebubbles: hasTextField(bluebubbles, "serverUrl") && hasTextField(bluebubbles, "password"),
166
+ };
167
+ const rows = [
168
+ { label: "CLI", status: "interactive" },
169
+ {
170
+ label: "Teams",
171
+ status: !senses.teams.enabled ? "disabled" : configured.teams ? "ready" : "needs_config",
172
+ },
173
+ {
174
+ label: "BlueBubbles",
175
+ status: !senses.bluebubbles.enabled ? "disabled" : configured.bluebubbles ? "ready" : "needs_config",
176
+ },
177
+ ];
178
+ return rows.map((row) => `- ${row.label}: ${row.status}`);
179
+ }
180
+ function readBundleMetaFile() {
181
+ try {
182
+ const metaPath = path.join((0, identity_1.getAgentRoot)(), "bundle-meta.json");
183
+ const raw = fs.readFileSync(metaPath, "utf-8");
184
+ return JSON.parse(raw);
185
+ }
186
+ catch { /* v8 ignore start -- defensive: fallback on read failure @preserve */
187
+ return null;
188
+ /* v8 ignore stop */
189
+ }
190
+ }
191
+ // ── Builder ─────────────────────────────────────────────────────────
192
+ async function buildTurnContext(input) {
193
+ const agentRoot = (0, identity_1.getAgentRoot)();
194
+ const agentName = (0, identity_1.getAgentName)();
195
+ // Sync config
196
+ let syncConfig = { enabled: false, remote: "origin" };
197
+ try {
198
+ syncConfig = (0, config_1.getSyncConfig)();
199
+ }
200
+ catch { /* v8 ignore next -- defensive @preserve */ /* config not available */ }
201
+ // Bridges
202
+ const activeBridges = (0, manager_1.createBridgeManager)().findBridgesForSession({
203
+ friendId: input.currentSession.friendId,
204
+ channel: input.currentSession.channel,
205
+ key: input.currentSession.key,
206
+ });
207
+ // Session activity
208
+ let sessionActivity = [];
209
+ try {
210
+ sessionActivity = (0, session_activity_1.listSessionActivity)({
211
+ sessionsDir: `${agentRoot}/state/sessions`,
212
+ friendsDir: `${agentRoot}/friends`,
213
+ agentName,
214
+ currentSession: {
215
+ friendId: input.currentSession.friendId,
216
+ channel: input.currentSession.channel,
217
+ key: input.currentSession.key,
218
+ },
219
+ });
220
+ }
221
+ catch { /* v8 ignore start -- defensive: fallback on read failure @preserve */
222
+ sessionActivity = [];
223
+ /* v8 ignore stop */
224
+ }
225
+ // Target candidates
226
+ let targetCandidates = [];
227
+ try {
228
+ if (input.channel !== "inner") {
229
+ targetCandidates = await (0, target_resolution_1.listTargetSessionCandidates)({
230
+ sessionsDir: `${agentRoot}/state/sessions`,
231
+ friendsDir: `${agentRoot}/friends`,
232
+ agentName,
233
+ currentSession: {
234
+ friendId: input.currentSession.friendId,
235
+ channel: input.currentSession.channel,
236
+ key: input.currentSession.key,
237
+ },
238
+ friendStore: input.friendStore,
239
+ });
240
+ }
241
+ }
242
+ catch { /* v8 ignore start -- defensive: fallback on read failure @preserve */
243
+ targetCandidates = [];
244
+ /* v8 ignore stop */
245
+ }
246
+ // Pending obligations
247
+ let pendingObligations = [];
248
+ try {
249
+ pendingObligations = (0, obligations_1.readPendingObligations)(agentRoot);
250
+ }
251
+ catch { /* v8 ignore start -- defensive: fallback on read failure @preserve */
252
+ pendingObligations = [];
253
+ /* v8 ignore stop */
254
+ }
255
+ // Coding sessions
256
+ let codingSessions = [];
257
+ let otherCodingSessions = [];
258
+ try {
259
+ const liveCodingSessions = (0, coding_1.getCodingSessionManager)()
260
+ .listSessions()
261
+ .filter((session) => isLiveCodingSessionStatus(session.status) && Boolean(session.originSession));
262
+ codingSessions = liveCodingSessions.filter((session) => session.originSession?.friendId === input.currentSession.friendId
263
+ && session.originSession.channel === input.currentSession.channel
264
+ && session.originSession.key === input.currentSession.key);
265
+ otherCodingSessions = liveCodingSessions.filter((session) => !(session.originSession?.friendId === input.currentSession.friendId
266
+ && session.originSession.channel === input.currentSession.channel
267
+ && session.originSession.key === input.currentSession.key));
268
+ }
269
+ catch { /* v8 ignore start -- defensive: fallback on read failure @preserve */
270
+ codingSessions = [];
271
+ otherCodingSessions = [];
272
+ /* v8 ignore stop */
273
+ }
274
+ // Inner work state
275
+ const innerWorkState = readInnerWorkState();
276
+ // Task board
277
+ let taskBoard;
278
+ try {
279
+ taskBoard = (0, tasks_1.getTaskModule)().getBoard();
280
+ }
281
+ catch { /* v8 ignore start -- defensive: fallback on read failure @preserve */
282
+ taskBoard = emptyTaskBoard();
283
+ /* v8 ignore stop */
284
+ }
285
+ // Return obligations
286
+ let returnObligations = [];
287
+ try {
288
+ returnObligations = (0, obligations_1.listActiveReturnObligations)(agentName);
289
+ }
290
+ catch { /* v8 ignore start -- defensive: fallback on read failure @preserve */
291
+ returnObligations = [];
292
+ /* v8 ignore stop */
293
+ }
294
+ // Recent episodes
295
+ const recentEpisodes = (0, episodes_1.readRecentEpisodes)(agentRoot, { limit: 20 });
296
+ // Active cares
297
+ const activeCares = (0, cares_1.readActiveCares)(agentRoot);
298
+ // ── Prompt-assembly pre-reads ──────────────────────────────────────
299
+ const daemonRunning = checkDaemonRunning();
300
+ let senseStatusLines = [];
301
+ try {
302
+ senseStatusLines = readSenseStatusLines();
303
+ }
304
+ catch { /* v8 ignore start -- defensive: fallback on read failure @preserve */
305
+ senseStatusLines = [];
306
+ /* v8 ignore stop */
307
+ }
308
+ const bundleMeta = readBundleMetaFile();
309
+ let daemonHealth = null;
310
+ try {
311
+ daemonHealth = (0, daemon_health_1.readHealth)((0, daemon_health_1.getDefaultHealthPath)());
312
+ }
313
+ catch { /* v8 ignore start -- defensive: fallback on read failure @preserve */
314
+ daemonHealth = null;
315
+ /* v8 ignore stop */
316
+ }
317
+ let journalFiles = [];
318
+ try {
319
+ const journalDir = path.join(agentRoot, "journal");
320
+ journalFiles = (0, prompt_1.readJournalFiles)(journalDir);
321
+ }
322
+ catch { /* v8 ignore start -- defensive: fallback on read failure @preserve */
323
+ journalFiles = [];
324
+ /* v8 ignore stop */
325
+ }
326
+ (0, runtime_1.emitNervesEvent)({
327
+ component: "senses",
328
+ event: "senses.turn_context_built",
329
+ message: "turn context snapshot assembled",
330
+ meta: {
331
+ channel: input.channel,
332
+ obligationCount: pendingObligations.length,
333
+ bridgeCount: activeBridges.length,
334
+ codingSessionCount: codingSessions.length,
335
+ episodeCount: recentEpisodes.length,
336
+ },
337
+ });
338
+ return {
339
+ activeBridges,
340
+ sessionActivity,
341
+ targetCandidates,
342
+ pendingObligations,
343
+ codingSessions,
344
+ otherCodingSessions,
345
+ innerWorkState,
346
+ taskBoard,
347
+ returnObligations,
348
+ recentEpisodes,
349
+ activeCares,
350
+ syncConfig,
351
+ syncFailure: undefined, // Set by pipeline after preTurnPull
352
+ daemonRunning,
353
+ senseStatusLines,
354
+ bundleMeta,
355
+ daemonHealth,
356
+ journalFiles,
357
+ };
358
+ }