@ouro.bot/cli 0.1.0-alpha.26 → 0.1.0-alpha.261

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 (266) 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 +1582 -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 +145 -0
  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 +464 -0
  31. package/dist/heart/daemon/cli-types.js +8 -0
  32. package/dist/heart/daemon/daemon-cli.js +29 -1179
  33. package/dist/heart/daemon/daemon-entry.js +216 -4
  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 +123 -0
  37. package/dist/heart/daemon/daemon.js +590 -54
  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 +276 -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 +157 -55
  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/phrases.js +1 -0
  124. package/dist/mind/prompt.js +765 -109
  125. package/dist/mind/scrutiny.js +173 -0
  126. package/dist/mind/token-estimate.js +8 -12
  127. package/dist/nerves/coverage/audit.js +1 -1
  128. package/dist/nerves/coverage/file-completeness.js +50 -5
  129. package/dist/nerves/coverage/run-artifacts.js +1 -1
  130. package/dist/nerves/event-buffer.js +111 -0
  131. package/dist/nerves/index.js +64 -4
  132. package/dist/nerves/observation.js +20 -0
  133. package/dist/nerves/runtime.js +5 -1
  134. package/dist/outlook-ui/assets/index-Ck8agNeO.js +61 -0
  135. package/dist/outlook-ui/assets/index-LwChZTgL.css +1 -0
  136. package/dist/outlook-ui/index.html +15 -0
  137. package/dist/repertoire/ado-client.js +15 -56
  138. package/dist/repertoire/ado-semantic.js +11 -10
  139. package/dist/repertoire/api-client.js +97 -0
  140. package/dist/repertoire/bitwarden-store.js +319 -0
  141. package/dist/repertoire/bw-installer.js +79 -0
  142. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  143. package/dist/repertoire/coding/context-pack.js +330 -0
  144. package/dist/repertoire/coding/feedback.js +197 -30
  145. package/dist/repertoire/coding/manager.js +149 -2
  146. package/dist/repertoire/coding/spawner.js +55 -9
  147. package/dist/repertoire/coding/tools.js +170 -7
  148. package/dist/repertoire/commerce-errors.js +109 -0
  149. package/dist/repertoire/commerce-self-test.js +156 -0
  150. package/dist/repertoire/credential-access.js +515 -0
  151. package/dist/repertoire/duffel-client.js +185 -0
  152. package/dist/repertoire/github-client.js +14 -55
  153. package/dist/repertoire/graph-client.js +11 -52
  154. package/dist/repertoire/guardrails.js +369 -0
  155. package/dist/repertoire/mcp-client.js +255 -0
  156. package/dist/repertoire/mcp-manager.js +305 -0
  157. package/dist/repertoire/mcp-tools.js +63 -0
  158. package/dist/repertoire/shell-sessions.js +133 -0
  159. package/dist/repertoire/skills.js +14 -23
  160. package/dist/repertoire/stripe-client.js +131 -0
  161. package/dist/repertoire/tasks/board.js +43 -5
  162. package/dist/repertoire/tasks/fix.js +182 -0
  163. package/dist/repertoire/tasks/index.js +28 -10
  164. package/dist/repertoire/tasks/lifecycle.js +2 -2
  165. package/dist/repertoire/tasks/parser.js +3 -2
  166. package/dist/repertoire/tasks/scanner.js +194 -37
  167. package/dist/repertoire/tasks/transitions.js +11 -28
  168. package/dist/repertoire/tools-base.js +43 -771
  169. package/dist/repertoire/tools-bluebubbles.js +201 -0
  170. package/dist/repertoire/tools-bridge.js +141 -0
  171. package/dist/repertoire/tools-config.js +185 -0
  172. package/dist/repertoire/tools-continuity.js +248 -0
  173. package/dist/repertoire/tools-credential.js +182 -0
  174. package/dist/repertoire/tools-files.js +342 -0
  175. package/dist/repertoire/tools-flight.js +224 -0
  176. package/dist/repertoire/tools-flow.js +62 -0
  177. package/dist/repertoire/tools-github.js +1 -7
  178. package/dist/repertoire/tools-memory.js +347 -0
  179. package/dist/repertoire/tools-session.js +739 -0
  180. package/dist/repertoire/tools-shell.js +120 -0
  181. package/dist/repertoire/tools-stripe.js +180 -0
  182. package/dist/repertoire/tools-surface.js +243 -0
  183. package/dist/repertoire/tools-teams.js +12 -62
  184. package/dist/repertoire/tools-travel.js +125 -0
  185. package/dist/repertoire/tools-user-profile.js +144 -0
  186. package/dist/repertoire/tools-vault.js +110 -0
  187. package/dist/repertoire/tools.js +155 -130
  188. package/dist/repertoire/travel-api-client.js +360 -0
  189. package/dist/repertoire/user-profile.js +118 -0
  190. package/dist/repertoire/vault-setup.js +241 -0
  191. package/dist/scripts/claude-code-hook.js +41 -0
  192. package/dist/scripts/claude-code-stop-hook.js +47 -0
  193. package/dist/senses/attention-queue.js +97 -0
  194. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  195. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +145 -10
  196. package/dist/senses/bluebubbles/entry.js +13 -0
  197. package/dist/senses/bluebubbles/inbound-log.js +110 -0
  198. package/dist/senses/bluebubbles/index.js +1374 -0
  199. package/dist/senses/bluebubbles/media.js +455 -0
  200. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +20 -5
  201. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +46 -6
  202. package/dist/senses/bluebubbles/runtime-state.js +109 -0
  203. package/dist/senses/bluebubbles/session-cleanup.js +72 -0
  204. package/dist/senses/cli/bracketed-paste.js +82 -0
  205. package/dist/senses/cli/image-paste.js +211 -0
  206. package/dist/senses/cli/image-ref-navigation.js +75 -0
  207. package/dist/senses/cli/ink-app.js +156 -0
  208. package/dist/senses/cli/inline-diff.js +64 -0
  209. package/dist/senses/cli/input-keys.js +168 -0
  210. package/dist/senses/cli/kill-ring.js +86 -0
  211. package/dist/senses/cli/message-list.js +51 -0
  212. package/dist/senses/cli/ouro-tui.js +581 -0
  213. package/dist/senses/cli/spinner-imperative.js +135 -0
  214. package/dist/senses/cli/spinner.js +101 -0
  215. package/dist/senses/cli/status-line.js +60 -0
  216. package/dist/senses/cli/streaming-markdown.js +526 -0
  217. package/dist/senses/cli/tool-display.js +83 -0
  218. package/dist/senses/cli/tool-render.js +85 -0
  219. package/dist/senses/cli/tui-store.js +240 -0
  220. package/dist/senses/cli/virtual-list.js +35 -0
  221. package/dist/senses/cli-entry.js +1 -1
  222. package/dist/senses/cli-layout.js +187 -0
  223. package/dist/senses/cli.js +569 -246
  224. package/dist/senses/commands.js +65 -1
  225. package/dist/senses/continuity.js +94 -0
  226. package/dist/senses/habit-turn-message.js +108 -0
  227. package/dist/senses/inner-dialog-worker.js +112 -19
  228. package/dist/senses/inner-dialog.js +593 -85
  229. package/dist/senses/pipeline.js +552 -0
  230. package/dist/senses/shared-turn.js +199 -0
  231. package/dist/senses/surface-tool.js +68 -0
  232. package/dist/senses/teams.js +664 -165
  233. package/dist/senses/trust-gate.js +112 -2
  234. package/package.json +14 -7
  235. package/skills/agent-commerce.md +106 -0
  236. package/skills/browser-navigation.md +110 -0
  237. package/skills/commerce-setup-guide.md +116 -0
  238. package/skills/commerce-setup.md +84 -0
  239. package/skills/configure-dev-tools.md +81 -0
  240. package/skills/travel-planning.md +138 -0
  241. package/dist/heart/daemon/subagent-installer.js +0 -134
  242. package/dist/senses/bluebubbles-entry.js +0 -11
  243. package/dist/senses/bluebubbles-media.js +0 -244
  244. package/dist/senses/bluebubbles.js +0 -421
  245. package/dist/senses/debug-activity.js +0 -107
  246. package/subagents/README.md +0 -73
  247. package/subagents/work-doer.md +0 -235
  248. package/subagents/work-merger.md +0 -618
  249. package/subagents/work-planner.md +0 -382
  250. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  251. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  252. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  253. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  254. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  255. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  256. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  257. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  258. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  259. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  260. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  261. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +0 -0
  262. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  263. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  264. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  265. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  266. /package/dist/heart/{daemon → versioning}/update-hooks.js +0 -0
@@ -0,0 +1,276 @@
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.DEFAULT_DAEMON_SOCKET_PATH = void 0;
37
+ exports.__bypassVitestGuardForTests = __bypassVitestGuardForTests;
38
+ exports.sendDaemonCommand = sendDaemonCommand;
39
+ exports.checkDaemonSocketAlive = checkDaemonSocketAlive;
40
+ exports.requestInnerWake = requestInnerWake;
41
+ const fs = __importStar(require("fs"));
42
+ const net = __importStar(require("net"));
43
+ const runtime_1 = require("../../nerves/runtime");
44
+ exports.DEFAULT_DAEMON_SOCKET_PATH = "/tmp/ouroboros-daemon.sock";
45
+ /**
46
+ * Defense-in-depth: detect if we're running under vitest. Tests that forget
47
+ * to `vi.mock("../../heart/daemon/socket-client")` would otherwise leak real
48
+ * `inner.wake` commands (with whatever literal agent name the test uses,
49
+ * commonly "testagent") into whichever real daemon happens to be running on
50
+ * the developer's machine. That has caused real outages when test loops
51
+ * flooded the production-on-localhost daemon.
52
+ *
53
+ * We detect vitest via `process.argv` (not env vars — the project bans those)
54
+ * and convert all socket operations into safe no-ops. Individual tests are
55
+ * still expected to vi.mock this module so they can assert on call counts,
56
+ * but this guard guarantees that "I forgot to mock" can never again take
57
+ * down the daemon.
58
+ *
59
+ * The socket-client's OWN tests (which exercise the real functions against a
60
+ * test socket) call `__bypassVitestGuardForTests(true)` to opt out of the
61
+ * guard. We persist that flag on globalThis so it survives `vi.resetModules`
62
+ * (which clears the module cache between tests).
63
+ */
64
+ const BYPASS_KEY = "__ouro_socket_client_bypass_vitest_guard__";
65
+ /** ONLY for socket-client.test.ts. Do not call from any other test or production code. */
66
+ function __bypassVitestGuardForTests(bypass) {
67
+ ;
68
+ globalThis[BYPASS_KEY] = bypass;
69
+ }
70
+ function isUnderVitest() {
71
+ if (globalThis[BYPASS_KEY] === true)
72
+ return false;
73
+ /* v8 ignore next -- defensive: process and process.argv always exist in node @preserve */
74
+ if (typeof process === "undefined" || !Array.isArray(process.argv))
75
+ return false;
76
+ return process.argv.some((arg) => typeof arg === "string" && arg.includes("vitest"));
77
+ }
78
+ function sendDaemonCommand(socketPath, command) {
79
+ if (isUnderVitest()) {
80
+ (0, runtime_1.emitNervesEvent)({
81
+ level: "warn",
82
+ component: "daemon",
83
+ event: "daemon.socket_command_test_blocked",
84
+ message: "blocked socket command from leaking into real daemon under vitest",
85
+ meta: { socketPath, kind: command.kind },
86
+ });
87
+ return Promise.resolve({ ok: true, message: "test mode: socket call suppressed" });
88
+ }
89
+ (0, runtime_1.emitNervesEvent)({
90
+ component: "daemon",
91
+ event: "daemon.socket_command_start",
92
+ message: "sending daemon command over socket",
93
+ meta: { socketPath, kind: command.kind },
94
+ });
95
+ return new Promise((resolve, reject) => {
96
+ const client = net.createConnection(socketPath);
97
+ let raw = "";
98
+ client.on("connect", () => {
99
+ // Write the command + newline delimiter. DO NOT call client.end()
100
+ // afterwards — the server closes the connection once it has written
101
+ // its response, which triggers our on("end") handler with the full
102
+ // response in `raw`.
103
+ //
104
+ // Calling client.end() here half-closes the TCP connection. The
105
+ // daemon server uses net.createServer() with the default
106
+ // allowHalfOpen: false, so when the server sees the client's FIN it
107
+ // auto-closes its own writable side — and any response the server
108
+ // tries to write after processing a long-running command (like
109
+ // agent.senseTurn, which runs a full LLM turn) gets dropped on the
110
+ // floor. Verified via repro: with client.end(), agent.senseTurn
111
+ // returns empty in ~149ms; without it, the same call returns the real
112
+ // response in ~5.8s. This is a regression of the fix in #303 that
113
+ // was silently reverted by 253e4b1f (commit titled "socket half-close
114
+ // fix" but actually *added* the half-close back).
115
+ client.write(JSON.stringify(command) + "\n");
116
+ });
117
+ client.on("data", (chunk) => {
118
+ raw += chunk.toString("utf-8");
119
+ });
120
+ client.on("error", (error) => {
121
+ (0, runtime_1.emitNervesEvent)({
122
+ level: "error",
123
+ component: "daemon",
124
+ event: "daemon.socket_command_error",
125
+ message: "daemon socket command failed",
126
+ meta: {
127
+ socketPath,
128
+ kind: command.kind,
129
+ error: error.message,
130
+ },
131
+ });
132
+ reject(error);
133
+ });
134
+ client.on("end", () => {
135
+ const trimmed = raw.trim();
136
+ if (trimmed.length === 0 && command.kind === "daemon.stop") {
137
+ (0, runtime_1.emitNervesEvent)({
138
+ component: "daemon",
139
+ event: "daemon.socket_command_end",
140
+ message: "daemon socket command completed",
141
+ meta: { socketPath, kind: command.kind, ok: true },
142
+ });
143
+ resolve({ ok: true, message: "daemon stopped" });
144
+ return;
145
+ }
146
+ if (trimmed.length === 0) {
147
+ const error = new Error("Daemon returned empty response.");
148
+ (0, runtime_1.emitNervesEvent)({
149
+ level: "error",
150
+ component: "daemon",
151
+ event: "daemon.socket_command_error",
152
+ message: "daemon socket command returned empty response",
153
+ meta: {
154
+ socketPath,
155
+ kind: command.kind,
156
+ error: error.message,
157
+ },
158
+ });
159
+ reject(error);
160
+ return;
161
+ }
162
+ try {
163
+ const parsed = JSON.parse(trimmed);
164
+ (0, runtime_1.emitNervesEvent)({
165
+ component: "daemon",
166
+ event: "daemon.socket_command_end",
167
+ message: "daemon socket command completed",
168
+ meta: {
169
+ socketPath,
170
+ kind: command.kind,
171
+ ok: parsed.ok,
172
+ },
173
+ });
174
+ resolve(parsed);
175
+ }
176
+ catch (error) {
177
+ (0, runtime_1.emitNervesEvent)({
178
+ level: "error",
179
+ component: "daemon",
180
+ event: "daemon.socket_command_error",
181
+ message: "daemon socket command returned invalid JSON",
182
+ meta: {
183
+ socketPath,
184
+ kind: command.kind,
185
+ error: error instanceof Error ? error.message : String(error),
186
+ },
187
+ });
188
+ reject(error);
189
+ }
190
+ });
191
+ });
192
+ }
193
+ function checkDaemonSocketAlive(socketPath) {
194
+ if (isUnderVitest()) {
195
+ return Promise.resolve(false);
196
+ }
197
+ (0, runtime_1.emitNervesEvent)({
198
+ component: "daemon",
199
+ event: "daemon.socket_alive_check_start",
200
+ message: "checking daemon socket health",
201
+ meta: { socketPath },
202
+ });
203
+ return new Promise((resolve) => {
204
+ const client = net.createConnection(socketPath);
205
+ let raw = "";
206
+ let done = false;
207
+ const finalize = (alive) => {
208
+ if (done)
209
+ return;
210
+ done = true;
211
+ (0, runtime_1.emitNervesEvent)({
212
+ component: "daemon",
213
+ event: "daemon.socket_alive_check_end",
214
+ message: "daemon socket health check completed",
215
+ meta: { socketPath, alive },
216
+ });
217
+ resolve(alive);
218
+ };
219
+ if ("setTimeout" in client && typeof client.setTimeout === "function") {
220
+ client.setTimeout(800, () => {
221
+ client.destroy();
222
+ finalize(false);
223
+ });
224
+ }
225
+ client.on("connect", () => {
226
+ // Same half-close rationale as sendDaemonCommand: do NOT call
227
+ // client.end() here. The server closes after responding and that
228
+ // triggers the on("end") handler below.
229
+ client.write(JSON.stringify({ kind: "daemon.status" }) + "\n");
230
+ });
231
+ client.on("data", (chunk) => {
232
+ raw += chunk.toString("utf-8");
233
+ });
234
+ client.on("error", () => finalize(false));
235
+ client.on("end", () => {
236
+ if (raw.trim().length === 0) {
237
+ finalize(false);
238
+ return;
239
+ }
240
+ try {
241
+ JSON.parse(raw);
242
+ finalize(true);
243
+ }
244
+ catch {
245
+ finalize(false);
246
+ }
247
+ });
248
+ });
249
+ }
250
+ async function requestInnerWake(agent, socketPath = exports.DEFAULT_DAEMON_SOCKET_PATH) {
251
+ if (isUnderVitest()) {
252
+ (0, runtime_1.emitNervesEvent)({
253
+ level: "warn",
254
+ component: "daemon",
255
+ event: "daemon.inner_wake_test_blocked",
256
+ message: "blocked inner wake from leaking into real daemon under vitest",
257
+ meta: { agent, socketPath },
258
+ });
259
+ return null;
260
+ }
261
+ const socketAvailable = fs.existsSync(socketPath);
262
+ (0, runtime_1.emitNervesEvent)({
263
+ component: "daemon",
264
+ event: "daemon.inner_wake_request",
265
+ message: "requesting daemon-managed inner wake",
266
+ meta: {
267
+ agent,
268
+ socketPath,
269
+ socketAvailable,
270
+ },
271
+ });
272
+ if (!socketAvailable) {
273
+ return null;
274
+ }
275
+ return sendDaemonCommand(socketPath, { kind: "inner.wake", agent });
276
+ }
@@ -39,6 +39,7 @@ const path = __importStar(require("path"));
39
39
  const identity_1 = require("../identity");
40
40
  const runtime_1 = require("../../nerves/runtime");
41
41
  const parser_1 = require("../../repertoire/tasks/parser");
42
+ const cadence_1 = require("./cadence");
42
43
  function walkMarkdownFiles(root, readdirSync, existsSync, files) {
43
44
  if (!existsSync(root))
44
45
  return;
@@ -53,29 +54,6 @@ function walkMarkdownFiles(root, readdirSync, existsSync, files) {
53
54
  }
54
55
  }
55
56
  }
56
- function parseCadence(raw) {
57
- if (typeof raw !== "string")
58
- return null;
59
- const value = raw.trim();
60
- if (!value)
61
- return null;
62
- // Cron format (minute hour day month weekday)
63
- if (/^\S+\s+\S+\s+\S+\s+\S+\s+\S+$/.test(value)) {
64
- return value;
65
- }
66
- const cadenceMatch = /^(\d+)(m|h|d)$/.exec(value);
67
- if (!cadenceMatch)
68
- return null;
69
- const interval = Number.parseInt(cadenceMatch[1], 10);
70
- if (!Number.isFinite(interval) || interval <= 0)
71
- return null;
72
- const unit = cadenceMatch[2];
73
- if (unit === "m")
74
- return `*/${interval} * * * *`;
75
- if (unit === "h")
76
- return `0 */${interval} * * *`;
77
- return `0 0 */${interval} * *`;
78
- }
79
57
  function parseScheduledAt(raw) {
80
58
  if (typeof raw !== "string")
81
59
  return null;
@@ -140,7 +118,7 @@ class TaskDrivenScheduler {
140
118
  const nextTaskPaths = new Map();
141
119
  for (const agent of this.agents) {
142
120
  const taskRoot = path.join(this.bundlesRoot, `${agent}.ouro`, "tasks");
143
- const collections = ["one-shots", "ongoing", "habits"];
121
+ const collections = ["one-shots", "ongoing"];
144
122
  const files = [];
145
123
  for (const collection of collections) {
146
124
  walkMarkdownFiles(path.join(taskRoot, collection), this.readdirSync, this.existsSync, files);
@@ -157,7 +135,7 @@ class TaskDrivenScheduler {
157
135
  nextTaskPaths.set(`${agent}:${taskId}`, filePath);
158
136
  if (task.status === "done")
159
137
  continue;
160
- const cadence = parseCadence(task.frontmatter.cadence);
138
+ const cadence = (0, cadence_1.parseCadenceToCron)(task.frontmatter.cadence);
161
139
  if (cadence) {
162
140
  const id = `${agent}:${taskId}:cadence`;
163
141
  nextJobs.set(id, {