@ouro.bot/cli 0.1.0-alpha.364 → 0.1.0-alpha.365

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.
Files changed (41) hide show
  1. package/README.md +15 -6
  2. package/changelog.json +9 -0
  3. package/dist/heart/auth/auth-flow.js +25 -110
  4. package/dist/heart/config.js +69 -55
  5. package/dist/heart/core.js +83 -33
  6. package/dist/heart/daemon/agent-config-check.js +41 -238
  7. package/dist/heart/daemon/agentic-repair.js +1 -1
  8. package/dist/heart/daemon/cli-defaults.js +15 -68
  9. package/dist/heart/daemon/cli-exec.js +246 -89
  10. package/dist/heart/daemon/cli-parse.js +71 -0
  11. package/dist/heart/daemon/daemon-cli.js +1 -2
  12. package/dist/heart/daemon/daemon-entry.js +1 -3
  13. package/dist/heart/daemon/doctor.js +9 -29
  14. package/dist/heart/daemon/provider-discovery.js +32 -59
  15. package/dist/heart/hatch/hatch-flow.js +9 -12
  16. package/dist/heart/hatch/specialist-prompt.js +1 -1
  17. package/dist/heart/hatch/specialist-tools.js +21 -1
  18. package/dist/heart/migrate-config.js +15 -42
  19. package/dist/heart/provider-binding-resolver.js +6 -7
  20. package/dist/heart/provider-credentials.js +379 -0
  21. package/dist/heart/provider-failover.js +3 -11
  22. package/dist/heart/provider-ping.js +13 -3
  23. package/dist/heart/provider-state.js +8 -0
  24. package/dist/heart/provider-visibility.js +3 -6
  25. package/dist/heart/providers/anthropic-token.js +15 -47
  26. package/dist/heart/providers/anthropic.js +4 -9
  27. package/dist/heart/providers/azure.js +3 -3
  28. package/dist/heart/providers/github-copilot.js +2 -2
  29. package/dist/heart/providers/minimax-vlm.js +2 -2
  30. package/dist/heart/providers/minimax.js +1 -1
  31. package/dist/heart/providers/openai-codex.js +4 -9
  32. package/dist/repertoire/bitwarden-store.js +63 -17
  33. package/dist/repertoire/bundle-templates.js +2 -2
  34. package/dist/repertoire/credential-access.js +47 -467
  35. package/dist/repertoire/tools-attachments.js +5 -4
  36. package/dist/repertoire/tools-vault.js +10 -80
  37. package/dist/repertoire/vault-unlock.js +359 -0
  38. package/dist/senses/bluebubbles/client.js +39 -4
  39. package/dist/senses/pipeline.js +0 -1
  40. package/package.json +1 -1
  41. package/dist/heart/provider-credential-pool.js +0 -395
@@ -300,38 +300,18 @@ function checkHabits(deps) {
300
300
  function checkSecurity(deps) {
301
301
  const checks = [];
302
302
  const agents = discoverAgents(deps);
303
- const providerPoolPath = `${deps.secretsRoot}/providers.json`;
304
- if (deps.existsSync(providerPoolPath)) {
305
- const stat = deps.statSync(providerPoolPath);
306
- const worldReadable = (stat.mode & 0o004) !== 0;
307
- checks.push({
308
- label: "machine provider credentials perms",
309
- status: worldReadable ? "warn" : "pass",
310
- detail: worldReadable ? "world-readable — consider chmod 600" : "not world-readable",
311
- });
312
- try {
313
- JSON.parse(deps.readFileSync(providerPoolPath));
314
- checks.push({ label: "machine provider credentials", status: "pass", detail: "readable JSON" });
315
- }
316
- catch {
317
- checks.push({ label: "machine provider credentials", status: "fail", detail: "unparseable JSON" });
318
- }
319
- }
320
303
  for (const agentDir of agents) {
321
304
  const agentName = agentDir.replace(/\.ouro$/, "");
322
305
  const secretsPath = `${deps.secretsRoot}/${agentName}/secrets.json`;
323
- if (!deps.existsSync(secretsPath)) {
324
- checks.push({ label: `${agentDir} secrets.json`, status: "fail", detail: "missing" });
325
- continue;
326
- }
327
- // Check file permissions
328
- const stat = deps.statSync(secretsPath);
329
- const worldReadable = (stat.mode & 0o004) !== 0;
330
- if (worldReadable) {
331
- checks.push({ label: `${agentDir} secrets.json perms`, status: "warn", detail: "world-readable — consider chmod 600" });
332
- }
333
- else {
334
- checks.push({ label: `${agentDir} secrets.json perms`, status: "pass", detail: "not world-readable" });
306
+ if (deps.existsSync(secretsPath)) {
307
+ const stat = deps.statSync(secretsPath);
308
+ const worldReadable = (stat.mode & 0o004) !== 0;
309
+ if (worldReadable) {
310
+ checks.push({ label: `${agentDir} legacy secrets.json perms`, status: "warn", detail: "world-readable — consider deleting or chmod 600" });
311
+ }
312
+ else {
313
+ checks.push({ label: `${agentDir} legacy secrets.json perms`, status: "pass", detail: "not world-readable" });
314
+ }
335
315
  }
336
316
  // Check agent.json for leaked credential keys
337
317
  const configPath = `${deps.bundlesRoot}/${agentDir}/agent.json`;
@@ -1,19 +1,20 @@
1
1
  "use strict";
2
2
  /**
3
- * Shared provider discovery — single path for finding a working LLM provider.
3
+ * Shared provider discovery for repair.
4
4
  *
5
- * Scans machine-pool credentials, legacy disk credentials, and environment variables,
6
- * deduplicates by provider, then pings each candidate to validate credentials actually work.
5
+ * Runtime repair only trusts the agent vault. First-run conveniences may still
6
+ * inspect env vars before credentials are stored, but once an agent exists the
7
+ * vault is the source of truth.
7
8
  */
8
9
  Object.defineProperty(exports, "__esModule", { value: true });
9
10
  exports.scanEnvVarCredentials = scanEnvVarCredentials;
10
11
  exports.discoverWorkingProvider = discoverWorkingProvider;
11
12
  const identity_1 = require("../identity");
12
- const provider_credential_pool_1 = require("../provider-credential-pool");
13
+ const provider_credentials_1 = require("../provider-credentials");
13
14
  const runtime_1 = require("../../nerves/runtime");
14
15
  /**
15
- * Scan environment variables for API keys using the canonical PROVIDER_CREDENTIALS descriptor.
16
- * Returns one DiscoveredCredential per provider that has at least one required field set.
16
+ * Scan environment variables for API keys during first-run bootstrap.
17
+ * This does not participate in runtime provider repair.
17
18
  */
18
19
  function scanEnvVarCredentials(env) {
19
20
  const results = [];
@@ -25,7 +26,6 @@ function scanEnvVarCredentials(env) {
25
26
  cred[credKey] = value;
26
27
  }
27
28
  }
28
- // Only register if at least one required field was found
29
29
  const hasRequired = desc.required.some((key) => !!cred[key]);
30
30
  if (hasRequired) {
31
31
  results.push({
@@ -45,62 +45,35 @@ function stringifyProviderFields(fields) {
45
45
  }
46
46
  return result;
47
47
  }
48
- function machinePoolSource(record) {
49
- if (record.provenance.contributedByAgent) {
50
- return `machine-pool:${record.provenance.contributedByAgent}`;
51
- }
52
- return `machine-pool:${record.provenance.source}`;
53
- }
54
- function discoverMachinePoolCredentials(secretsRoot) {
55
- const homeDir = (0, provider_credential_pool_1.providerCredentialHomeDirFromSecretsRoot)(secretsRoot);
56
- const poolResult = (0, provider_credential_pool_1.readProviderCredentialPool)(homeDir);
57
- if (!poolResult.ok)
58
- return [];
59
- const credentials = [];
60
- for (const [, record] of Object.entries(poolResult.pool.providers)) {
61
- credentials.push({
62
- provider: record.provider,
63
- agentName: machinePoolSource(record),
64
- credentials: stringifyProviderFields(record.credentials),
65
- providerConfig: stringifyProviderFields(record.config),
66
- });
67
- }
68
- return credentials;
48
+ function discoveredFromVaultRecord(record) {
49
+ return {
50
+ provider: record.provider,
51
+ agentName: "vault",
52
+ credentials: stringifyProviderFields(record.credentials),
53
+ providerConfig: stringifyProviderFields(record.config),
54
+ };
69
55
  }
70
- /**
71
- * Discover the first working provider by scanning configured credential sources,
72
- * deduplicating by provider, and pinging each candidate.
73
- */
74
56
  async function discoverWorkingProvider(deps) {
75
- const poolCreds = discoverMachinePoolCredentials(deps.secretsRoot);
76
- const diskCreds = deps.discoverExistingCredentials(deps.secretsRoot);
77
- const envCreds = scanEnvVarCredentials(deps.env);
78
- // Deduplicate: machine pool first, legacy per-agent disk next, env vars last.
79
- const seenProviders = new Set();
80
- const candidates = [];
81
- for (const cred of poolCreds) {
82
- seenProviders.add(cred.provider);
83
- candidates.push(cred);
84
- }
85
- for (const cred of diskCreds) {
86
- if (!seenProviders.has(cred.provider)) {
87
- seenProviders.add(cred.provider);
88
- candidates.push(cred);
89
- }
90
- }
91
- for (const cred of envCreds) {
92
- if (!seenProviders.has(cred.provider)) {
93
- seenProviders.add(cred.provider);
94
- candidates.push(cred);
95
- }
57
+ const poolResult = await (0, provider_credentials_1.refreshProviderCredentialPool)(deps.agentName);
58
+ if (!poolResult.ok) {
59
+ (0, runtime_1.emitNervesEvent)({
60
+ level: "warn",
61
+ component: "daemon",
62
+ event: "daemon.provider_discovery_none",
63
+ message: "provider discovery could not read agent vault",
64
+ meta: { agentName: deps.agentName, reason: poolResult.reason },
65
+ });
66
+ return null;
96
67
  }
68
+ const candidates = Object.entries(poolResult.pool.providers)
69
+ .map(([, record]) => discoveredFromVaultRecord(record));
97
70
  if (candidates.length === 0) {
98
71
  (0, runtime_1.emitNervesEvent)({
99
72
  level: "info",
100
73
  component: "daemon",
101
74
  event: "daemon.provider_discovery_none",
102
- message: "no provider credentials found in machine pool, legacy disk, or environment",
103
- meta: {},
75
+ message: "no provider credentials found in agent vault",
76
+ meta: { agentName: deps.agentName },
104
77
  });
105
78
  return null;
106
79
  }
@@ -111,7 +84,7 @@ async function discoverWorkingProvider(deps) {
111
84
  component: "daemon",
112
85
  event: "daemon.provider_discovery_ping",
113
86
  message: `pinging provider: ${candidate.provider}`,
114
- meta: { provider: candidate.provider, source: candidate.agentName },
87
+ meta: { agentName: deps.agentName, provider: candidate.provider, source: candidate.agentName },
115
88
  });
116
89
  const result = await deps.pingProvider(candidate.provider, config);
117
90
  if (result.ok) {
@@ -120,7 +93,7 @@ async function discoverWorkingProvider(deps) {
120
93
  component: "daemon",
121
94
  event: "daemon.provider_discovery_ok",
122
95
  message: `provider discovery succeeded: ${candidate.provider}`,
123
- meta: { provider: candidate.provider, source: candidate.agentName },
96
+ meta: { agentName: deps.agentName, provider: candidate.provider, source: candidate.agentName },
124
97
  });
125
98
  return {
126
99
  provider: candidate.provider,
@@ -133,8 +106,8 @@ async function discoverWorkingProvider(deps) {
133
106
  level: "warn",
134
107
  component: "daemon",
135
108
  event: "daemon.provider_discovery_all_failed",
136
- message: "all provider candidates failed ping",
137
- meta: { candidateCount: candidates.length },
109
+ message: "all vault provider candidates failed ping",
110
+ meta: { agentName: deps.agentName, candidateCount: candidates.length },
138
111
  });
139
112
  return null;
140
113
  }
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.writeSecretsFile = writeSecretsFile;
36
+ exports.storeHatchlingProviderCredentials = storeHatchlingProviderCredentials;
37
37
  exports.runHatchFlow = runHatchFlow;
38
38
  const fs = __importStar(require("fs"));
39
39
  const os = __importStar(require("os"));
@@ -45,7 +45,7 @@ const auth_flow_1 = require("../auth/auth-flow");
45
45
  const provider_models_1 = require("../provider-models");
46
46
  const habit_parser_1 = require("../habits/habit-parser");
47
47
  const machine_identity_1 = require("../machine-identity");
48
- const provider_credential_pool_1 = require("../provider-credential-pool");
48
+ const provider_credentials_1 = require("../provider-credentials");
49
49
  const provider_state_1 = require("../provider-state");
50
50
  const hatch_specialist_1 = require("./hatch-specialist");
51
51
  function requiredCredentialKeys(provider) {
@@ -67,8 +67,8 @@ function validateCredentials(provider, credentials) {
67
67
  throw new Error(`Missing required credentials for ${provider}: ${missing.join(", ")}`);
68
68
  }
69
69
  }
70
- function writeSecretsFile(agentName, provider, credentials, secretsRoot) {
71
- return (0, auth_flow_1.writeProviderCredentials)(agentName, provider, credentials, { secretsRoot }).secretsPath;
70
+ async function storeHatchlingProviderCredentials(agentName, provider, credentials) {
71
+ return (await (0, auth_flow_1.storeProviderCredentials)(agentName, provider, credentials)).credentialPath;
72
72
  }
73
73
  function writeReadme(dir, purpose) {
74
74
  fs.mkdirSync(dir, { recursive: true });
@@ -135,10 +135,10 @@ function writeHatchlingAgentConfig(bundleRoot, input) {
135
135
  template.enabled = true;
136
136
  fs.writeFileSync(path.join(bundleRoot, "agent.json"), `${JSON.stringify(template, null, 2)}\n`, "utf-8");
137
137
  }
138
- function writeHatchlingProviderState(bundleRoot, input, secretsRoot, now) {
138
+ function writeHatchlingProviderState(bundleRoot, input, now) {
139
139
  const model = (0, provider_models_1.getDefaultModelForProvider)(input.provider);
140
140
  const machine = (0, machine_identity_1.loadOrCreateMachineIdentity)({
141
- homeDir: (0, provider_credential_pool_1.providerCredentialHomeDirFromSecretsRoot)(secretsRoot),
141
+ homeDir: (0, provider_credentials_1.providerCredentialMachineHomeDir)(),
142
142
  now: () => now,
143
143
  });
144
144
  const state = (0, provider_state_1.bootstrapProviderStateFromAgentConfig)({
@@ -160,7 +160,6 @@ async function runHatchFlow(input, deps = {}) {
160
160
  });
161
161
  validateCredentials(input.provider, input.credentials);
162
162
  const bundlesRoot = deps.bundlesRoot ?? path.join(os.homedir(), "AgentBundles");
163
- const secretsRoot = deps.secretsRoot ?? path.join(os.homedir(), ".agentsecrets");
164
163
  const sourceIdentities = deps.specialistIdentitySourceDir ?? (0, hatch_specialist_1.getSpecialistIdentitySourceDir)();
165
164
  const targetIdentities = deps.specialistIdentityTargetDir ?? (0, hatch_specialist_1.getRepoSpecialistIdentitiesDir)();
166
165
  const now = deps.now ? deps.now() : new Date();
@@ -173,8 +172,6 @@ async function runHatchFlow(input, deps = {}) {
173
172
  identitiesDir: targetIdentities,
174
173
  random,
175
174
  });
176
- const specialistSecretsPath = writeSecretsFile("SerpentGuide", input.provider, input.credentials, secretsRoot);
177
- const hatchlingSecretsPath = writeSecretsFile(input.agentName, input.provider, input.credentials, secretsRoot);
178
175
  const bundleRoot = path.join(bundlesRoot, `${input.agentName}.ouro`);
179
176
  fs.mkdirSync(bundleRoot, { recursive: true });
180
177
  writeReadme(bundleRoot, "Root of this agent bundle.");
@@ -189,7 +186,8 @@ async function runHatchFlow(input, deps = {}) {
189
186
  writeReadme(path.join(bundleRoot, "senses"), "Sense-specific config.");
190
187
  writeReadme(path.join(bundleRoot, "senses", "teams"), "Teams sense config.");
191
188
  writeHatchlingAgentConfig(bundleRoot, input);
192
- writeHatchlingProviderState(bundleRoot, input, secretsRoot, now);
189
+ const credentialPath = await storeHatchlingProviderCredentials(input.agentName, input.provider, input.credentials);
190
+ writeHatchlingProviderState(bundleRoot, input, now);
193
191
  writeDiaryScaffold(bundleRoot);
194
192
  writeFriendImprint(bundleRoot, input.humanName, now);
195
193
  writeHeartbeatHabit(bundleRoot, now);
@@ -202,7 +200,6 @@ async function runHatchFlow(input, deps = {}) {
202
200
  return {
203
201
  bundleRoot,
204
202
  selectedIdentity: selected.fileName,
205
- specialistSecretsPath,
206
- hatchlingSecretsPath,
203
+ credentialPath,
207
204
  };
208
205
  }
@@ -44,7 +44,7 @@ function buildSpecialistSystemPrompt(soulText, identityText, existingBundles, co
44
44
  `Provider: ${context.provider}`,
45
45
  `Temp directory: ${context.tempDir}`,
46
46
  "Final home: ~/AgentBundles/<Name>.ouro/",
47
- "Secrets: ~/.agentsecrets/<name>/secrets.json",
47
+ "Provider credentials: the hatch tool stores them in the agent's vault.",
48
48
  ].join("\n"));
49
49
  sections.push([
50
50
  "## Bundle creation guidelines",
@@ -42,7 +42,10 @@ const tools_base_1 = require("../../repertoire/tools-base");
42
42
  const hatch_flow_1 = require("./hatch-flow");
43
43
  const hatch_animation_1 = require("./hatch-animation");
44
44
  const bundle_manifest_1 = require("../../mind/bundle-manifest");
45
+ const identity_1 = require("../identity");
45
46
  const runtime_1 = require("../../nerves/runtime");
47
+ const vault_setup_1 = require("../../repertoire/vault-setup");
48
+ const vault_unlock_1 = require("../../repertoire/vault-unlock");
46
49
  const completeAdoptionTool = {
47
50
  type: "function",
48
51
  function: {
@@ -171,8 +174,17 @@ async function execCompleteAdoption(args, deps) {
171
174
  // Move tempDir -> final bundle location
172
175
  moveDir(deps.tempDir, targetBundle);
173
176
  // Write secrets
177
+ let generatedVaultUnlockSecret = null;
174
178
  try {
175
- (0, hatch_flow_1.writeSecretsFile)(name, deps.provider, deps.credentials, deps.secretsRoot);
179
+ const vault = (0, identity_1.resolveVaultConfig)(name);
180
+ const vaultUnlockSecret = crypto.randomBytes(32).toString("base64");
181
+ const vaultResult = await (0, vault_setup_1.createVaultAccount)(name, vault.serverUrl, vault.email, vaultUnlockSecret);
182
+ if (!vaultResult.success) {
183
+ throw new Error(`failed to create vault: ${vaultResult.error}`);
184
+ }
185
+ (0, vault_unlock_1.storeVaultUnlockSecret)({ agentName: name, email: vault.email, serverUrl: vault.serverUrl }, vaultUnlockSecret);
186
+ generatedVaultUnlockSecret = vaultUnlockSecret;
187
+ await (0, hatch_flow_1.storeHatchlingProviderCredentials)(name, deps.provider, deps.credentials);
176
188
  }
177
189
  catch (e) {
178
190
  // Rollback: remove the moved bundle
@@ -217,6 +229,14 @@ async function execCompleteAdoption(args, deps) {
217
229
  if (handoffMessage && deps.animationWriter) {
218
230
  deps.animationWriter(`\n${handoffMessage}\n`);
219
231
  }
232
+ if (generatedVaultUnlockSecret && deps.animationWriter) {
233
+ deps.animationWriter([
234
+ "",
235
+ `Vault unlock secret for ${name}: ${generatedVaultUnlockSecret}`,
236
+ `Use this with \`ouro vault unlock --agent ${name}\` on another machine.`,
237
+ "",
238
+ ].join("\n"));
239
+ }
220
240
  (0, runtime_1.emitNervesEvent)({
221
241
  component: "daemon",
222
242
  event: "daemon.adoption_complete",
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  // v1 → v2 agent.json migration.
3
- // Moves model from secrets.json into agent.json under humanFacing/agentFacing.
4
- // Uses raw fs — NO import from config.ts (avoids circular dependency).
3
+ // Creates explicit humanFacing/agentFacing blocks from the legacy provider.
4
+ // Uses raw fs and provider-model defaults — NO import from config.ts.
5
5
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
6
6
  if (k2 === undefined) k2 = k;
7
7
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -40,19 +40,15 @@ exports.migrateAgentConfigV1ToV2 = migrateAgentConfigV1ToV2;
40
40
  const fs = __importStar(require("fs"));
41
41
  const path = __importStar(require("path"));
42
42
  const runtime_1 = require("../nerves/runtime");
43
- const MODEL_FIELD = {
44
- azure: "modelName",
45
- minimax: "model",
46
- anthropic: "model",
47
- "openai-codex": "model",
48
- "github-copilot": "model",
49
- };
50
- function resolveSecretsPath(agentRoot, deps) {
51
- const agentName = path.basename(agentRoot).replace(/\.ouro$/, "");
52
- const secretsBase = deps?.secretsRoot ?? path.join(require("os").homedir(), ".agentsecrets");
53
- return path.join(secretsBase, agentName, "secrets.json");
43
+ const provider_models_1 = require("./provider-models");
44
+ function isAgentProvider(value) {
45
+ return value === "azure" ||
46
+ value === "minimax" ||
47
+ value === "anthropic" ||
48
+ value === "openai-codex" ||
49
+ value === "github-copilot";
54
50
  }
55
- function migrateAgentConfigV1ToV2(agentRoot, deps) {
51
+ function migrateAgentConfigV1ToV2(agentRoot) {
56
52
  const configPath = path.join(agentRoot, "agent.json");
57
53
  let raw;
58
54
  try {
@@ -84,44 +80,21 @@ function migrateAgentConfigV1ToV2(agentRoot, deps) {
84
80
  message: "migrating agent config v1 → v2",
85
81
  meta: { agentRoot },
86
82
  });
87
- const provider = config.provider;
88
- let model = "";
89
- if (provider) {
90
- const secretsPath = resolveSecretsPath(agentRoot, deps);
91
- try {
92
- const secretsRaw = fs.readFileSync(secretsPath, "utf-8");
93
- const secrets = JSON.parse(secretsRaw);
94
- const providers = secrets.providers;
95
- if (providers) {
96
- const providerSecrets = providers[provider];
97
- if (providerSecrets) {
98
- /* v8 ignore next -- fallback: all known providers are in MODEL_FIELD @preserve */
99
- const fieldName = MODEL_FIELD[provider] ?? "model";
100
- const rawModel = providerSecrets[fieldName];
101
- model = typeof rawModel === "string" ? rawModel : "";
102
- // Strip model from secrets
103
- delete providerSecrets[fieldName];
104
- fs.writeFileSync(secretsPath, JSON.stringify(secrets, null, 2) + "\n", "utf-8");
105
- }
106
- }
107
- }
108
- catch {
109
- // Missing or malformed secrets.json — leave model as empty string
110
- }
111
- }
83
+ const provider = isAgentProvider(config.provider) ? config.provider : "anthropic";
84
+ const model = (0, provider_models_1.getDefaultModelForProvider)(provider);
112
85
  // Write v2 config
113
86
  const { provider: _removed, ...rest } = config;
114
87
  const v2Config = {
115
88
  ...rest,
116
89
  version: 2,
117
- humanFacing: { provider: provider ?? "anthropic", model },
118
- agentFacing: { provider: provider ?? "anthropic", model },
90
+ humanFacing: { provider, model },
91
+ agentFacing: { provider, model },
119
92
  };
120
93
  fs.writeFileSync(configPath, JSON.stringify(v2Config, null, 2) + "\n", "utf-8");
121
94
  (0, runtime_1.emitNervesEvent)({
122
95
  component: "config/identity",
123
96
  event: "config_identity.migrate_end",
124
97
  message: "agent config migration complete",
125
- meta: { agentRoot, provider: provider ?? "unknown", model },
98
+ meta: { agentRoot, provider, model },
126
99
  });
127
100
  }
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.normalizeProviderLane = normalizeProviderLane;
4
4
  exports.resolveEffectiveProviderBinding = resolveEffectiveProviderBinding;
5
5
  const runtime_1 = require("../nerves/runtime");
6
- const provider_credential_pool_1 = require("./provider-credential-pool");
6
+ const provider_credentials_1 = require("./provider-credentials");
7
7
  const provider_state_1 = require("./provider-state");
8
8
  function legacyLaneWarning(selector, lane) {
9
9
  return {
@@ -36,7 +36,7 @@ function buildUseRepair(agentName, lane, force = false) {
36
36
  function buildAuthRepair(agentName, provider) {
37
37
  return {
38
38
  command: `ouro auth --agent ${agentName} --provider ${provider}`,
39
- message: `Authenticate ${provider} once for this machine's shared credential pool.`,
39
+ message: `Store ${provider} credentials in ${agentName}'s vault.`,
40
40
  };
41
41
  }
42
42
  function missingProviderStateWarning(agentName) {
@@ -54,13 +54,13 @@ function invalidProviderStateWarning(agentName) {
54
54
  function missingCredentialWarning(provider) {
55
55
  return {
56
56
  code: "credential-missing",
57
- message: `${provider} has no credential record in the machine credential pool.`,
57
+ message: `${provider} has no credential record in the agent vault.`,
58
58
  };
59
59
  }
60
60
  function invalidCredentialPoolWarning(provider) {
61
61
  return {
62
62
  code: "credential-pool-invalid",
63
- message: `${provider} cannot read credentials because the machine credential pool is invalid.`,
63
+ message: `${provider} cannot read credentials from the agent vault.`,
64
64
  };
65
65
  }
66
66
  function presentCredential(record) {
@@ -69,7 +69,6 @@ function presentCredential(record) {
69
69
  provider: record.provider,
70
70
  revision: record.revision,
71
71
  source: record.provenance.source,
72
- contributedByAgent: record.provenance.contributedByAgent,
73
72
  updatedAt: record.updatedAt,
74
73
  credentialFields: Object.keys(record.credentials).sort(),
75
74
  configFields: Object.keys(record.config).sort(),
@@ -90,7 +89,7 @@ function resolveCredential(poolResult, provider, agentName) {
90
89
  warnings: [missingCredentialWarning(provider)],
91
90
  };
92
91
  }
93
- if (poolResult.reason === "invalid") {
92
+ if (poolResult.reason === "invalid" || poolResult.reason === "unavailable") {
94
93
  return {
95
94
  credential: {
96
95
  status: "invalid-pool",
@@ -198,7 +197,7 @@ function resolveEffectiveProviderBinding(input) {
198
197
  return result;
199
198
  }
200
199
  const laneBinding = stateResult.state.lanes[laneResolution.lane];
201
- const poolResult = (0, provider_credential_pool_1.readProviderCredentialPool)(input.homeDir);
200
+ const poolResult = (0, provider_credentials_1.readProviderCredentialPool)(input.agentName);
202
201
  const credentialResult = resolveCredential(poolResult, laneBinding.provider, input.agentName);
203
202
  const readinessResult = resolveReadiness({
204
203
  provider: laneBinding.provider,