@ouro.bot/cli 0.1.0-alpha.431 → 0.1.0-alpha.432
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.432",
|
|
6
|
+
"changes": [
|
|
7
|
+
"`ouro up` no longer risks hanging forever on an unbounded npm registry check during startup; the update-check phase now shows live detail, aborts the stalled fetch after a short shared timeout, and continues booting with truthful status like `skipped; registry did not answer`.",
|
|
8
|
+
"The same bounded update-check helper now powers `ouro versions`, so published-version lookup cannot freeze there either and the human-facing status wording stays consistent across commands.",
|
|
9
|
+
"Focused startup/version coverage plus the full test suite now protect the stalled-registry regression, and `@ouro.bot/cli` plus the `ouro.bot` wrapper are version-synced for the startup freeze fix release."
|
|
10
|
+
]
|
|
11
|
+
},
|
|
4
12
|
{
|
|
5
13
|
"version": "0.1.0-alpha.431",
|
|
6
14
|
"changes": [
|
|
@@ -53,6 +53,7 @@ const runtime_1 = require("../../nerves/runtime");
|
|
|
53
53
|
const ouro_path_installer_1 = require("../versioning/ouro-path-installer");
|
|
54
54
|
const ouro_uti_1 = require("../versioning/ouro-uti");
|
|
55
55
|
const ouro_version_manager_1 = require("../versioning/ouro-version-manager");
|
|
56
|
+
const update_checker_1 = require("../versioning/update-checker");
|
|
56
57
|
const skill_management_installer_1 = require("./skill-management-installer");
|
|
57
58
|
const hatch_flow_1 = require("../hatch/hatch-flow");
|
|
58
59
|
const specialist_orchestrator_1 = require("../hatch/specialist-orchestrator");
|
|
@@ -144,6 +145,29 @@ function defaultReadRecentDaemonLogLines(lines = 10) {
|
|
|
144
145
|
}
|
|
145
146
|
return recentLines.slice(-lines).map((line) => (0, log_tailer_1.formatLogLine)(line));
|
|
146
147
|
}
|
|
148
|
+
/* v8 ignore start -- CLI npm registry fetch wrapper: integration code @preserve */
|
|
149
|
+
async function defaultFetchCliRegistryJson(timeoutMs) {
|
|
150
|
+
const controller = new AbortController();
|
|
151
|
+
const timeoutId = setTimeout(() => {
|
|
152
|
+
controller.abort();
|
|
153
|
+
}, timeoutMs);
|
|
154
|
+
try {
|
|
155
|
+
const res = await fetch("https://registry.npmjs.org/@ouro.bot/cli", {
|
|
156
|
+
signal: controller.signal,
|
|
157
|
+
});
|
|
158
|
+
return res.json();
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
162
|
+
throw new Error(`update check timed out after ${Math.max(1, Math.round(timeoutMs / 1000))}s`);
|
|
163
|
+
}
|
|
164
|
+
throw error;
|
|
165
|
+
}
|
|
166
|
+
finally {
|
|
167
|
+
clearTimeout(timeoutId);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/* v8 ignore stop */
|
|
147
171
|
function defaultSleep(ms) {
|
|
148
172
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
149
173
|
}
|
|
@@ -501,6 +525,7 @@ function createDefaultOuroCliDeps(socketPath = socket_client_1.DEFAULT_DAEMON_SO
|
|
|
501
525
|
readRecentDaemonLogLines: defaultReadRecentDaemonLogLines,
|
|
502
526
|
sleep: defaultSleep,
|
|
503
527
|
now: () => Date.now(),
|
|
528
|
+
updateCheckTimeoutMs: update_checker_1.CLI_UPDATE_CHECK_TIMEOUT_MS,
|
|
504
529
|
startupPollIntervalMs: 250,
|
|
505
530
|
startupStabilityWindowMs: 1_500,
|
|
506
531
|
startupTimeoutMs: 10_000,
|
|
@@ -540,10 +565,7 @@ function createDefaultOuroCliDeps(socketPath = socket_client_1.DEFAULT_DAEMON_SO
|
|
|
540
565
|
checkForCliUpdate: async () => {
|
|
541
566
|
const { checkForUpdate } = await Promise.resolve().then(() => __importStar(require("../versioning/update-checker")));
|
|
542
567
|
return checkForUpdate((0, bundle_manifest_1.getPackageVersion)(), {
|
|
543
|
-
fetchRegistryJson:
|
|
544
|
-
const res = await fetch("https://registry.npmjs.org/@ouro.bot/cli");
|
|
545
|
-
return res.json();
|
|
546
|
-
},
|
|
568
|
+
fetchRegistryJson: () => defaultFetchCliRegistryJson(update_checker_1.CLI_UPDATE_CHECK_TIMEOUT_MS),
|
|
547
569
|
distTag: "latest",
|
|
548
570
|
});
|
|
549
571
|
},
|
|
@@ -76,6 +76,7 @@ const provider_state_1 = require("../provider-state");
|
|
|
76
76
|
const machine_identity_1 = require("../machine-identity");
|
|
77
77
|
const provider_models_1 = require("../provider-models");
|
|
78
78
|
const ouro_version_manager_1 = require("../versioning/ouro-version-manager");
|
|
79
|
+
const update_checker_1 = require("../versioning/update-checker");
|
|
79
80
|
const sync_1 = require("../sync");
|
|
80
81
|
const cli_parse_1 = require("./cli-parse");
|
|
81
82
|
const cli_parse_2 = require("./cli-parse");
|
|
@@ -104,6 +105,55 @@ const DEFAULT_DAEMON_STARTUP_POLL_INTERVAL_MS = 500;
|
|
|
104
105
|
const DEFAULT_DAEMON_STARTUP_STABILITY_WINDOW_MS = 1_500;
|
|
105
106
|
const DEFAULT_DAEMON_STARTUP_RETRY_LIMIT = 1;
|
|
106
107
|
const DEFAULT_DAEMON_STARTUP_LOG_LINES = 10;
|
|
108
|
+
function summarizeCliUpdateCheckStatus(error, timedOut = false) {
|
|
109
|
+
const normalized = error.trim().toLowerCase();
|
|
110
|
+
if (timedOut || normalized.includes("timed out") || normalized.includes("abort")) {
|
|
111
|
+
return "skipped; registry did not answer";
|
|
112
|
+
}
|
|
113
|
+
if (normalized.includes("registry unavailable")) {
|
|
114
|
+
return "skipped; registry unavailable";
|
|
115
|
+
}
|
|
116
|
+
if (normalized.includes("network") ||
|
|
117
|
+
normalized.includes("fetch failed") ||
|
|
118
|
+
normalized.includes("enotfound") ||
|
|
119
|
+
normalized.includes("eai_again") ||
|
|
120
|
+
normalized.includes("econnreset")) {
|
|
121
|
+
return "skipped; registry unavailable";
|
|
122
|
+
}
|
|
123
|
+
return "skipped; update check unavailable";
|
|
124
|
+
}
|
|
125
|
+
async function runCliUpdateCheckWithTimeout(checkForCliUpdate, timeoutMs = update_checker_1.CLI_UPDATE_CHECK_TIMEOUT_MS) {
|
|
126
|
+
return await new Promise((resolve, reject) => {
|
|
127
|
+
let settled = false;
|
|
128
|
+
const timeoutId = setTimeout(() => {
|
|
129
|
+
settled = true;
|
|
130
|
+
resolve({
|
|
131
|
+
timedOut: true,
|
|
132
|
+
result: {
|
|
133
|
+
available: false,
|
|
134
|
+
error: `update check timed out after ${Math.max(1, Math.round(timeoutMs / 1000))}s`,
|
|
135
|
+
},
|
|
136
|
+
});
|
|
137
|
+
}, timeoutMs);
|
|
138
|
+
/* v8 ignore start -- Promise-settlement wiring is exercised by command tests; v8 misses these callback lines @preserve */
|
|
139
|
+
void checkForCliUpdate()
|
|
140
|
+
.then((result) => {
|
|
141
|
+
if (settled)
|
|
142
|
+
return;
|
|
143
|
+
settled = true;
|
|
144
|
+
clearTimeout(timeoutId);
|
|
145
|
+
resolve({ result, timedOut: false });
|
|
146
|
+
})
|
|
147
|
+
.catch((error) => {
|
|
148
|
+
if (settled)
|
|
149
|
+
return;
|
|
150
|
+
settled = true;
|
|
151
|
+
clearTimeout(timeoutId);
|
|
152
|
+
reject(error);
|
|
153
|
+
});
|
|
154
|
+
/* v8 ignore stop */
|
|
155
|
+
});
|
|
156
|
+
}
|
|
107
157
|
async function checkAgentProviders(deps, agentsOverride, onProgress) {
|
|
108
158
|
const agents = agentsOverride ?? await listCliAgents(deps);
|
|
109
159
|
const bundlesRoot = deps.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
|
|
@@ -3590,9 +3640,11 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
3590
3640
|
// ── versioned CLI update check ──
|
|
3591
3641
|
if (deps.checkForCliUpdate) {
|
|
3592
3642
|
progress.startPhase("update check");
|
|
3643
|
+
progress.updateDetail("checking npm registry\ncontinuing startup if it stays quiet");
|
|
3593
3644
|
let pendingReExec = false;
|
|
3645
|
+
let updateCheckStatus = "up to date";
|
|
3594
3646
|
try {
|
|
3595
|
-
const updateResult = await deps.checkForCliUpdate
|
|
3647
|
+
const { result: updateResult, timedOut } = await runCliUpdateCheckWithTimeout(deps.checkForCliUpdate, deps.updateCheckTimeoutMs ?? update_checker_1.CLI_UPDATE_CHECK_TIMEOUT_MS);
|
|
3596
3648
|
if (updateResult.available && updateResult.latestVersion) {
|
|
3597
3649
|
/* v8 ignore next -- fallback: getCurrentCliVersion always injected in tests @preserve */
|
|
3598
3650
|
const currentVersion = linkedVersionBeforeUp ?? "unknown";
|
|
@@ -3606,9 +3658,13 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
3606
3658
|
}
|
|
3607
3659
|
pendingReExec = true;
|
|
3608
3660
|
}
|
|
3661
|
+
else if (updateResult.error) {
|
|
3662
|
+
updateCheckStatus = summarizeCliUpdateCheckStatus(updateResult.error, timedOut);
|
|
3663
|
+
}
|
|
3609
3664
|
/* v8 ignore start -- update check error: tested via daemon-cli-update-flow.test.ts @preserve */
|
|
3610
3665
|
}
|
|
3611
3666
|
catch (error) {
|
|
3667
|
+
updateCheckStatus = summarizeCliUpdateCheckStatus(error instanceof Error ? error.message : String(error));
|
|
3612
3668
|
(0, runtime_1.emitNervesEvent)({
|
|
3613
3669
|
level: "warn",
|
|
3614
3670
|
component: "daemon",
|
|
@@ -3623,7 +3679,7 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
3623
3679
|
deps.reExecFromNewVersion(args);
|
|
3624
3680
|
}
|
|
3625
3681
|
else {
|
|
3626
|
-
progress.completePhase("update check",
|
|
3682
|
+
progress.completePhase("update check", updateCheckStatus);
|
|
3627
3683
|
}
|
|
3628
3684
|
}
|
|
3629
3685
|
progress.startPhase("system setup");
|
|
@@ -4028,16 +4084,16 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
4028
4084
|
const sections = [localSection];
|
|
4029
4085
|
if (deps.checkForCliUpdate) {
|
|
4030
4086
|
try {
|
|
4031
|
-
const updateResult = await deps.checkForCliUpdate
|
|
4087
|
+
const { result: updateResult, timedOut } = await runCliUpdateCheckWithTimeout(deps.checkForCliUpdate, deps.updateCheckTimeoutMs ?? update_checker_1.CLI_UPDATE_CHECK_TIMEOUT_MS);
|
|
4032
4088
|
if (updateResult.latestVersion) {
|
|
4033
4089
|
sections.push(`published latest: ${updateResult.latestVersion} (${updateResult.available ? "update available" : "up to date"})`);
|
|
4034
4090
|
}
|
|
4035
4091
|
else if (updateResult.error) {
|
|
4036
|
-
sections.push(`published latest: unavailable (${updateResult.error})`);
|
|
4092
|
+
sections.push(`published latest: unavailable (${summarizeCliUpdateCheckStatus(updateResult.error, timedOut)})`);
|
|
4037
4093
|
}
|
|
4038
4094
|
}
|
|
4039
4095
|
catch (err) {
|
|
4040
|
-
const reason = err instanceof Error ? err.message : String(err);
|
|
4096
|
+
const reason = summarizeCliUpdateCheckStatus(err instanceof Error ? err.message : String(err));
|
|
4041
4097
|
sections.push(`published latest: unavailable (${reason})`);
|
|
4042
4098
|
}
|
|
4043
4099
|
}
|
|
@@ -33,12 +33,14 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.CLI_UPDATE_CHECK_TIMEOUT_MS = void 0;
|
|
36
37
|
exports.checkForUpdate = checkForUpdate;
|
|
37
38
|
exports.startUpdateChecker = startUpdateChecker;
|
|
38
39
|
exports.stopUpdateChecker = stopUpdateChecker;
|
|
39
40
|
const semver = __importStar(require("semver"));
|
|
40
41
|
const runtime_1 = require("../../nerves/runtime");
|
|
41
42
|
const DEFAULT_INTERVAL_MS = 30 * 60 * 1000; // 30 minutes
|
|
43
|
+
exports.CLI_UPDATE_CHECK_TIMEOUT_MS = 3_000;
|
|
42
44
|
async function checkForUpdate(currentVersion, deps) {
|
|
43
45
|
(0, runtime_1.emitNervesEvent)({
|
|
44
46
|
component: "daemon",
|