@ouro.bot/cli 0.1.0-alpha.365 → 0.1.0-alpha.366
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.366",
|
|
6
|
+
"changes": [
|
|
7
|
+
"`ouro up` now treats locked per-agent credential vaults as an unlock problem instead of a provider-auth problem, prompting `ouro vault unlock --agent <agent>` before any `ouro auth` repair flow.",
|
|
8
|
+
"Provider startup checks now preserve credential-pool `unavailable` state and show concise locked-vault guidance instead of nesting duplicate vault errors and secondary auth instructions.",
|
|
9
|
+
"`@ouro.bot/cli` and the `ouro.bot` wrapper are version-synced for the vault unlock repair release."
|
|
10
|
+
]
|
|
11
|
+
},
|
|
4
12
|
{
|
|
5
13
|
"version": "0.1.0-alpha.365",
|
|
6
14
|
"changes": [
|
|
@@ -234,12 +234,30 @@ function missingCredentialResult(agentName, lane, provider, model, credentialPat
|
|
|
234
234
|
};
|
|
235
235
|
}
|
|
236
236
|
function invalidPoolResult(agentName, lane, provider, model, pool) {
|
|
237
|
+
if (pool.reason === "unavailable" && isVaultLockedError(pool.error)) {
|
|
238
|
+
return {
|
|
239
|
+
ok: false,
|
|
240
|
+
error: `${lane} provider ${provider} model ${model} cannot read provider credentials because ${agentName}'s credential vault is locked on this machine.`,
|
|
241
|
+
fix: `Run 'ouro vault unlock --agent ${agentName}', then run 'ouro up' again.`,
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
if (pool.reason === "invalid") {
|
|
245
|
+
return {
|
|
246
|
+
ok: false,
|
|
247
|
+
error: `${lane} provider ${provider} model ${model} cannot read provider credentials from ${agentName}'s vault at ${pool.poolPath}: ${pool.error}`,
|
|
248
|
+
fix: `Run 'ouro auth --agent ${agentName} --provider ${provider}' to rewrite this provider credential, then run 'ouro up' again.`,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
237
251
|
return {
|
|
238
252
|
ok: false,
|
|
239
253
|
error: `${lane} provider ${provider} model ${model} cannot read provider credentials from ${agentName}'s vault at ${pool.poolPath}: ${pool.error}`,
|
|
240
|
-
fix: `Run 'ouro vault unlock --agent ${agentName}', then run 'ouro auth --agent ${agentName} --provider ${provider}'
|
|
254
|
+
fix: `Run 'ouro vault unlock --agent ${agentName}', then run 'ouro up' again. If the credential is missing or stale after unlock, run 'ouro auth --agent ${agentName} --provider ${provider}'.`,
|
|
241
255
|
};
|
|
242
256
|
}
|
|
257
|
+
function isVaultLockedError(error) {
|
|
258
|
+
const normalized = error.toLowerCase();
|
|
259
|
+
return /(?:ouro )?credential vault is locked|vault(?: is)? locked/.test(normalized);
|
|
260
|
+
}
|
|
243
261
|
function failedPingResult(agentName, lane, provider, model, result) {
|
|
244
262
|
return {
|
|
245
263
|
ok: false,
|
|
@@ -302,7 +320,7 @@ async function checkAgentConfigWithProviderHealth(agentName, bundlesRoot, secret
|
|
|
302
320
|
}
|
|
303
321
|
return invalidPoolResult(agentName, lane, binding.provider, binding.model, {
|
|
304
322
|
...poolResult,
|
|
305
|
-
reason:
|
|
323
|
+
reason: poolResult.reason,
|
|
306
324
|
});
|
|
307
325
|
}
|
|
308
326
|
const record = credentialRecordForLane(poolResult.pool, binding.provider);
|
|
@@ -48,6 +48,7 @@ function makeInteractiveRepairDeps(deps) {
|
|
|
48
48
|
writeStdout: deps.writeStdout,
|
|
49
49
|
/* v8 ignore next -- fallback no-op: tests always inject runAuthFlow; default is for production @preserve */
|
|
50
50
|
runAuthFlow: deps.runAuthFlow ?? (async () => undefined),
|
|
51
|
+
runVaultUnlock: deps.runVaultUnlock,
|
|
51
52
|
};
|
|
52
53
|
}
|
|
53
54
|
function discoveredProviderModel(provider) {
|
|
@@ -1815,6 +1815,9 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
1815
1815
|
const authRunner = deps.runAuthFlow ?? (await Promise.resolve().then(() => __importStar(require("../auth/auth-flow")))).runRuntimeAuthFlow;
|
|
1816
1816
|
await authRunner({ agentName: agent, provider, promptInput: deps.promptInput });
|
|
1817
1817
|
},
|
|
1818
|
+
runVaultUnlock: async (agent) => {
|
|
1819
|
+
await executeVaultUnlock({ kind: "vault.unlock", agent }, deps);
|
|
1820
|
+
},
|
|
1818
1821
|
});
|
|
1819
1822
|
}
|
|
1820
1823
|
}
|
|
@@ -14,8 +14,12 @@ function isCredentialIssue(degraded) {
|
|
|
14
14
|
const hint = degraded.fixHint.toLowerCase();
|
|
15
15
|
return reason.includes("credentials") || hint.includes("ouro auth");
|
|
16
16
|
}
|
|
17
|
+
function isVaultUnlockIssue(degraded) {
|
|
18
|
+
const text = `${degraded.errorReason}\n${degraded.fixHint}`.toLowerCase();
|
|
19
|
+
return /ouro vault unlock|credential vault is locked|vault(?: is)? locked/.test(text);
|
|
20
|
+
}
|
|
17
21
|
function isConfigError(degraded) {
|
|
18
|
-
return degraded.fixHint.length > 0 && !isCredentialIssue(degraded);
|
|
22
|
+
return degraded.fixHint.length > 0 && !isVaultUnlockIssue(degraded) && !isCredentialIssue(degraded);
|
|
19
23
|
}
|
|
20
24
|
function isAgentProvider(value) {
|
|
21
25
|
return Object.prototype.hasOwnProperty.call(identity_1.PROVIDER_CREDENTIALS, value);
|
|
@@ -31,6 +35,10 @@ function authCommandFor(degraded) {
|
|
|
31
35
|
const command = degraded.fixHint.match(/ouro auth[^\n.]+/)?.[0]?.trim();
|
|
32
36
|
return command && command.length > 0 ? command : `ouro auth --agent ${degraded.agent}`;
|
|
33
37
|
}
|
|
38
|
+
function vaultUnlockCommandFor(degraded) {
|
|
39
|
+
const command = degraded.fixHint.match(/ouro vault unlock[^\n.]+/)?.[0]?.trim();
|
|
40
|
+
return command && command.length > 0 ? command : `ouro vault unlock --agent ${degraded.agent}`;
|
|
41
|
+
}
|
|
34
42
|
async function runInteractiveRepair(degraded, deps) {
|
|
35
43
|
(0, runtime_1.emitNervesEvent)({
|
|
36
44
|
level: "info",
|
|
@@ -44,7 +52,34 @@ async function runInteractiveRepair(degraded, deps) {
|
|
|
44
52
|
}
|
|
45
53
|
let repairsAttempted = false;
|
|
46
54
|
for (const entry of degraded) {
|
|
47
|
-
if (
|
|
55
|
+
if (isVaultUnlockIssue(entry)) {
|
|
56
|
+
const unlockCommand = vaultUnlockCommandFor(entry);
|
|
57
|
+
const answer = await deps.promptInput(`run \`${unlockCommand}\` now? [y/n] `);
|
|
58
|
+
if (answer.toLowerCase() === "y") {
|
|
59
|
+
try {
|
|
60
|
+
if (!deps.runVaultUnlock) {
|
|
61
|
+
deps.writeStdout(`fix hint for ${entry.agent}: ${entry.fixHint}`);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
await deps.runVaultUnlock(entry.agent);
|
|
65
|
+
repairsAttempted = true;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
70
|
+
deps.writeStdout(`vault unlock error for ${entry.agent}: ${msg}`);
|
|
71
|
+
repairsAttempted = true;
|
|
72
|
+
(0, runtime_1.emitNervesEvent)({
|
|
73
|
+
level: "error",
|
|
74
|
+
component: "daemon",
|
|
75
|
+
event: "daemon.interactive_repair_vault_unlock_error",
|
|
76
|
+
message: `vault unlock failed for ${entry.agent}`,
|
|
77
|
+
meta: { agent: entry.agent, error: msg },
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else if (isCredentialIssue(entry)) {
|
|
48
83
|
const provider = extractProviderFromFixHint(entry.fixHint);
|
|
49
84
|
const authCommand = authCommandFor(entry);
|
|
50
85
|
const answer = await deps.promptInput(`run \`${authCommand}\` now? [y/n] `);
|