@ouro.bot/cli 0.1.0-alpha.379 → 0.1.0-alpha.380

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,14 @@
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.380",
6
+ "changes": [
7
+ "Daemon startup now supplements pidfile cleanup with the scoped orphan-process scan, so a partial stale pidfile cannot leave an older daemon process alive after `ouro up` replaces the runtime.",
8
+ "`ouro status` now keeps vault runtime/config failures compact in sense rows, replacing multi-line vault-lock explanations with a direct `ouro vault unlock --agent <agent>` hint.",
9
+ "`@ouro.bot/cli` and the `ouro.bot` wrapper are version-synced for the daemon/status polish release."
10
+ ]
11
+ },
4
12
  {
5
13
  "version": "0.1.0-alpha.379",
6
14
  "changes": [
@@ -36,6 +36,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.OuroDaemon = void 0;
37
37
  exports.parseOrphanPidsFromPs = parseOrphanPidsFromPs;
38
38
  exports.filterPidfilePidsToActualOrphans = filterPidfilePidsToActualOrphans;
39
+ exports.mergeUniqueOrphanPids = mergeUniqueOrphanPids;
39
40
  exports.killOrphanProcesses = killOrphanProcesses;
40
41
  exports.writePidfile = writePidfile;
41
42
  exports.handleAgentSenseTurn = handleAgentSenseTurn;
@@ -162,6 +163,19 @@ function filterPidfilePidsToActualOrphans(candidatePids, psRunner = runPsCheck)
162
163
  }
163
164
  return survivingOrphans;
164
165
  }
166
+ function mergeUniqueOrphanPids(...sources) {
167
+ const merged = [];
168
+ const seen = new Set();
169
+ for (const source of sources) {
170
+ for (const pid of source) {
171
+ if (seen.has(pid))
172
+ continue;
173
+ seen.add(pid);
174
+ merged.push(pid);
175
+ }
176
+ }
177
+ return merged;
178
+ }
165
179
  /* v8 ignore start -- shells out to ps; covered by filterPidfilePidsToActualOrphans unit tests via injected runner @preserve */
166
180
  function runPsCheck(pids) {
167
181
  try {
@@ -203,7 +217,8 @@ function killOrphanProcesses() {
203
217
  return;
204
218
  }
205
219
  try {
206
- let pidsToKill = [];
220
+ let pidfileOrphans = [];
221
+ let scanOrphans = [];
207
222
  // Primary: read pidfile from previous daemon
208
223
  try {
209
224
  const raw = fs.readFileSync(PIDFILE_PATH, "utf-8");
@@ -212,19 +227,21 @@ function killOrphanProcesses() {
212
227
  .filter((n) => !isNaN(n) && n !== process.pid);
213
228
  // Verify each candidate is an actual live orphan before killing. See
214
229
  // docstring above for why this matters.
215
- pidsToKill = filterPidfilePidsToActualOrphans(candidates);
230
+ pidfileOrphans = filterPidfilePidsToActualOrphans(candidates);
216
231
  fs.unlinkSync(PIDFILE_PATH);
217
232
  }
218
233
  catch {
219
- // No pidfile — fall back to ps scan (scoped to orphans with PPID=1).
234
+ // No pidfile — the ps scan below still covers true orphans.
220
235
  }
221
- if (pidsToKill.length === 0) {
222
- try {
223
- const result = (0, child_process_1.execSync)("ps -eo pid,ppid,command", { encoding: "utf-8", timeout: 5000 });
224
- pidsToKill = parseOrphanPidsFromPs(result, process.pid);
225
- }
226
- catch { /* ps failed — best effort */ }
236
+ // Always supplement the pidfile with the scoped ps scan. A stale or
237
+ // partial pidfile can otherwise kill one old daemon while leaving a
238
+ // sibling PPID=1 daemon alive without a socket.
239
+ try {
240
+ const result = (0, child_process_1.execSync)("ps -eo pid,ppid,command", { encoding: "utf-8", timeout: 5000 });
241
+ scanOrphans = parseOrphanPidsFromPs(result, process.pid);
227
242
  }
243
+ catch { /* ps failed — best effort */ }
244
+ const pidsToKill = mergeUniqueOrphanPids(pidfileOrphans, scanOrphans);
228
245
  if (pidsToKill.length > 0) {
229
246
  for (const pid of pidsToKill) {
230
247
  try {
@@ -96,6 +96,20 @@ function numberField(record, key, fallback) {
96
96
  const value = record?.[key];
97
97
  return typeof value === "number" && Number.isFinite(value) ? value : fallback;
98
98
  }
99
+ function compactRuntimeConfigError(agent, error) {
100
+ const compact = error.replace(/\s+/g, " ").trim();
101
+ if (/credential vault is locked|vault locked|vault is locked/i.test(compact)) {
102
+ return `vault locked; run 'ouro vault unlock --agent ${agent}'`;
103
+ }
104
+ return compact || "unavailable";
105
+ }
106
+ function runtimeConfigUnavailableDetail(agent, runtimeConfig) {
107
+ if (runtimeConfig.ok)
108
+ return "";
109
+ if (runtimeConfig.reason === "missing")
110
+ return `missing vault runtime/config (${agent})`;
111
+ return `vault runtime/config unavailable (${compactRuntimeConfigError(agent, runtimeConfig.error)})`;
112
+ }
99
113
  function senseFactsFromRuntimeConfig(agent, senses, runtimeConfig) {
100
114
  const base = {
101
115
  cli: { configured: true, detail: "local interactive terminal" },
@@ -103,11 +117,7 @@ function senseFactsFromRuntimeConfig(agent, senses, runtimeConfig) {
103
117
  bluebubbles: { configured: false, detail: "not enabled in agent.json" },
104
118
  };
105
119
  const payload = runtimeConfig.ok ? runtimeConfig.config : {};
106
- const unavailableDetail = runtimeConfig.ok
107
- ? ""
108
- : runtimeConfig.reason === "missing"
109
- ? `missing vault runtime/config (${agent})`
110
- : `vault runtime/config unavailable (${runtimeConfig.error})`;
120
+ const unavailableDetail = runtimeConfigUnavailableDetail(agent, runtimeConfig);
111
121
  const teams = payload.teams;
112
122
  const teamsChannel = payload.teamsChannel;
113
123
  const bluebubbles = payload.bluebubbles;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.379",
3
+ "version": "0.1.0-alpha.380",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",