@ouro.bot/cli 0.1.0-alpha.3 → 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 (289) hide show
  1. package/README.md +188 -190
  2. package/SerpentGuide.ouro/agent.json +82 -0
  3. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +6 -3
  4. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +2 -2
  5. package/SerpentGuide.ouro/psyche/identities/python.md +31 -0
  6. package/assets/ouroboros.png +0 -0
  7. package/changelog.json +1888 -0
  8. package/dist/arc/attention-types.js +8 -0
  9. package/dist/arc/cares.js +140 -0
  10. package/dist/arc/episodes.js +117 -0
  11. package/dist/arc/intentions.js +133 -0
  12. package/dist/arc/json-store.js +117 -0
  13. package/dist/arc/obligations.js +237 -0
  14. package/dist/arc/packets.js +203 -0
  15. package/dist/arc/presence.js +185 -0
  16. package/dist/heart/active-work.js +832 -0
  17. package/dist/heart/agent-entry.js +37 -2
  18. package/dist/heart/attachments/image-normalize.js +194 -0
  19. package/dist/heart/attachments/materialize.js +230 -0
  20. package/dist/heart/attachments/render.js +29 -0
  21. package/dist/heart/attachments/store.js +103 -0
  22. package/dist/heart/attachments/types.js +138 -0
  23. package/dist/heart/auth/auth-flow.js +456 -0
  24. package/dist/heart/bridges/manager.js +358 -0
  25. package/dist/heart/bridges/state-machine.js +135 -0
  26. package/dist/heart/bridges/store.js +123 -0
  27. package/dist/heart/bundle-state.js +168 -0
  28. package/dist/heart/commitments.js +111 -0
  29. package/dist/heart/config-registry.js +304 -0
  30. package/dist/heart/config.js +123 -28
  31. package/dist/heart/core.js +738 -191
  32. package/dist/heart/cross-chat-delivery.js +131 -0
  33. package/dist/heart/daemon/agent-config-check.js +149 -0
  34. package/dist/heart/daemon/agent-discovery.js +157 -0
  35. package/dist/heart/daemon/agent-service.js +360 -0
  36. package/dist/heart/daemon/cadence.js +70 -0
  37. package/dist/heart/daemon/cli-defaults.js +574 -0
  38. package/dist/heart/daemon/cli-exec.js +1945 -0
  39. package/dist/heart/daemon/cli-parse.js +808 -0
  40. package/dist/heart/daemon/cli-render.js +503 -0
  41. package/dist/heart/daemon/cli-types.js +8 -0
  42. package/dist/heart/daemon/daemon-cli.js +29 -673
  43. package/dist/heart/daemon/daemon-entry.js +259 -8
  44. package/dist/heart/daemon/daemon-health.js +136 -0
  45. package/dist/heart/daemon/daemon-runtime-sync.js +231 -0
  46. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  47. package/dist/heart/daemon/daemon.js +745 -18
  48. package/dist/heart/daemon/health-monitor.js +38 -0
  49. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  50. package/dist/heart/daemon/hooks/bundle-meta.js +206 -0
  51. package/dist/heart/daemon/inner-status.js +89 -0
  52. package/dist/heart/daemon/launchd.js +171 -0
  53. package/dist/heart/daemon/log-tailer.js +82 -12
  54. package/dist/heart/daemon/logs-prune.js +105 -0
  55. package/dist/heart/daemon/message-router.js +17 -8
  56. package/dist/heart/daemon/os-cron-deps.js +134 -0
  57. package/dist/heart/daemon/ouro-bot-entry.js +1 -1
  58. package/dist/heart/daemon/process-manager.js +181 -1
  59. package/dist/heart/daemon/pulse.js +463 -0
  60. package/dist/heart/daemon/run-hooks.js +39 -0
  61. package/dist/heart/daemon/runtime-logging.js +70 -15
  62. package/dist/heart/daemon/runtime-metadata.js +219 -0
  63. package/dist/heart/daemon/runtime-mode.js +67 -0
  64. package/dist/heart/daemon/safe-mode.js +161 -0
  65. package/dist/heart/daemon/sense-manager.js +335 -0
  66. package/dist/heart/daemon/session-id-resolver.js +131 -0
  67. package/dist/heart/daemon/skill-management-installer.js +94 -0
  68. package/dist/heart/daemon/socket-client.js +307 -0
  69. package/dist/heart/daemon/task-scheduler.js +3 -25
  70. package/dist/heart/daemon/thoughts.js +510 -0
  71. package/dist/heart/delegation.js +62 -0
  72. package/dist/heart/habits/habit-migration.js +181 -0
  73. package/dist/heart/habits/habit-parser.js +140 -0
  74. package/dist/heart/habits/habit-scheduler.js +371 -0
  75. package/dist/heart/hatch/hatch-animation.js +35 -0
  76. package/dist/heart/{daemon → hatch}/hatch-flow.js +31 -130
  77. package/dist/heart/{daemon → hatch}/hatch-specialist.js +7 -2
  78. package/dist/heart/hatch/specialist-orchestrator.js +129 -0
  79. package/dist/heart/hatch/specialist-prompt.js +101 -0
  80. package/dist/heart/hatch/specialist-tools.js +283 -0
  81. package/dist/heart/identity.js +241 -54
  82. package/dist/heart/kicks.js +2 -20
  83. package/dist/heart/mcp/mcp-server.js +653 -0
  84. package/dist/heart/migrate-config.js +127 -0
  85. package/dist/heart/model-capabilities.js +59 -0
  86. package/dist/heart/outlook/outlook-http.js +439 -0
  87. package/dist/heart/outlook/outlook-read.js +1618 -0
  88. package/dist/heart/outlook/outlook-render.js +1032 -0
  89. package/dist/heart/outlook/outlook-types.js +7 -0
  90. package/dist/heart/outlook/outlook-view.js +194 -0
  91. package/dist/heart/progress-story.js +42 -0
  92. package/dist/heart/provider-failover.js +88 -0
  93. package/dist/heart/provider-ping.js +162 -0
  94. package/dist/heart/providers/anthropic-token.js +163 -0
  95. package/dist/heart/providers/anthropic.js +181 -41
  96. package/dist/heart/providers/azure.js +98 -11
  97. package/dist/heart/providers/error-classification.js +63 -0
  98. package/dist/heart/providers/github-copilot.js +136 -0
  99. package/dist/heart/providers/minimax-vlm.js +189 -0
  100. package/dist/heart/providers/minimax.js +23 -5
  101. package/dist/heart/providers/openai-codex.js +33 -22
  102. package/dist/heart/sense-truth.js +61 -0
  103. package/dist/heart/session-activity.js +172 -0
  104. package/dist/heart/session-recall.js +216 -0
  105. package/dist/heart/start-of-turn-packet.js +339 -0
  106. package/dist/heart/streaming.js +120 -33
  107. package/dist/heart/sync.js +332 -0
  108. package/dist/heart/target-resolution.js +127 -0
  109. package/dist/heart/tempo.js +93 -0
  110. package/dist/heart/temporal-view.js +41 -0
  111. package/dist/heart/tool-activity-callbacks.js +36 -0
  112. package/dist/heart/tool-description.js +135 -0
  113. package/dist/heart/tool-friction.js +55 -0
  114. package/dist/heart/tool-loop.js +200 -0
  115. package/dist/heart/turn-context.js +358 -0
  116. package/dist/heart/turn-coordinator.js +28 -0
  117. package/dist/heart/versioning/ouro-bot-global-installer.js +128 -0
  118. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +5 -4
  119. package/dist/heart/versioning/ouro-path-installer.js +221 -0
  120. package/dist/heart/{daemon → versioning}/ouro-uti.js +11 -2
  121. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  122. package/dist/heart/versioning/staged-restart.js +146 -0
  123. package/dist/heart/versioning/update-checker.js +113 -0
  124. package/dist/heart/versioning/update-hooks.js +142 -0
  125. package/dist/heart/versioning/wrapper-publish-guard.js +86 -0
  126. package/dist/mind/associative-recall.js +135 -66
  127. package/dist/mind/bundle-manifest.js +77 -1
  128. package/dist/mind/context.js +125 -14
  129. package/dist/mind/diary-integrity.js +60 -0
  130. package/dist/mind/{memory.js → diary.js} +84 -96
  131. package/dist/mind/embedding-provider.js +60 -0
  132. package/dist/mind/file-state.js +179 -0
  133. package/dist/mind/first-impressions.js +16 -2
  134. package/dist/mind/friends/channel.js +64 -0
  135. package/dist/mind/friends/group-context.js +144 -0
  136. package/dist/mind/friends/resolver.js +37 -0
  137. package/dist/mind/friends/store-file.js +58 -3
  138. package/dist/mind/friends/trust-explanation.js +74 -0
  139. package/dist/mind/friends/types.js +9 -1
  140. package/dist/mind/journal-index.js +161 -0
  141. package/dist/mind/obligation-steering.js +221 -0
  142. package/dist/mind/pending.js +76 -9
  143. package/dist/mind/phrases.js +1 -0
  144. package/dist/mind/prompt.js +1011 -107
  145. package/dist/mind/scrutiny.js +173 -0
  146. package/dist/mind/token-estimate.js +8 -12
  147. package/dist/nerves/cli-logging.js +22 -3
  148. package/dist/nerves/coverage/audit.js +1 -1
  149. package/dist/nerves/coverage/file-completeness.js +59 -5
  150. package/dist/nerves/coverage/run-artifacts.js +1 -1
  151. package/dist/nerves/event-buffer.js +111 -0
  152. package/dist/nerves/index.js +224 -4
  153. package/dist/nerves/observation.js +20 -0
  154. package/dist/nerves/redact.js +79 -0
  155. package/dist/nerves/runtime.js +5 -1
  156. package/dist/outlook-ui/assets/index-Ck8agNeO.js +61 -0
  157. package/dist/outlook-ui/assets/index-LwChZTgL.css +1 -0
  158. package/dist/outlook-ui/index.html +15 -0
  159. package/dist/repertoire/ado-client.js +17 -56
  160. package/dist/repertoire/ado-semantic.js +11 -10
  161. package/dist/repertoire/api-client.js +97 -0
  162. package/dist/repertoire/bitwarden-store.js +319 -0
  163. package/dist/repertoire/bundle-templates.js +72 -0
  164. package/dist/repertoire/bw-installer.js +79 -0
  165. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  166. package/dist/repertoire/coding/context-pack.js +330 -0
  167. package/dist/repertoire/coding/feedback.js +301 -0
  168. package/dist/repertoire/coding/index.js +4 -1
  169. package/dist/repertoire/coding/manager.js +220 -13
  170. package/dist/repertoire/coding/spawner.js +58 -12
  171. package/dist/repertoire/coding/tools.js +209 -7
  172. package/dist/repertoire/commerce-errors.js +109 -0
  173. package/dist/repertoire/commerce-self-test.js +156 -0
  174. package/dist/repertoire/credential-access.js +527 -0
  175. package/dist/repertoire/data/ado-endpoints.json +188 -0
  176. package/dist/repertoire/duffel-client.js +185 -0
  177. package/dist/repertoire/github-client.js +14 -55
  178. package/dist/repertoire/graph-client.js +11 -52
  179. package/dist/repertoire/guardrails.js +375 -0
  180. package/dist/repertoire/mcp-client.js +255 -0
  181. package/dist/repertoire/mcp-manager.js +305 -0
  182. package/dist/repertoire/mcp-tools.js +63 -0
  183. package/dist/repertoire/shell-sessions.js +133 -0
  184. package/dist/repertoire/skills.js +14 -23
  185. package/dist/repertoire/stripe-client.js +131 -0
  186. package/dist/repertoire/tasks/board.js +43 -5
  187. package/dist/repertoire/tasks/fix.js +182 -0
  188. package/dist/repertoire/tasks/index.js +28 -10
  189. package/dist/repertoire/tasks/lifecycle.js +2 -2
  190. package/dist/repertoire/tasks/parser.js +3 -2
  191. package/dist/repertoire/tasks/scanner.js +194 -37
  192. package/dist/repertoire/tasks/transitions.js +11 -28
  193. package/dist/repertoire/tool-results.js +29 -0
  194. package/dist/repertoire/tools-attachments.js +316 -0
  195. package/dist/repertoire/tools-base.js +45 -707
  196. package/dist/repertoire/tools-bluebubbles.js +94 -0
  197. package/dist/repertoire/tools-bridge.js +141 -0
  198. package/dist/repertoire/tools-bundle.js +984 -0
  199. package/dist/repertoire/tools-config.js +185 -0
  200. package/dist/repertoire/tools-continuity.js +248 -0
  201. package/dist/repertoire/tools-credential.js +182 -0
  202. package/dist/repertoire/tools-files.js +342 -0
  203. package/dist/repertoire/tools-flight.js +224 -0
  204. package/dist/repertoire/tools-flow.js +105 -0
  205. package/dist/repertoire/tools-github.js +1 -7
  206. package/dist/repertoire/tools-memory.js +374 -0
  207. package/dist/repertoire/tools-session.js +739 -0
  208. package/dist/repertoire/tools-shell.js +120 -0
  209. package/dist/repertoire/tools-stripe.js +180 -0
  210. package/dist/repertoire/tools-surface.js +243 -0
  211. package/dist/repertoire/tools-teams.js +64 -61
  212. package/dist/repertoire/tools-travel.js +125 -0
  213. package/dist/repertoire/tools-user-profile.js +144 -0
  214. package/dist/repertoire/tools-vault.js +110 -0
  215. package/dist/repertoire/tools.js +149 -98
  216. package/dist/repertoire/travel-api-client.js +360 -0
  217. package/dist/repertoire/user-profile.js +118 -0
  218. package/dist/repertoire/vault-setup.js +241 -0
  219. package/dist/scripts/claude-code-hook.js +41 -0
  220. package/dist/scripts/claude-code-stop-hook.js +47 -0
  221. package/dist/senses/attention-queue.js +116 -0
  222. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  223. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  224. package/dist/senses/bluebubbles/client.js +568 -0
  225. package/dist/senses/bluebubbles/entry.js +13 -0
  226. package/dist/senses/bluebubbles/inbound-log.js +113 -0
  227. package/dist/senses/bluebubbles/index.js +1427 -0
  228. package/dist/senses/bluebubbles/media.js +390 -0
  229. package/dist/senses/bluebubbles/model.js +282 -0
  230. package/dist/senses/bluebubbles/mutation-log.js +116 -0
  231. package/dist/senses/bluebubbles/replay.js +129 -0
  232. package/dist/senses/bluebubbles/runtime-state.js +109 -0
  233. package/dist/senses/bluebubbles/session-cleanup.js +72 -0
  234. package/dist/senses/cli/bracketed-paste.js +82 -0
  235. package/dist/senses/cli/image-paste.js +287 -0
  236. package/dist/senses/cli/image-ref-navigation.js +75 -0
  237. package/dist/senses/cli/ink-app.js +156 -0
  238. package/dist/senses/cli/inline-diff.js +64 -0
  239. package/dist/senses/cli/input-keys.js +174 -0
  240. package/dist/senses/cli/kill-ring.js +86 -0
  241. package/dist/senses/cli/message-list.js +51 -0
  242. package/dist/senses/cli/ouro-tui.js +595 -0
  243. package/dist/senses/cli/spinner-imperative.js +135 -0
  244. package/dist/senses/cli/spinner.js +101 -0
  245. package/dist/senses/cli/status-line.js +60 -0
  246. package/dist/senses/cli/streaming-markdown.js +526 -0
  247. package/dist/senses/cli/tool-display.js +83 -0
  248. package/dist/senses/cli/tool-render.js +85 -0
  249. package/dist/senses/cli/tui-store.js +240 -0
  250. package/dist/senses/cli/virtual-list.js +35 -0
  251. package/dist/senses/cli-entry.js +1 -1
  252. package/dist/senses/cli-layout.js +187 -0
  253. package/dist/senses/cli.js +772 -264
  254. package/dist/senses/commands.js +65 -1
  255. package/dist/senses/continuity.js +94 -0
  256. package/dist/senses/habit-turn-message.js +108 -0
  257. package/dist/senses/inner-dialog-worker.js +112 -19
  258. package/dist/senses/inner-dialog.js +633 -86
  259. package/dist/senses/pipeline.js +560 -0
  260. package/dist/senses/shared-turn.js +195 -0
  261. package/dist/senses/surface-tool.js +68 -0
  262. package/dist/senses/teams.js +814 -196
  263. package/dist/senses/trust-gate.js +112 -2
  264. package/package.json +25 -9
  265. package/skills/agent-commerce.md +106 -0
  266. package/skills/browser-navigation.md +110 -0
  267. package/skills/commerce-setup-guide.md +116 -0
  268. package/skills/commerce-setup.md +84 -0
  269. package/skills/configure-dev-tools.md +81 -0
  270. package/skills/travel-planning.md +138 -0
  271. package/AdoptionSpecialist.ouro/agent.json +0 -20
  272. package/AdoptionSpecialist.ouro/psyche/identities/python.md +0 -1
  273. package/dist/heart/daemon/subagent-installer.js +0 -125
  274. package/dist/inner-worker-entry.js +0 -4
  275. package/subagents/README.md +0 -73
  276. package/subagents/work-doer.md +0 -233
  277. package/subagents/work-merger.md +0 -624
  278. package/subagents/work-planner.md +0 -373
  279. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  280. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  281. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  282. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  283. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  284. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  285. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  286. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  287. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  288. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +0 -0
  289. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
@@ -0,0 +1,219 @@
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.getRuntimeMetadata = getRuntimeMetadata;
37
+ const crypto_1 = require("crypto");
38
+ const fs = __importStar(require("fs"));
39
+ const os = __importStar(require("os"));
40
+ const path = __importStar(require("path"));
41
+ const childProcess = __importStar(require("child_process"));
42
+ const identity_1 = require("../identity");
43
+ const runtime_1 = require("../../nerves/runtime");
44
+ const UNKNOWN_METADATA = "unknown";
45
+ function optionalFunction(target, key) {
46
+ try {
47
+ const candidate = target[key];
48
+ return typeof candidate === "function" ? candidate : null;
49
+ }
50
+ catch {
51
+ return null;
52
+ }
53
+ }
54
+ function readVersion(packageJsonPath, readFileSyncImpl) {
55
+ try {
56
+ const parsed = JSON.parse(readFileSyncImpl(packageJsonPath, "utf-8"));
57
+ return typeof parsed.version === "string" && parsed.version.trim().length > 0
58
+ ? parsed.version.trim()
59
+ : UNKNOWN_METADATA;
60
+ }
61
+ catch {
62
+ return UNKNOWN_METADATA;
63
+ }
64
+ }
65
+ function readLastUpdated(repoRoot, packageJsonPath, statSyncImpl, execFileSyncImpl) {
66
+ try {
67
+ const raw = execFileSyncImpl("git", ["log", "-1", "--format=%cI"], {
68
+ cwd: repoRoot,
69
+ encoding: "utf-8",
70
+ stdio: ["ignore", "pipe", "ignore"],
71
+ }).trim();
72
+ if (raw.length > 0) {
73
+ return { value: raw, source: "git" };
74
+ }
75
+ }
76
+ catch {
77
+ // fall through to mtime fallback
78
+ }
79
+ try {
80
+ const stats = statSyncImpl(packageJsonPath);
81
+ return {
82
+ value: stats.mtime.toISOString(),
83
+ source: "package-json-mtime",
84
+ };
85
+ }
86
+ catch {
87
+ return { value: UNKNOWN_METADATA, source: "unknown" };
88
+ }
89
+ }
90
+ function readHomeDir() {
91
+ const homedirImpl = optionalFunction(os, "homedir");
92
+ if (!homedirImpl) {
93
+ return null;
94
+ }
95
+ try {
96
+ return homedirImpl.call(os);
97
+ }
98
+ catch {
99
+ return null;
100
+ }
101
+ }
102
+ function listConfigTargets(bundlesRoot, secretsRoot, daemonLoggingPath, readdirSyncImpl) {
103
+ if (!readdirSyncImpl)
104
+ return [];
105
+ const targets = new Set();
106
+ if (daemonLoggingPath) {
107
+ targets.add(daemonLoggingPath);
108
+ }
109
+ try {
110
+ const bundleEntries = readdirSyncImpl(bundlesRoot, { withFileTypes: true });
111
+ for (const entry of bundleEntries) {
112
+ if (!entry.isDirectory() || !entry.name.endsWith(".ouro"))
113
+ continue;
114
+ targets.add(path.join(bundlesRoot, entry.name, "agent.json"));
115
+ }
116
+ }
117
+ catch {
118
+ // ignore unreadable bundle roots
119
+ }
120
+ if (secretsRoot) {
121
+ try {
122
+ const secretEntries = readdirSyncImpl(secretsRoot, { withFileTypes: true });
123
+ for (const entry of secretEntries) {
124
+ if (!entry.isDirectory())
125
+ continue;
126
+ targets.add(path.join(secretsRoot, entry.name, "secrets.json"));
127
+ }
128
+ }
129
+ catch {
130
+ // ignore unreadable secrets roots
131
+ }
132
+ }
133
+ return [...targets].sort();
134
+ }
135
+ function readConfigFingerprint(targets, readFileSyncImpl, existsSyncImpl) {
136
+ if (!readFileSyncImpl || !existsSyncImpl) {
137
+ return {
138
+ value: UNKNOWN_METADATA,
139
+ source: "unknown",
140
+ trackedFiles: targets.length,
141
+ presentFiles: 0,
142
+ };
143
+ }
144
+ const hash = (0, crypto_1.createHash)("sha256");
145
+ let presentFiles = 0;
146
+ for (const target of targets) {
147
+ hash.update(target);
148
+ hash.update("\0");
149
+ if (!existsSyncImpl(target)) {
150
+ hash.update("missing");
151
+ hash.update("\0");
152
+ continue;
153
+ }
154
+ presentFiles += 1;
155
+ hash.update("present");
156
+ hash.update("\0");
157
+ try {
158
+ hash.update(readFileSyncImpl(target, "utf-8"));
159
+ }
160
+ catch {
161
+ hash.update("unreadable");
162
+ }
163
+ hash.update("\0");
164
+ }
165
+ return {
166
+ value: hash.digest("hex"),
167
+ source: "content-hash",
168
+ trackedFiles: targets.length,
169
+ presentFiles,
170
+ };
171
+ }
172
+ function getRuntimeMetadata(deps = {}) {
173
+ const repoRoot = deps.repoRoot ?? (0, identity_1.getRepoRoot)();
174
+ const bundlesRoot = deps.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
175
+ const homeDir = readHomeDir();
176
+ const secretsRoot = deps.secretsRoot ?? (homeDir ? path.join(homeDir, ".agentsecrets") : null);
177
+ const daemonLoggingPath = deps.daemonLoggingPath ?? (0, identity_1.getAgentDaemonLoggingConfigPath)();
178
+ const readFileSyncImpl = deps.readFileSync ?? optionalFunction(fs, "readFileSync")?.bind(fs) ?? null;
179
+ const statSyncImpl = deps.statSync ?? optionalFunction(fs, "statSync")?.bind(fs) ?? null;
180
+ const readdirSyncImpl = deps.readdirSync ?? optionalFunction(fs, "readdirSync")?.bind(fs) ?? null;
181
+ const existsSyncImpl = deps.existsSync ?? optionalFunction(fs, "existsSync")?.bind(fs) ?? null;
182
+ const execFileSyncImpl = deps.execFileSync
183
+ ?? optionalFunction(childProcess, "execFileSync")?.bind(childProcess)
184
+ ?? null;
185
+ const packageJsonPath = path.join(repoRoot, "package.json");
186
+ const version = readFileSyncImpl
187
+ ? readVersion(packageJsonPath, readFileSyncImpl)
188
+ : UNKNOWN_METADATA;
189
+ const lastUpdated = statSyncImpl
190
+ ? readLastUpdated(repoRoot, packageJsonPath, statSyncImpl, execFileSyncImpl ?? (() => {
191
+ throw new Error("git unavailable");
192
+ }))
193
+ : { value: UNKNOWN_METADATA, source: "unknown" };
194
+ const configTargets = listConfigTargets(bundlesRoot, secretsRoot, daemonLoggingPath, readdirSyncImpl);
195
+ const configFingerprint = readConfigFingerprint(configTargets, readFileSyncImpl, existsSyncImpl);
196
+ (0, runtime_1.emitNervesEvent)({
197
+ component: "daemon",
198
+ event: "daemon.runtime_metadata_read",
199
+ message: "read runtime metadata",
200
+ meta: {
201
+ version,
202
+ lastUpdated: lastUpdated.value,
203
+ lastUpdatedSource: lastUpdated.source,
204
+ repoRoot,
205
+ configFingerprint: configFingerprint.value === UNKNOWN_METADATA
206
+ ? UNKNOWN_METADATA
207
+ : configFingerprint.value.slice(0, 12),
208
+ configFingerprintSource: configFingerprint.source,
209
+ configTrackedFiles: configFingerprint.trackedFiles,
210
+ configPresentFiles: configFingerprint.presentFiles,
211
+ },
212
+ });
213
+ return {
214
+ version,
215
+ lastUpdated: lastUpdated.value,
216
+ repoRoot,
217
+ configFingerprint: configFingerprint.value,
218
+ };
219
+ }
@@ -0,0 +1,67 @@
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.detectRuntimeMode = detectRuntimeMode;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const runtime_1 = require("../../nerves/runtime");
40
+ function detectRuntimeMode(rootPath, deps = {}) {
41
+ const checkExists = deps.existsSync ?? fs.existsSync;
42
+ // 1. Production: installed via npm
43
+ if (rootPath.includes("node_modules/@ouro.bot/cli") ||
44
+ rootPath.includes("node_modules/ouro.bot")) {
45
+ (0, runtime_1.emitNervesEvent)({
46
+ component: "daemon",
47
+ event: "daemon.runtime_mode_detected",
48
+ message: "detected runtime mode",
49
+ meta: { rootPath, mode: "production" },
50
+ });
51
+ return "production";
52
+ }
53
+ // 2-4. Everything else is dev: worktrees, git repos, unknown paths
54
+ // (conservative default: assume dev unless proven production)
55
+ const reason = rootPath.includes(".claude/worktrees/")
56
+ ? "worktree"
57
+ : checkExists(path.join(rootPath, ".git"))
58
+ ? "git-repo"
59
+ : "unknown";
60
+ (0, runtime_1.emitNervesEvent)({
61
+ component: "daemon",
62
+ event: "daemon.runtime_mode_detected",
63
+ message: "detected runtime mode",
64
+ meta: { rootPath, mode: "dev", reason },
65
+ });
66
+ return "dev";
67
+ }
@@ -0,0 +1,161 @@
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.SAFE_MODE_OVERRIDE_FILENAME = void 0;
37
+ exports.detectSafeMode = detectSafeMode;
38
+ exports.pruneOldCrashes = pruneOldCrashes;
39
+ const fs = __importStar(require("fs"));
40
+ const path = __importStar(require("path"));
41
+ const runtime_1 = require("../../nerves/runtime");
42
+ exports.SAFE_MODE_OVERRIDE_FILENAME = "safe-mode-override.json";
43
+ /** 3+ crashes within this window triggers safe mode */
44
+ const CRASH_WINDOW_MS = 5 * 60 * 1000; // 5 minutes
45
+ const CRASH_THRESHOLD = 3;
46
+ /**
47
+ * Reads crash history from the tombstone file and determines if safe mode should be active.
48
+ * Returns active if 3+ crashes occurred within 5 minutes.
49
+ *
50
+ * Safe mode is bypassed when:
51
+ * - devMode is true
52
+ * - A safe-mode override file exists (written by `ouro up --force`)
53
+ */
54
+ function detectSafeMode(tombstonePath, options) {
55
+ const inactive = { active: false, reason: "", enteredAt: "" };
56
+ // Dev mode: never enter safe mode
57
+ if (options?.devMode) {
58
+ return inactive;
59
+ }
60
+ // Check for override file (--force)
61
+ const overridePath = path.join(path.dirname(tombstonePath), exports.SAFE_MODE_OVERRIDE_FILENAME);
62
+ try {
63
+ if (fs.existsSync(overridePath)) {
64
+ return inactive;
65
+ }
66
+ }
67
+ catch {
68
+ // Best-effort check
69
+ }
70
+ // Read tombstone
71
+ let parsed;
72
+ try {
73
+ const raw = fs.readFileSync(tombstonePath, "utf-8");
74
+ parsed = JSON.parse(raw);
75
+ }
76
+ catch {
77
+ return inactive;
78
+ }
79
+ // Extract recentCrashes
80
+ if (!Array.isArray(parsed.recentCrashes)) {
81
+ return inactive;
82
+ }
83
+ const nowMs = options?.now ? options.now() : Date.now();
84
+ const windowStart = nowMs - CRASH_WINDOW_MS;
85
+ // Filter to valid string timestamps within the crash window
86
+ const recentInWindow = parsed.recentCrashes.filter((entry) => {
87
+ if (typeof entry !== "string")
88
+ return false;
89
+ const ts = new Date(entry).getTime();
90
+ if (isNaN(ts))
91
+ return false;
92
+ return ts >= windowStart;
93
+ });
94
+ if (recentInWindow.length < CRASH_THRESHOLD) {
95
+ return inactive;
96
+ }
97
+ const result = {
98
+ active: true,
99
+ reason: `crash loop detected: ${recentInWindow.length} crashes in last 5 minutes`,
100
+ enteredAt: new Date(nowMs).toISOString(),
101
+ };
102
+ (0, runtime_1.emitNervesEvent)({
103
+ level: "error",
104
+ component: "daemon",
105
+ event: "daemon.safe_mode_entered",
106
+ message: result.reason,
107
+ meta: {
108
+ crashCount: recentInWindow.length,
109
+ windowMs: CRASH_WINDOW_MS,
110
+ tombstonePath,
111
+ },
112
+ });
113
+ return result;
114
+ }
115
+ /**
116
+ * Prunes crash entries older than 5 minutes from the tombstone's recentCrashes.
117
+ * Also removes the safe-mode override file if present.
118
+ * Called after successful startup (uptime > stability threshold).
119
+ */
120
+ function pruneOldCrashes(tombstonePath, options) {
121
+ // Remove override file
122
+ const overridePath = path.join(path.dirname(tombstonePath), exports.SAFE_MODE_OVERRIDE_FILENAME);
123
+ try {
124
+ if (fs.existsSync(overridePath)) {
125
+ fs.unlinkSync(overridePath);
126
+ }
127
+ }
128
+ catch {
129
+ // Best-effort
130
+ }
131
+ // Read existing tombstone
132
+ let parsed;
133
+ try {
134
+ const raw = fs.readFileSync(tombstonePath, "utf-8");
135
+ parsed = JSON.parse(raw);
136
+ }
137
+ catch {
138
+ return;
139
+ }
140
+ if (!Array.isArray(parsed.recentCrashes)) {
141
+ return;
142
+ }
143
+ const nowMs = options?.now ? options.now() : Date.now();
144
+ const windowStart = nowMs - CRASH_WINDOW_MS;
145
+ // Keep only entries within the window
146
+ const pruned = parsed.recentCrashes.filter((entry) => {
147
+ if (typeof entry !== "string")
148
+ return false;
149
+ const ts = new Date(entry).getTime();
150
+ if (isNaN(ts))
151
+ return false;
152
+ return ts >= windowStart;
153
+ });
154
+ parsed.recentCrashes = pruned;
155
+ try {
156
+ fs.writeFileSync(tombstonePath, JSON.stringify(parsed, null, 2) + "\n", "utf-8");
157
+ }
158
+ catch {
159
+ // Best-effort
160
+ }
161
+ }