@ouro.bot/cli 0.1.0-alpha.700 → 0.1.0-alpha.701

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.
package/changelog.json CHANGED
@@ -1,6 +1,13 @@
1
1
  {
2
2
  "_note": "This changelog is maintained as part of the PR/version-bump workflow. Agent-curated, not auto-generated. Agents read this file directly via read_file to understand what changed between versions.",
3
3
  "versions": [
4
+ {
5
+ "version": "0.1.0-alpha.701",
6
+ "changes": [
7
+ "Retry daemon launchd bootstrap when stale labels make kickstart fail so runtime replacement does not fall back to an unlabelled daemon process.",
8
+ "Keep daemon restart persistence verifiable after native habit scheduler installs launchd jobs."
9
+ ]
10
+ },
4
11
  {
5
12
  "version": "0.1.0-alpha.700",
6
13
  "changes": [
@@ -277,6 +277,21 @@ function readDaemonLaunchAgentPid() {
277
277
  return null;
278
278
  }
279
279
  }
280
+ function launchdExec(cmd) {
281
+ (0, child_process_1.execSync)(cmd, { stdio: "ignore" });
282
+ }
283
+ function bootstrapDaemonLaunchAgent(domain, plistPath) {
284
+ launchdExec(`launchctl bootstrap ${domain} "${plistPath}"`);
285
+ }
286
+ function kickstartDaemonLaunchAgent(domain) {
287
+ launchdExec(`launchctl kickstart -k ${domain}/${launchd_1.DAEMON_PLIST_LABEL}`);
288
+ }
289
+ function bootoutDaemonLaunchAgentLabel(userUid) {
290
+ (0, launchd_1.bootoutLaunchAgentByLabel)({
291
+ exec: launchdExec,
292
+ userUid,
293
+ });
294
+ }
280
295
  async function waitForBootstrappedDaemonSocket(socketPath, deps = {}) {
281
296
  const checkSocketAlive = deps.checkSocketAlive ?? socket_client_1.checkDaemonSocketAlive;
282
297
  const now = deps.now ?? Date.now;
@@ -323,11 +338,41 @@ async function startDaemonProcessViaLaunchd(socketPath) {
323
338
  message: "starting daemon launch agent for current login session",
324
339
  meta: { plistPath, label: launchd_1.DAEMON_PLIST_LABEL },
325
340
  });
326
- if (isDaemonLaunchAgentLoaded({ exec: (cmd) => { (0, child_process_1.execSync)(cmd, { stdio: "ignore" }); }, userUid })) {
327
- (0, child_process_1.execSync)(`launchctl kickstart -k ${domain}/${launchd_1.DAEMON_PLIST_LABEL}`, { stdio: "ignore" });
341
+ if (isDaemonLaunchAgentLoaded({ exec: launchdExec, userUid })) {
342
+ try {
343
+ kickstartDaemonLaunchAgent(domain);
344
+ }
345
+ catch (error) {
346
+ (0, runtime_1.emitNervesEvent)({
347
+ level: "warn",
348
+ component: "daemon",
349
+ event: "daemon.launchd_kickstart_recovering",
350
+ message: "daemon launch agent kickstart failed; clearing label and bootstrapping from plist",
351
+ meta: { plistPath, label: launchd_1.DAEMON_PLIST_LABEL, error: error instanceof Error ? error.message : String(error) },
352
+ });
353
+ try {
354
+ bootoutDaemonLaunchAgentLabel(userUid);
355
+ bootstrapDaemonLaunchAgent(domain, plistPath);
356
+ }
357
+ catch (repairError) {
358
+ (0, runtime_1.emitNervesEvent)({
359
+ level: "warn",
360
+ component: "daemon",
361
+ event: "daemon.launchd_kickstart_recovery_error",
362
+ message: "daemon launch agent kickstart recovery failed; preserving launchd ownership instead of falling back to detached spawn",
363
+ meta: {
364
+ plistPath,
365
+ label: launchd_1.DAEMON_PLIST_LABEL,
366
+ kickstartError: error instanceof Error ? error.message : String(error),
367
+ recoveryError: repairError instanceof Error ? repairError.message : String(repairError),
368
+ },
369
+ });
370
+ return { pid: readDaemonLaunchAgentPid() };
371
+ }
372
+ }
328
373
  }
329
374
  else {
330
- (0, child_process_1.execSync)(`launchctl bootstrap ${domain} "${plistPath}"`, { stdio: "ignore" });
375
+ bootstrapDaemonLaunchAgent(domain, plistPath);
331
376
  }
332
377
  (0, runtime_1.emitNervesEvent)({
333
378
  component: "daemon",
@@ -355,7 +400,7 @@ async function defaultEnsureDaemonBootPersistence(socketPath) {
355
400
  }
356
401
  const plistPath = writeDaemonBootPlist(socketPath);
357
402
  const userUid = currentUserUid();
358
- if (isDaemonLaunchAgentLoaded({ exec: (cmd) => { (0, child_process_1.execSync)(cmd, { stdio: "ignore" }); }, userUid })) {
403
+ if (isDaemonLaunchAgentLoaded({ exec: launchdExec, userUid })) {
359
404
  (0, runtime_1.emitNervesEvent)({
360
405
  component: "daemon",
361
406
  event: "daemon.launchd_bootstrap_skipped_loaded",
@@ -370,7 +415,7 @@ function defaultPrepareDaemonRuntimeReplacement() {
370
415
  return;
371
416
  }
372
417
  (0, launchd_1.bootoutLaunchAgentByLabel)({
373
- exec: (cmd) => { (0, child_process_1.execSync)(cmd, { stdio: "ignore" }); },
418
+ exec: launchdExec,
374
419
  userUid: process.getuid?.() ?? 0,
375
420
  });
376
421
  // launchctl bootout may return before the old daemon's SIGTERM cleanup has
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.700",
3
+ "version": "0.1.0-alpha.701",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",