@ouro.bot/cli 0.1.0-alpha.396 → 0.1.0-alpha.397
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 +10 -0
- package/dist/heart/daemon/cli-exec.js +34 -42
- package/dist/heart/daemon/readiness-repair.js +25 -14
- package/package.json +1 -1
package/changelog.json
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
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.397",
|
|
6
|
+
"changes": [
|
|
7
|
+
"`ouro up` provider repair output now uses compact readiness cards and `need repair` progress labels instead of dense degraded-agent prose.",
|
|
8
|
+
"Guided readiness repair and post-repair summaries now share the same typed issue renderer, so locked vaults, missing provider credentials, and generic repair hints show consistent `next`/`or` commands.",
|
|
9
|
+
"`ouro vault replace` now prompts for a `new` unlock secret and prints a short recovery handoff to `ouro repair --agent <agent>` instead of dumping generic provider/runtime credential commands into the middle of `ouro up`.",
|
|
10
|
+
"`ouro vault recover` also prompts for a `new` unlock secret while continuing to avoid printing credential values or portable unlock material.",
|
|
11
|
+
"`@ouro.bot/cli` and the `ouro.bot` wrapper are version-synced for the provider repair visual cleanup release."
|
|
12
|
+
]
|
|
13
|
+
},
|
|
4
14
|
{
|
|
5
15
|
"version": "0.1.0-alpha.396",
|
|
6
16
|
"changes": [
|
|
@@ -153,6 +153,25 @@ async function listCliAgents(deps) {
|
|
|
153
153
|
async function checkAlreadyRunningAgentProviders(deps) {
|
|
154
154
|
return checkAgentProviders(deps);
|
|
155
155
|
}
|
|
156
|
+
function readinessIssueFromDegraded(entry) {
|
|
157
|
+
return entry.issue ?? (0, readiness_repair_1.genericReadinessIssue)({
|
|
158
|
+
summary: `${entry.agent}: ${entry.errorReason}`,
|
|
159
|
+
...(entry.fixHint ? { fix: entry.fixHint } : {}),
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
function writeProviderRepairSummary(deps, title, degraded) {
|
|
163
|
+
deps.writeStdout(title);
|
|
164
|
+
for (const entry of degraded) {
|
|
165
|
+
for (const line of (0, readiness_repair_1.renderReadinessIssueNextSteps)(readinessIssueFromDegraded(entry))) {
|
|
166
|
+
deps.writeStdout(line);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
function providerRepairCountSummary(count) {
|
|
171
|
+
if (count === 0)
|
|
172
|
+
return "ok";
|
|
173
|
+
return `${count} ${count === 1 ? "needs" : "need"} repair`;
|
|
174
|
+
}
|
|
156
175
|
async function reportPostRepairProviderHealth(deps, repairedAgents) {
|
|
157
176
|
const remainingDegraded = await checkAgentProviders(deps, repairedAgents);
|
|
158
177
|
(0, runtime_1.emitNervesEvent)({
|
|
@@ -168,14 +187,8 @@ async function reportPostRepairProviderHealth(deps, repairedAgents) {
|
|
|
168
187
|
deps.writeStdout("provider checks recovered after repair");
|
|
169
188
|
return remainingDegraded;
|
|
170
189
|
}
|
|
171
|
-
deps
|
|
172
|
-
|
|
173
|
-
deps.writeStdout(` ${d.agent}: ${d.errorReason}`);
|
|
174
|
-
if (d.fixHint) {
|
|
175
|
-
deps.writeStdout(` fix: ${d.fixHint}`);
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
deps.writeStdout("run `ouro up` again after applying the remaining fixes.");
|
|
190
|
+
writeProviderRepairSummary(deps, "Still blocked:", remainingDegraded);
|
|
191
|
+
deps.writeStdout("Run `ouro up` again after these are fixed.");
|
|
179
192
|
return remainingDegraded;
|
|
180
193
|
}
|
|
181
194
|
async function checkProviderHealthBeforeChat(agentName, deps) {
|
|
@@ -825,7 +838,7 @@ async function executeVaultReplace(command, deps) {
|
|
|
825
838
|
const configuredVault = (0, identity_1.resolveVaultConfig)(command.agent, config.vault);
|
|
826
839
|
const email = command.email ?? defaultRepairVaultEmail(command.agent, config);
|
|
827
840
|
const serverUrl = command.serverUrl ?? config.vault?.serverUrl ?? configuredVault.serverUrl;
|
|
828
|
-
const unlockSecret = (await promptSecret(`Choose Ouro vault unlock secret for ${email}: `)).trim();
|
|
841
|
+
const unlockSecret = (await promptSecret(`Choose new Ouro vault unlock secret for ${email}: `)).trim();
|
|
829
842
|
if (!unlockSecret) {
|
|
830
843
|
throw new Error("vault replace requires an unlock secret. Re-run in an interactive terminal and enter a human-chosen unlock secret.");
|
|
831
844
|
}
|
|
@@ -846,13 +859,8 @@ async function executeVaultReplace(command, deps) {
|
|
|
846
859
|
`vault replaced for ${command.agent}`,
|
|
847
860
|
`vault: ${email} at ${serverUrl}`,
|
|
848
861
|
`local unlock store: ${repair.store.kind}${repair.store.secure ? "" : " (explicit plaintext fallback)"}`,
|
|
849
|
-
"
|
|
850
|
-
|
|
851
|
-
"Re-auth/re-enter the credentials this agent should use:",
|
|
852
|
-
` ouro auth --agent ${command.agent} --provider <provider>`,
|
|
853
|
-
` ouro vault config set --agent ${command.agent} --key <field>`,
|
|
854
|
-
` ouro provider refresh --agent ${command.agent}`,
|
|
855
|
-
` ouro auth verify --agent ${command.agent}`,
|
|
862
|
+
"imported: none",
|
|
863
|
+
`next: ouro repair --agent ${command.agent}`,
|
|
856
864
|
"Keep the vault unlock secret saved outside Ouro. Another machine will need it once.",
|
|
857
865
|
].join("\n");
|
|
858
866
|
deps.writeStdout(message);
|
|
@@ -871,7 +879,7 @@ async function executeVaultRecover(command, deps) {
|
|
|
871
879
|
const configuredVault = (0, identity_1.resolveVaultConfig)(command.agent, config.vault);
|
|
872
880
|
const email = command.email ?? defaultRepairVaultEmail(command.agent, config);
|
|
873
881
|
const serverUrl = command.serverUrl ?? config.vault?.serverUrl ?? configuredVault.serverUrl;
|
|
874
|
-
const unlockSecret = (await promptSecret(`Choose Ouro vault unlock secret for ${email}: `)).trim();
|
|
882
|
+
const unlockSecret = (await promptSecret(`Choose new Ouro vault unlock secret for ${email}: `)).trim();
|
|
875
883
|
if (!unlockSecret) {
|
|
876
884
|
throw new Error("vault recover requires an unlock secret. Re-run in an interactive terminal and enter a human-chosen unlock secret.");
|
|
877
885
|
}
|
|
@@ -1450,12 +1458,7 @@ function readinessReportsFromDegraded(degraded) {
|
|
|
1450
1458
|
return degraded.map((entry) => ({
|
|
1451
1459
|
agent: entry.agent,
|
|
1452
1460
|
ok: false,
|
|
1453
|
-
issues: [
|
|
1454
|
-
entry.issue ?? (0, readiness_repair_1.genericReadinessIssue)({
|
|
1455
|
-
summary: entry.errorReason,
|
|
1456
|
-
...(entry.fixHint ? { fix: entry.fixHint } : {}),
|
|
1457
|
-
}),
|
|
1458
|
-
],
|
|
1461
|
+
issues: [readinessIssueFromDegraded(entry)],
|
|
1459
1462
|
}));
|
|
1460
1463
|
}
|
|
1461
1464
|
async function runReadinessRepairForDegraded(degraded, deps) {
|
|
@@ -2234,30 +2237,25 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
2234
2237
|
progress.startPhase("provider checks");
|
|
2235
2238
|
const preflightProviderDegraded = await checkAgentProviders(deps);
|
|
2236
2239
|
providerChecksAlreadyRun = true;
|
|
2237
|
-
progress.completePhase("provider checks", preflightProviderDegraded.length
|
|
2240
|
+
progress.completePhase("provider checks", providerRepairCountSummary(preflightProviderDegraded.length));
|
|
2238
2241
|
if (preflightProviderDegraded.length > 0) {
|
|
2239
2242
|
progress.end();
|
|
2240
2243
|
if (command.noRepair) {
|
|
2241
|
-
deps
|
|
2242
|
-
|
|
2243
|
-
deps.writeStdout(` ${d.agent}: ${d.errorReason}`);
|
|
2244
|
-
if (d.fixHint) {
|
|
2245
|
-
deps.writeStdout(` fix: ${d.fixHint}`);
|
|
2246
|
-
}
|
|
2247
|
-
}
|
|
2248
|
-
const message = "daemon not started because provider checks are degraded; run `ouro repair` after applying the fixes.";
|
|
2244
|
+
writeProviderRepairSummary(deps, "Provider checks need repair:", preflightProviderDegraded);
|
|
2245
|
+
const message = "daemon not started: provider checks need repair. Run `ouro repair` or rerun `ouro up` to choose a repair path.";
|
|
2249
2246
|
deps.writeStdout(message);
|
|
2250
2247
|
return message;
|
|
2251
2248
|
}
|
|
2252
2249
|
const repairResult = await runReadinessRepairForDegraded(preflightProviderDegraded, deps);
|
|
2253
2250
|
if (!repairResult.repairsAttempted) {
|
|
2254
|
-
|
|
2251
|
+
writeProviderRepairSummary(deps, "Provider checks still need repair:", preflightProviderDegraded);
|
|
2252
|
+
const message = "daemon not started: provider checks need repair. Run `ouro repair` or rerun `ouro up` to choose a repair path.";
|
|
2255
2253
|
deps.writeStdout(message);
|
|
2256
2254
|
return message;
|
|
2257
2255
|
}
|
|
2258
2256
|
const remainingDegraded = await reportPostRepairProviderHealth(deps, preflightProviderDegraded.map((entry) => entry.agent));
|
|
2259
2257
|
if (remainingDegraded.length > 0) {
|
|
2260
|
-
const message = "daemon not started
|
|
2258
|
+
const message = "daemon not started: provider checks still need repair.";
|
|
2261
2259
|
deps.writeStdout(message);
|
|
2262
2260
|
return message;
|
|
2263
2261
|
}
|
|
@@ -2275,7 +2273,7 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
2275
2273
|
progress.startPhase("provider checks");
|
|
2276
2274
|
const providerDegraded = await checkAlreadyRunningAgentProviders(deps);
|
|
2277
2275
|
daemonResult.stability = mergeStartupStability(daemonResult.stability, providerDegraded);
|
|
2278
|
-
progress.completePhase("provider checks", providerDegraded.length
|
|
2276
|
+
progress.completePhase("provider checks", providerRepairCountSummary(providerDegraded.length));
|
|
2279
2277
|
}
|
|
2280
2278
|
progress.end();
|
|
2281
2279
|
deps.writeStdout(daemonResult.message);
|
|
@@ -2283,13 +2281,7 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
|
|
|
2283
2281
|
if (daemonResult.stability?.degraded && daemonResult.stability.degraded.length > 0) {
|
|
2284
2282
|
if (command.noRepair) {
|
|
2285
2283
|
// --no-repair: write degraded summary and skip interactive repair
|
|
2286
|
-
deps
|
|
2287
|
-
for (const d of daemonResult.stability.degraded) {
|
|
2288
|
-
deps.writeStdout(` ${d.agent}: ${d.errorReason}`);
|
|
2289
|
-
if (d.fixHint) {
|
|
2290
|
-
deps.writeStdout(` fix: ${d.fixHint}`);
|
|
2291
|
-
}
|
|
2292
|
-
}
|
|
2284
|
+
writeProviderRepairSummary(deps, "Provider checks need repair:", daemonResult.stability.degraded);
|
|
2293
2285
|
(0, runtime_1.emitNervesEvent)({
|
|
2294
2286
|
level: "warn",
|
|
2295
2287
|
component: "daemon",
|
|
@@ -6,6 +6,7 @@ exports.providerLiveCheckFailedIssue = providerLiveCheckFailedIssue;
|
|
|
6
6
|
exports.genericReadinessIssue = genericReadinessIssue;
|
|
7
7
|
exports.isKnownReadinessIssue = isKnownReadinessIssue;
|
|
8
8
|
exports.renderReadinessIssue = renderReadinessIssue;
|
|
9
|
+
exports.renderReadinessIssueNextSteps = renderReadinessIssueNextSteps;
|
|
9
10
|
exports.runGuidedReadinessRepair = runGuidedReadinessRepair;
|
|
10
11
|
const runtime_1 = require("../../nerves/runtime");
|
|
11
12
|
function vaultLockedIssue(agentName) {
|
|
@@ -13,24 +14,24 @@ function vaultLockedIssue(agentName) {
|
|
|
13
14
|
kind: "vault-locked",
|
|
14
15
|
severity: "blocked",
|
|
15
16
|
actor: "human-required",
|
|
16
|
-
summary: `${agentName}
|
|
17
|
-
detail: "
|
|
17
|
+
summary: `${agentName}: vault locked`,
|
|
18
|
+
detail: "Pick the path that matches what the human actually has. Ouro will not print or store the unlock secret as a portable file.",
|
|
18
19
|
actions: [
|
|
19
20
|
{
|
|
20
21
|
kind: "vault-unlock",
|
|
21
|
-
label: "
|
|
22
|
+
label: "Unlock with saved secret",
|
|
22
23
|
command: `ouro vault unlock --agent ${agentName}`,
|
|
23
24
|
actor: "human-required",
|
|
24
25
|
},
|
|
25
26
|
{
|
|
26
27
|
kind: "vault-replace",
|
|
27
|
-
label: "
|
|
28
|
+
label: "Create empty replacement vault",
|
|
28
29
|
command: `ouro vault replace --agent ${agentName}`,
|
|
29
30
|
actor: "human-required",
|
|
30
31
|
},
|
|
31
32
|
{
|
|
32
33
|
kind: "vault-recover",
|
|
33
|
-
label: "
|
|
34
|
+
label: "Recover from JSON export",
|
|
34
35
|
command: `ouro vault recover --agent ${agentName} --from <json>`,
|
|
35
36
|
actor: "human-required",
|
|
36
37
|
executable: false,
|
|
@@ -43,19 +44,19 @@ function providerCredentialMissingIssue(input) {
|
|
|
43
44
|
kind: "provider-credentials-missing",
|
|
44
45
|
severity: "blocked",
|
|
45
46
|
actor: "human-required",
|
|
46
|
-
summary: `${input.agentName}
|
|
47
|
-
detail: `
|
|
47
|
+
summary: `${input.agentName}: missing ${input.provider} credentials (${input.lane}, ${input.model})`,
|
|
48
|
+
detail: `source: ${input.credentialPath}`,
|
|
48
49
|
actions: [
|
|
49
50
|
{
|
|
50
51
|
kind: "provider-auth",
|
|
51
|
-
label: `Authenticate ${input.provider}
|
|
52
|
+
label: `Authenticate ${input.provider}`,
|
|
52
53
|
command: `ouro auth --agent ${input.agentName} --provider ${input.provider}`,
|
|
53
54
|
actor: "human-required",
|
|
54
55
|
provider: input.provider,
|
|
55
56
|
},
|
|
56
57
|
{
|
|
57
58
|
kind: "provider-use",
|
|
58
|
-
label: "Choose
|
|
59
|
+
label: "Choose another provider/model",
|
|
59
60
|
command: `ouro use --agent ${input.agentName} --lane ${input.lane} --provider <provider> --model <model>`,
|
|
60
61
|
actor: "human-choice",
|
|
61
62
|
executable: false,
|
|
@@ -69,7 +70,7 @@ function providerLiveCheckFailedIssue(input) {
|
|
|
69
70
|
kind: "provider-live-check-failed",
|
|
70
71
|
severity: "blocked",
|
|
71
72
|
actor: "human-choice",
|
|
72
|
-
summary: `${input.agentName}
|
|
73
|
+
summary: `${input.agentName}: ${input.lane} provider ${input.provider} / ${input.model} failed live check`,
|
|
73
74
|
detail: input.message,
|
|
74
75
|
actions: [
|
|
75
76
|
{
|
|
@@ -118,11 +119,21 @@ function renderReadinessIssue(issue) {
|
|
|
118
119
|
}
|
|
119
120
|
issue.actions.forEach((action, index) => {
|
|
120
121
|
lines.push(`${index + 1}. ${action.label}`);
|
|
121
|
-
lines.push(`
|
|
122
|
+
lines.push(` ${action.command}`);
|
|
122
123
|
});
|
|
123
124
|
lines.push(`${issue.actions.length + 1}. Skip for now`);
|
|
124
125
|
return lines.join("\n");
|
|
125
126
|
}
|
|
127
|
+
function renderReadinessIssueNextSteps(issue) {
|
|
128
|
+
const lines = [` ${issue.summary}`];
|
|
129
|
+
if (issue.detail && issue.kind !== "vault-locked") {
|
|
130
|
+
lines.push(` ${issue.detail}`);
|
|
131
|
+
}
|
|
132
|
+
issue.actions.forEach((action, index) => {
|
|
133
|
+
lines.push(` ${index === 0 ? "next" : "or"}: ${action.command}`);
|
|
134
|
+
});
|
|
135
|
+
return lines;
|
|
136
|
+
}
|
|
126
137
|
function selectedActionFor(answer, issue) {
|
|
127
138
|
const selected = Number.parseInt(answer.trim(), 10);
|
|
128
139
|
if (!Number.isFinite(selected))
|
|
@@ -160,11 +171,11 @@ async function runGuidedReadinessRepair(reports, deps) {
|
|
|
160
171
|
const answer = await deps.promptInput(`Choose [1-${issue.actions.length + 1}]: `);
|
|
161
172
|
const action = selectedActionFor(answer, issue);
|
|
162
173
|
if (action === "skip") {
|
|
163
|
-
deps.writeStdout(`
|
|
174
|
+
deps.writeStdout(`skipped ${report.agent} for now.`);
|
|
164
175
|
continue;
|
|
165
176
|
}
|
|
166
177
|
if (!action) {
|
|
167
|
-
deps.writeStdout(`invalid
|
|
178
|
+
deps.writeStdout(`invalid choice for ${report.agent}; no repair attempted.`);
|
|
168
179
|
continue;
|
|
169
180
|
}
|
|
170
181
|
if (!isExecutableAction(action)) {
|
|
@@ -178,7 +189,7 @@ async function runGuidedReadinessRepair(reports, deps) {
|
|
|
178
189
|
try {
|
|
179
190
|
await deps.runRepairAction(report.agent, action, issue);
|
|
180
191
|
repairsAttempted = true;
|
|
181
|
-
deps.writeStdout(`repair
|
|
192
|
+
deps.writeStdout(`repair step finished for ${report.agent}.`);
|
|
182
193
|
}
|
|
183
194
|
catch (error) {
|
|
184
195
|
const message = error instanceof Error ? error.message : String(error);
|