@ouro.bot/cli 0.1.0-alpha.340 → 0.1.0-alpha.341

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,12 @@
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.341",
6
+ "changes": [
7
+ "`ouro up` and `ouro doctor` now detect when PATH resolves `ouro` to a stale external launcher before the managed `~/.ouro-cli/bin/ouro` wrapper, then print exact path-specific remediation instead of leaving users stuck on an older shim."
8
+ ]
9
+ },
4
10
  {
5
11
  "version": "0.1.0-alpha.340",
6
12
  "changes": [
@@ -485,6 +485,10 @@ async function performSystemSetup(deps) {
485
485
  if (installResult.repairedOldLauncher) {
486
486
  deps.writeStdout("repaired stale ouro launcher at ~/.local/bin/ouro");
487
487
  }
488
+ if (installResult.pathResolution?.status === "shadowed") {
489
+ deps.writeStdout(`fix ouro PATH: ${installResult.pathResolution.detail}; ` +
490
+ `fix: ${installResult.pathResolution.remediation}`);
491
+ }
488
492
  }
489
493
  catch (error) {
490
494
  (0, runtime_1.emitNervesEvent)({
@@ -2252,6 +2256,7 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
2252
2256
  bundlesRoot: deps.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)(),
2253
2257
  secretsRoot: deps.secretsRoot ?? path.join(os.homedir(), ".agentsecrets"),
2254
2258
  homedir: os.homedir(),
2259
+ envPath: process.env.PATH ?? "",
2255
2260
  };
2256
2261
  const doctorResult = await (0, doctor_1.runDoctorChecks)(doctorDeps);
2257
2262
  const output = (0, cli_render_doctor_1.formatDoctorOutput)(doctorResult);
@@ -7,6 +7,7 @@
7
7
  * "fail" check and the remaining categories still run.
8
8
  */
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.checkCliPath = checkCliPath;
10
11
  exports.checkDaemon = checkDaemon;
11
12
  exports.checkAgents = checkAgents;
12
13
  exports.checkSenses = checkSenses;
@@ -16,8 +17,32 @@ exports.checkDisk = checkDisk;
16
17
  exports.runDoctorChecks = runDoctorChecks;
17
18
  const runtime_1 = require("../../nerves/runtime");
18
19
  const bluebubbles_health_diagnostics_1 = require("./bluebubbles-health-diagnostics");
20
+ const ouro_path_installer_1 = require("../versioning/ouro-path-installer");
19
21
  const DEFAULT_BLUEBUBBLES_REQUEST_TIMEOUT_MS = 30_000;
20
22
  // ── Category checkers ──
23
+ function checkCliPath(deps) {
24
+ const resolution = (0, ouro_path_installer_1.diagnoseOuroPath)({
25
+ homeDir: deps.homedir,
26
+ envPath: deps.envPath ?? "",
27
+ existsSync: deps.existsSync,
28
+ readFileSync: (p) => deps.readFileSync(p),
29
+ });
30
+ const status = resolution.status === "ok"
31
+ ? "pass"
32
+ : resolution.status === "shadowed"
33
+ ? "fail"
34
+ : "warn";
35
+ return {
36
+ name: "CLI",
37
+ checks: [{
38
+ label: "ouro PATH resolution",
39
+ status,
40
+ detail: resolution.remediation
41
+ ? `${resolution.detail}; fix: ${resolution.remediation}`
42
+ : resolution.detail,
43
+ }],
44
+ };
45
+ }
21
46
  async function checkDaemon(deps) {
22
47
  const checks = [];
23
48
  const socketExists = deps.existsSync(deps.socketPath);
@@ -365,6 +390,7 @@ function computeSummary(categories) {
365
390
  return { passed, warnings, failed };
366
391
  }
367
392
  const CATEGORY_CHECKERS = [
393
+ { name: "CLI", fn: checkCliPath },
368
394
  { name: "Daemon", fn: checkDaemon },
369
395
  { name: "Agents", fn: checkAgents },
370
396
  { name: "Senses", fn: checkSenses },
@@ -33,6 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.diagnoseOuroPath = diagnoseOuroPath;
36
37
  exports.installOuroCommand = installOuroCommand;
37
38
  const fs = __importStar(require("fs"));
38
39
  const os = __importStar(require("os"));
@@ -80,6 +81,9 @@ function detectShellProfile(homeDir, shell) {
80
81
  function isBinDirInPath(binDir, envPath) {
81
82
  return envPath.split(path.delimiter).some((p) => p === binDir);
82
83
  }
84
+ function samePath(a, b) {
85
+ return path.resolve(a) === path.resolve(b);
86
+ }
83
87
  function buildPathExportLine(binDir, shell) {
84
88
  const base = shell ? path.basename(shell) : /* v8 ignore next -- unreachable: only called when detectShellProfile returns non-null, which requires shell @preserve */ "";
85
89
  if (base === "fish") {
@@ -97,6 +101,56 @@ function isWrapperCurrent(scriptPath, existsSync, readFileSync) {
97
101
  return false;
98
102
  }
99
103
  }
104
+ function firstOuroOnPath(envPath, existsSync) {
105
+ for (const dir of envPath.split(path.delimiter)) {
106
+ if (!dir)
107
+ continue;
108
+ const candidate = path.join(dir, "ouro");
109
+ if (existsSync(candidate))
110
+ return candidate;
111
+ }
112
+ return null;
113
+ }
114
+ function diagnoseOuroPath(deps) {
115
+ const binDir = path.join(deps.homeDir, ".ouro-cli", "bin");
116
+ const expectedPath = path.join(binDir, "ouro");
117
+ const resolvedPath = firstOuroOnPath(deps.envPath, deps.existsSync);
118
+ if (!resolvedPath) {
119
+ return {
120
+ status: "missing",
121
+ expectedPath,
122
+ resolvedPath: null,
123
+ detail: `PATH does not resolve ouro; expected ${expectedPath}`,
124
+ remediation: `add ${binDir} to PATH or open a new shell after ouro up updates your shell profile`,
125
+ };
126
+ }
127
+ if (samePath(resolvedPath, expectedPath)) {
128
+ return {
129
+ status: "ok",
130
+ expectedPath,
131
+ resolvedPath,
132
+ detail: `PATH resolves ouro to ${expectedPath}`,
133
+ remediation: null,
134
+ };
135
+ }
136
+ if (isWrapperCurrent(resolvedPath, deps.existsSync, deps.readFileSync)) {
137
+ return {
138
+ status: "ok",
139
+ expectedPath,
140
+ resolvedPath,
141
+ detail: `PATH resolves ouro through a compatible wrapper at ${resolvedPath}`,
142
+ remediation: null,
143
+ };
144
+ }
145
+ const shadowDir = path.dirname(resolvedPath);
146
+ return {
147
+ status: "shadowed",
148
+ expectedPath,
149
+ resolvedPath,
150
+ detail: `PATH resolves ouro to ${resolvedPath} before ${expectedPath}`,
151
+ remediation: `move ${binDir} before ${shadowDir} in PATH, or remove/replace ${resolvedPath} after confirming it is the stale ouro launcher`,
152
+ };
153
+ }
100
154
  function installOuroCommand(deps = {}) {
101
155
  /* v8 ignore start -- dep defaults: only used in real runtime, tests always inject @preserve */
102
156
  const platform = deps.platform ?? process.platform;
@@ -126,6 +180,7 @@ function installOuroCommand(deps = {}) {
126
180
  const binDir = path.join(homeDir, ".ouro-cli", "bin");
127
181
  const scriptPath = path.join(binDir, "ouro");
128
182
  const oldScriptPath = path.join(homeDir, ".local", "bin", "ouro");
183
+ const resolvePath = () => diagnoseOuroPath({ homeDir, envPath, existsSync, readFileSync });
129
184
  const modernCurrent = isWrapperCurrent(scriptPath, existsSync, readFileSync);
130
185
  const oldExists = existsSync(oldScriptPath);
131
186
  const oldCurrent = oldExists && isWrapperCurrent(oldScriptPath, existsSync, readFileSync);
@@ -152,13 +207,23 @@ function installOuroCommand(deps = {}) {
152
207
  }
153
208
  // ── Fast-path: modern wrapper already current ──
154
209
  if (modernCurrent) {
210
+ const pathResolution = resolvePath();
211
+ if (pathResolution.status === "shadowed") {
212
+ (0, runtime_1.emitNervesEvent)({
213
+ level: "warn",
214
+ component: "daemon",
215
+ event: "daemon.ouro_path_shadowed",
216
+ message: "PATH resolves ouro to a stale external launcher",
217
+ meta: { resolvedPath: pathResolution.resolvedPath, expectedPath: pathResolution.expectedPath, remediation: pathResolution.remediation },
218
+ });
219
+ }
155
220
  (0, runtime_1.emitNervesEvent)({
156
221
  component: "daemon",
157
222
  event: "daemon.ouro_path_install_skip",
158
223
  message: "ouro command already installed",
159
- meta: { scriptPath },
224
+ meta: { scriptPath, pathStatus: pathResolution.status, resolvedPath: pathResolution.resolvedPath },
160
225
  });
161
- return { installed: false, scriptPath, pathReady: isBinDirInPath(binDir, envPath), shellProfileUpdated: null, skippedReason: "already-installed", repairedOldLauncher };
226
+ return { installed: false, scriptPath, pathReady: isBinDirInPath(binDir, envPath), shellProfileUpdated: null, skippedReason: "already-installed", repairedOldLauncher, pathResolution };
162
227
  }
163
228
  (0, runtime_1.emitNervesEvent)({
164
229
  component: "daemon",
@@ -211,11 +276,21 @@ function installOuroCommand(deps = {}) {
211
276
  }
212
277
  }
213
278
  }
279
+ const pathResolution = resolvePath();
280
+ if (pathResolution.status === "shadowed") {
281
+ (0, runtime_1.emitNervesEvent)({
282
+ level: "warn",
283
+ component: "daemon",
284
+ event: "daemon.ouro_path_shadowed",
285
+ message: "PATH resolves ouro to a stale external launcher",
286
+ meta: { resolvedPath: pathResolution.resolvedPath, expectedPath: pathResolution.expectedPath, remediation: pathResolution.remediation },
287
+ });
288
+ }
214
289
  (0, runtime_1.emitNervesEvent)({
215
290
  component: "daemon",
216
291
  event: "daemon.ouro_path_install_end",
217
292
  message: "ouro command installed",
218
- meta: { scriptPath, pathReady, shellProfileUpdated, oldScriptPath: oldExists ? oldScriptPath : null },
293
+ meta: { scriptPath, pathReady, shellProfileUpdated, oldScriptPath: oldExists ? oldScriptPath : null, pathStatus: pathResolution.status, resolvedPath: pathResolution.resolvedPath },
219
294
  });
220
- return { installed: true, scriptPath, pathReady, shellProfileUpdated, repairedOldLauncher };
295
+ return { installed: true, scriptPath, pathReady, shellProfileUpdated, repairedOldLauncher, pathResolution };
221
296
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.340",
3
+ "version": "0.1.0-alpha.341",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",