@ouro.bot/cli 0.1.0-alpha.726 → 0.1.0-alpha.728

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 (35) hide show
  1. package/README.md +14 -1
  2. package/assets/bluebubbles-host +264 -0
  3. package/changelog.json +18 -0
  4. package/dist/heart/config.js +1 -2
  5. package/dist/heart/core.js +181 -209
  6. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  7. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  8. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  9. package/dist/heart/daemon/cli-defaults.js +8 -1
  10. package/dist/heart/daemon/cli-exec.js +239 -34
  11. package/dist/heart/daemon/cli-help.js +17 -6
  12. package/dist/heart/daemon/cli-parse.js +69 -1
  13. package/dist/heart/daemon/cli-render.js +7 -0
  14. package/dist/heart/daemon/daemon.js +79 -14
  15. package/dist/heart/daemon/doctor.js +21 -1
  16. package/dist/heart/daemon/mcp-canary.js +160 -29
  17. package/dist/heart/daemon/process-manager.js +100 -18
  18. package/dist/heart/daemon/socket-client.js +28 -19
  19. package/dist/heart/providers/anthropic.js +17 -12
  20. package/dist/heart/streaming.js +6 -6
  21. package/dist/heart/versioning/ouro-path-installer.js +30 -24
  22. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  23. package/dist/heart/versioning/version-intent.js +114 -0
  24. package/dist/mind/prompt-budget.js +104 -5
  25. package/dist/repertoire/tools.js +0 -10
  26. package/dist/senses/bluebubbles/client.js +43 -57
  27. package/dist/senses/bluebubbles/context-packet.js +104 -19
  28. package/dist/senses/bluebubbles/entry.js +14 -1
  29. package/dist/senses/bluebubbles/index.js +1398 -719
  30. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  31. package/dist/senses/bluebubbles/outbound-state.js +4 -0
  32. package/dist/senses/bluebubbles/reaction-policy.js +4 -12
  33. package/dist/senses/bluebubbles/semantic-receipts.js +178 -10
  34. package/dist/senses/bluebubbles/webhook-registration.js +228 -0
  35. package/package.json +4 -2
@@ -0,0 +1,273 @@
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
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
36
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.BLUEBUBBLES_LAUNCH_AGENT_LABEL = exports.BLUEBUBBLES_EXECUTABLE_PATH = exports.BLUEBUBBLES_APP_PATH = void 0;
40
+ exports.blueBubblesLaunchAgentPlist = blueBubblesLaunchAgentPlist;
41
+ exports.blueBubblesLaunchAgentPath = blueBubblesLaunchAgentPath;
42
+ exports.inspectBlueBubblesHost = inspectBlueBubblesHost;
43
+ exports.runBlueBubblesHostAction = runBlueBubblesHostAction;
44
+ exports.createDefaultBlueBubblesHostDeps = createDefaultBlueBubblesHostDeps;
45
+ const child_process_1 = require("child_process");
46
+ const fs = __importStar(require("fs"));
47
+ const os = __importStar(require("os"));
48
+ const path = __importStar(require("path"));
49
+ const runtime_1 = require("../../nerves/runtime");
50
+ exports.BLUEBUBBLES_APP_PATH = "/Applications/BlueBubbles.app";
51
+ exports.BLUEBUBBLES_EXECUTABLE_PATH = `${exports.BLUEBUBBLES_APP_PATH}/Contents/MacOS/BlueBubbles`;
52
+ exports.BLUEBUBBLES_LAUNCH_AGENT_LABEL = "com.bluebubbles.server";
53
+ function blueBubblesLaunchAgentPlist(appExecutablePath = exports.BLUEBUBBLES_EXECUTABLE_PATH) {
54
+ return `<?xml version="1.0" encoding="UTF-8"?>
55
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
56
+ <plist version="1.0">
57
+ <dict>
58
+ <key>AssociatedBundleIdentifiers</key>
59
+ <array>
60
+ <string>com.BlueBubbles.BlueBubbles-Server</string>
61
+ </array>
62
+ <key>Label</key>
63
+ <string>com.bluebubbles.server</string>
64
+ <key>Program</key>
65
+ <string>${appExecutablePath}</string>
66
+ <key>RunAtLoad</key>
67
+ <true/>
68
+ <key>KeepAlive</key>
69
+ <dict>
70
+ <key>SuccessfulExit</key>
71
+ <false/>
72
+ <key>Crashed</key>
73
+ <true/>
74
+ </dict>
75
+ </dict>
76
+ </plist>`;
77
+ }
78
+ function blueBubblesLaunchAgentPath(homeDir) {
79
+ return path.join(homeDir, "Library", "LaunchAgents", `${exports.BLUEBUBBLES_LAUNCH_AGENT_LABEL}.plist`);
80
+ }
81
+ function requireMacOS(deps) {
82
+ if (deps.platform !== "darwin")
83
+ throw new Error("BlueBubbles host lifecycle requires macOS");
84
+ }
85
+ function launchdDomain(deps) {
86
+ return `gui/${deps.uid}`;
87
+ }
88
+ function serviceTarget(deps) {
89
+ return `${launchdDomain(deps)}/${exports.BLUEBUBBLES_LAUNCH_AGENT_LABEL}`;
90
+ }
91
+ function requireLaunchctl(result, operation) {
92
+ if (!result.ok)
93
+ throw new Error(`launchctl ${operation} failed: ${result.detail}`);
94
+ }
95
+ async function inspectBlueBubblesHost(deps) {
96
+ requireMacOS(deps);
97
+ const plistPath = blueBubblesLaunchAgentPath(deps.homeDir);
98
+ const expectedPlist = blueBubblesLaunchAgentPlist();
99
+ let plist = "missing";
100
+ if (deps.existsSync(plistPath)) {
101
+ try {
102
+ plist = deps.readFileSync(plistPath) === expectedPlist ? "current" : "drifted";
103
+ }
104
+ catch {
105
+ plist = "drifted";
106
+ }
107
+ }
108
+ const launchd = deps.launchctl(["print", serviceTarget(deps)]);
109
+ const http = deps.probeHttp
110
+ ? await deps.probeHttp()
111
+ : { ok: null, detail: "HTTP health was not configured for this host inspection" };
112
+ const state = {
113
+ app: deps.existsSync(exports.BLUEBUBBLES_APP_PATH) ? "present" : "missing",
114
+ plist,
115
+ service: launchd.ok ? "loaded" : "not-loaded",
116
+ serviceDetail: launchd.detail,
117
+ process: deps.isProcessRunning() ? "running" : "not-running",
118
+ http,
119
+ plistPath,
120
+ launchdDomain: launchdDomain(deps),
121
+ launchAgentLabel: exports.BLUEBUBBLES_LAUNCH_AGENT_LABEL,
122
+ };
123
+ (0, runtime_1.emitNervesEvent)({
124
+ component: "daemon",
125
+ event: "daemon.bluebubbles_host_inspected",
126
+ message: "inspected native BlueBubbles host lifecycle",
127
+ meta: {
128
+ app: state.app,
129
+ plist: state.plist,
130
+ service: state.service,
131
+ process: state.process,
132
+ httpOk: state.http.ok,
133
+ launchdDomain: state.launchdDomain,
134
+ },
135
+ });
136
+ return state;
137
+ }
138
+ function writeNativePlist(deps, plistPath) {
139
+ deps.mkdirSync(path.dirname(plistPath), { recursive: true });
140
+ deps.writeFileSync(plistPath, blueBubblesLaunchAgentPlist(), { mode: 0o644 });
141
+ }
142
+ function reloadNativeService(deps, plistPath, wasLoaded) {
143
+ const target = serviceTarget(deps);
144
+ const domain = launchdDomain(deps);
145
+ if (wasLoaded)
146
+ requireLaunchctl(deps.launchctl(["bootout", target]), "bootout");
147
+ requireLaunchctl(deps.launchctl(["disable", target]), "disable");
148
+ requireLaunchctl(deps.launchctl(["enable", target]), "enable");
149
+ requireLaunchctl(deps.launchctl(["bootstrap", domain, plistPath]), "bootstrap");
150
+ }
151
+ async function runBlueBubblesHostAction(action, deps) {
152
+ requireMacOS(deps);
153
+ (0, runtime_1.emitNervesEvent)({
154
+ component: "daemon",
155
+ event: "daemon.bluebubbles_host_action_start",
156
+ message: "starting native BlueBubbles host lifecycle action",
157
+ meta: { action, uid: deps.uid },
158
+ });
159
+ try {
160
+ const before = await inspectBlueBubblesHost(deps);
161
+ let changed = false;
162
+ if (action === "status") {
163
+ (0, runtime_1.emitNervesEvent)({
164
+ component: "daemon",
165
+ event: "daemon.bluebubbles_host_action_end",
166
+ message: "completed native BlueBubbles host lifecycle action",
167
+ meta: { action, changed: false, service: before.service },
168
+ });
169
+ return { action, changed: false, state: before };
170
+ }
171
+ if (action === "remove") {
172
+ if (before.service === "loaded") {
173
+ requireLaunchctl(deps.launchctl(["disable", serviceTarget(deps)]), "disable");
174
+ requireLaunchctl(deps.launchctl(["bootout", serviceTarget(deps)]), "bootout");
175
+ changed = true;
176
+ }
177
+ if (before.plist !== "missing") {
178
+ deps.unlinkSync(before.plistPath);
179
+ changed = true;
180
+ }
181
+ const state = changed ? await inspectBlueBubblesHost(deps) : before;
182
+ (0, runtime_1.emitNervesEvent)({
183
+ component: "daemon",
184
+ event: "daemon.bluebubbles_host_action_end",
185
+ message: "completed native BlueBubbles host lifecycle action",
186
+ meta: { action, changed, service: state.service },
187
+ });
188
+ return { action, changed, state };
189
+ }
190
+ if (before.app === "missing") {
191
+ throw new Error(`BlueBubbles app is missing at ${exports.BLUEBUBBLES_APP_PATH}`);
192
+ }
193
+ const needsPlist = before.plist !== "current";
194
+ if (needsPlist) {
195
+ writeNativePlist(deps, before.plistPath);
196
+ changed = true;
197
+ }
198
+ if (needsPlist || before.service !== "loaded") {
199
+ reloadNativeService(deps, before.plistPath, before.service === "loaded");
200
+ changed = true;
201
+ }
202
+ const state = changed ? await inspectBlueBubblesHost(deps) : before;
203
+ if (state.plist !== "current" || state.service !== "loaded") {
204
+ throw new Error(`BlueBubbles host postcondition failed: plist=${state.plist}, service=${state.service}`);
205
+ }
206
+ (0, runtime_1.emitNervesEvent)({
207
+ component: "daemon",
208
+ event: "daemon.bluebubbles_host_action_end",
209
+ message: "completed native BlueBubbles host lifecycle action",
210
+ meta: { action, changed, service: state.service },
211
+ });
212
+ return { action, changed, state };
213
+ }
214
+ catch (error) {
215
+ (0, runtime_1.emitNervesEvent)({
216
+ component: "daemon",
217
+ event: "daemon.bluebubbles_host_action_error",
218
+ level: "error",
219
+ message: "native BlueBubbles host lifecycle action failed",
220
+ meta: { action, uid: deps.uid, error: error instanceof Error ? error.message : String(error) },
221
+ });
222
+ throw error;
223
+ }
224
+ }
225
+ function createDefaultBlueBubblesHostDeps(input = {}) {
226
+ const serverUrl = input.serverUrl ?? "http://127.0.0.1:1234/";
227
+ const requestTimeoutMs = input.requestTimeoutMs ?? 30_000;
228
+ /* v8 ignore next -- production uses global fetch; unit tests inject the adapter @preserve */
229
+ const fetchImpl = input.fetchImpl ?? fetch;
230
+ const probeHttp = input.probeHttp ?? (async () => {
231
+ try {
232
+ const response = await fetchImpl(serverUrl, {
233
+ method: "GET",
234
+ signal: AbortSignal.timeout(requestTimeoutMs),
235
+ });
236
+ return { ok: true, detail: `HTTP server responded with ${response.status}` };
237
+ }
238
+ catch (error) {
239
+ return { ok: false, detail: error instanceof Error ? error.message : String(error) };
240
+ }
241
+ });
242
+ return {
243
+ platform: process.platform,
244
+ homeDir: os.homedir(),
245
+ uid: process.getuid?.() ?? 0,
246
+ existsSync: fs.existsSync,
247
+ readFileSync: (filePath) => fs.readFileSync(filePath, "utf8"),
248
+ mkdirSync: fs.mkdirSync,
249
+ writeFileSync: (filePath, content, options) => fs.writeFileSync(filePath, content, options),
250
+ unlinkSync: fs.unlinkSync,
251
+ launchctl: (args) => {
252
+ try {
253
+ const stdout = (0, child_process_1.execFileSync)("launchctl", args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
254
+ return { ok: true, detail: stdout.trim() || "ok" };
255
+ }
256
+ catch (error) {
257
+ const detail = error instanceof Error ? error.message : String(error);
258
+ return { ok: false, detail };
259
+ }
260
+ },
261
+ isProcessRunning: () => {
262
+ try {
263
+ (0, child_process_1.execFileSync)("pgrep", ["-f", exports.BLUEBUBBLES_EXECUTABLE_PATH], { stdio: "ignore" });
264
+ return true;
265
+ }
266
+ catch {
267
+ return false;
268
+ }
269
+ },
270
+ probeHttp,
271
+ };
272
+ }
273
+ __exportStar(require("./bluebubbles-host-protocol"), exports);
@@ -65,6 +65,7 @@ const runtime_mode_1 = require("./runtime-mode");
65
65
  const agent_discovery_1 = require("./agent-discovery");
66
66
  const bundle_manifest_1 = require("../../mind/bundle-manifest");
67
67
  const ouro_bot_global_installer_1 = require("../versioning/ouro-bot-global-installer");
68
+ const version_intent_1 = require("../versioning/version-intent");
68
69
  const logs_prune_1 = require("./logs-prune");
69
70
  const daemon_health_1 = require("./daemon-health");
70
71
  const log_tailer_1 = require("./log-tailer");
@@ -702,7 +703,11 @@ async function defaultRunSerpentGuide() {
702
703
  function createDefaultOuroCliDeps(socketPath = socket_client_1.DEFAULT_DAEMON_SOCKET_PATH) {
703
704
  return {
704
705
  socketPath,
705
- sendCommand: socket_client_1.sendDaemonCommand,
706
+ sendCommand: (commandSocketPath, command) => (0, socket_client_1.sendDaemonCommand)(commandSocketPath, command, {
707
+ timeoutMs: command.kind === "daemon.status"
708
+ ? socket_client_1.DEFAULT_DAEMON_STATUS_TIMEOUT_MS
709
+ : socket_client_1.DEFAULT_DAEMON_COMMAND_TIMEOUT_MS,
710
+ }),
706
711
  startDaemonProcess: defaultStartDaemonProcess,
707
712
  writeStdout: defaultWriteStdout,
708
713
  setExitCode: (code) => {
@@ -766,6 +771,8 @@ function createDefaultOuroCliDeps(socketPath = socket_client_1.DEFAULT_DAEMON_SO
766
771
  distTag: update_checker_1.CLI_UPDATE_DIST_TAG,
767
772
  });
768
773
  },
774
+ readVersionIntent: () => (0, version_intent_1.readVersionIntent)(),
775
+ writeVersionIntent: (intent) => (0, version_intent_1.writeVersionIntent)(intent),
769
776
  installCliVersion: async (version) => { (0, ouro_version_manager_1.installVersion)(version, {}); },
770
777
  validateCliVersionForActivation: (version) => (0, ouro_version_manager_1.validateInstalledVersionForActivation)(version, {}),
771
778
  activateCliVersion: (version) => {