@ouro.bot/cli 0.1.0-alpha.464 → 0.1.0-alpha.465

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/README.md CHANGED
@@ -180,6 +180,7 @@ ouro vault unlock --agent <name>
180
180
  ouro vault status --agent <name>
181
181
  ouro vault config set --agent <name> --key teams.clientSecret
182
182
  ouro vault config status --agent <name> --scope all
183
+ ouro vault ops porkbun set --agent <name> --account <account>
183
184
  ouro connect --agent <name>
184
185
  ouro connect providers --agent <name>
185
186
  ouro connect perplexity --agent <name>
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.465",
6
+ "changes": [
7
+ "`ouro vault ops porkbun set` now stores account-scoped Porkbun API credentials in the owning agent vault through hidden prompts, outside the connect bay and runtime/config.",
8
+ "Porkbun ops credentials are named by their true authority boundary at `ops/registrars/porkbun/accounts/<account>`, so multiple Porkbun accounts can coexist and domain allowlists remain separate.",
9
+ "Auth/provider docs now clarify that `ouro connect` is only for harness-managed capabilities, while registrar and deployment credentials belong in explicit `ops/...` vault items."
10
+ ]
11
+ },
4
12
  {
5
13
  "version": "0.1.0-alpha.464",
6
14
  "changes": [
@@ -103,6 +103,7 @@ const provider_ping_1 = require("../provider-ping");
103
103
  const agent_discovery_1 = require("./agent-discovery");
104
104
  const connect_bay_1 = require("./connect-bay");
105
105
  const runtime_capability_check_1 = require("../runtime-capability-check");
106
+ const porkbun_ops_1 = require("./porkbun-ops");
106
107
  // ── ensureDaemonRunning ──
107
108
  const DEFAULT_DAEMON_STARTUP_TIMEOUT_MS = 60_000;
108
109
  const DEFAULT_DAEMON_STARTUP_POLL_INTERVAL_MS = 500;
@@ -325,6 +326,8 @@ function agentResolutionFailureMode(command) {
325
326
  case "vault.status":
326
327
  case "vault.config.set":
327
328
  case "vault.config.status":
329
+ case "vault.ops.porkbun.set":
330
+ case "vault.ops.porkbun.status":
328
331
  case "connect":
329
332
  case "account.ensure":
330
333
  case "mail.import-mbox":
@@ -2009,6 +2012,75 @@ async function executeVaultConfigStatus(command, deps) {
2009
2012
  deps.writeStdout(message);
2010
2013
  return message;
2011
2014
  }
2015
+ async function executeVaultOpsPorkbunSet(command, deps) {
2016
+ if (command.agent === "SerpentGuide") {
2017
+ throw new Error("SerpentGuide has no persistent credential vault. Store ops credentials in the owning agent vault.");
2018
+ }
2019
+ const account = (0, porkbun_ops_1.normalizePorkbunOpsAccount)(command.account);
2020
+ const promptSecret = requirePromptSecret(deps, "Porkbun ops credential entry");
2021
+ const apiKey = (0, porkbun_ops_1.requirePorkbunOpsSecret)(await promptSecret(`Porkbun API key for ${account}: `), "Porkbun API key");
2022
+ const secretApiKey = (0, porkbun_ops_1.requirePorkbunOpsSecret)(await promptSecret(`Porkbun Secret API key for ${account}: `), "Porkbun Secret API key");
2023
+ const itemName = (0, porkbun_ops_1.porkbunOpsCredentialItemName)(account);
2024
+ const payload = {
2025
+ schemaVersion: 1,
2026
+ kind: porkbun_ops_1.PORKBUN_OPS_CREDENTIAL_KIND,
2027
+ updatedAt: providerCliNow(deps).toISOString(),
2028
+ account,
2029
+ apiKey,
2030
+ secretApiKey,
2031
+ };
2032
+ const progress = createHumanCommandProgress(deps, "vault ops porkbun");
2033
+ try {
2034
+ await runCommandProgressPhase(progress, "storing Porkbun ops credentials", async () => {
2035
+ const store = (0, credential_access_1.getCredentialStore)(command.agent);
2036
+ await store.store(itemName, {
2037
+ username: account,
2038
+ password: JSON.stringify(payload),
2039
+ notes: "Operational Porkbun account API credential. Domain API access and Ouro DNS allowlists live outside this secret item.",
2040
+ });
2041
+ return itemName;
2042
+ }, () => "secret stored");
2043
+ }
2044
+ finally {
2045
+ progress.end();
2046
+ }
2047
+ const message = [
2048
+ `stored Porkbun ops credentials for ${command.agent}`,
2049
+ `item: vault:${command.agent}:${itemName}`,
2050
+ `account: ${account}`,
2051
+ "authority: Porkbun account-level API credential",
2052
+ "domain bindings and DNS allowlists live outside this secret item",
2053
+ "secret values were not printed",
2054
+ ].join("\n");
2055
+ deps.writeStdout(message);
2056
+ return message;
2057
+ }
2058
+ async function executeVaultOpsPorkbunStatus(command, deps) {
2059
+ if (command.agent === "SerpentGuide") {
2060
+ const message = "SerpentGuide has no persistent credential vault. Ops credentials belong in the owning agent vault.";
2061
+ deps.writeStdout(message);
2062
+ return message;
2063
+ }
2064
+ const store = (0, credential_access_1.getCredentialStore)(command.agent);
2065
+ const lines = [`agent: ${command.agent}`, "ops credentials: Porkbun"];
2066
+ if (command.account) {
2067
+ const account = (0, porkbun_ops_1.normalizePorkbunOpsAccount)(command.account);
2068
+ const itemName = (0, porkbun_ops_1.porkbunOpsCredentialItemName)(account);
2069
+ const meta = await store.get(itemName);
2070
+ lines.push(`item: vault:${command.agent}:${itemName}`);
2071
+ lines.push(`status: ${meta ? "present" : "missing"}`);
2072
+ if (meta?.username)
2073
+ lines.push(`account: ${meta.username}`);
2074
+ }
2075
+ else {
2076
+ const items = (await store.list()).filter((item) => item.domain.startsWith(`${porkbun_ops_1.PORKBUN_OPS_CREDENTIAL_PREFIX}/`));
2077
+ lines.push(`items: ${items.length === 0 ? "none stored" : items.map((item) => item.domain).sort().join(", ")}`);
2078
+ }
2079
+ lines.push("secret values were not printed");
2080
+ const message = lines.join("\n");
2081
+ deps.writeStdout(message);
2082
+ return message;
2083
+ }
2012
2084
  function requirePromptSecret(deps, purpose) {
2013
2085
  if (deps.promptSecret)
2014
2086
  return deps.promptSecret;
@@ -5354,6 +5426,12 @@ async function runOuroCli(args, deps = (0, cli_defaults_1.createDefaultOuroCliDe
5354
5426
  if (command.kind === "vault.config.status") {
5355
5427
  return executeVaultConfigStatus(command, deps);
5356
5428
  }
5429
+ if (command.kind === "vault.ops.porkbun.set") {
5430
+ return executeVaultOpsPorkbunSet(command, deps);
5431
+ }
5432
+ if (command.kind === "vault.ops.porkbun.status") {
5433
+ return executeVaultOpsPorkbunStatus(command, deps);
5434
+ }
5357
5435
  // ── auth (local, no daemon socket needed) ──
5358
5436
  if (command.kind === "auth.run") {
5359
5437
  return executeAuthRun(command, deps);
@@ -212,9 +212,9 @@ exports.COMMAND_REGISTRY = {
212
212
  vault: {
213
213
  category: "Auth",
214
214
  description: "Create, replace, recover, unlock, inspect, and populate the agent credential vault",
215
- usage: "ouro vault <create|replace|recover|unlock|status|config> [--agent <name>]",
215
+ usage: "ouro vault <create|replace|recover|unlock|status|config|ops> [--agent <name>]",
216
216
  example: "ouro vault status",
217
- subcommands: ["create", "replace", "recover", "unlock", "status", "config set", "config status"],
217
+ subcommands: ["create", "replace", "recover", "unlock", "status", "config set", "config status", "ops porkbun set", "ops porkbun status"],
218
218
  },
219
219
  thoughts: {
220
220
  category: "Internal",
@@ -366,6 +366,16 @@ const SUBCOMMAND_HELP = {
366
366
  usage: "ouro vault config status [--agent <name>] [--scope agent|machine|all]",
367
367
  example: "ouro vault config status --scope all",
368
368
  },
369
+ "vault ops porkbun set": {
370
+ description: "Store account-scoped Porkbun API credentials as an ops vault item, outside connect/runtime config",
371
+ usage: "ouro vault ops porkbun set [--agent <name>] --account <account>",
372
+ example: "ouro vault ops porkbun set --agent slugger --account ari@mendelow.me",
373
+ },
374
+ "vault ops porkbun status": {
375
+ description: "Check whether Porkbun ops credentials are present without printing secret values",
376
+ usage: "ouro vault ops porkbun status [--agent <name>] [--account <account>]",
377
+ example: "ouro vault ops porkbun status --agent slugger --account ari@mendelow.me",
378
+ },
369
379
  };
370
380
  // ── Levenshtein distance ──
371
381
  function levenshteinDistance(a, b) {
@@ -16,6 +16,7 @@ exports.parseMcpServeCommand = parseMcpServeCommand;
16
16
  exports.parseOuroCommand = parseOuroCommand;
17
17
  const types_1 = require("../../mind/friends/types");
18
18
  const cli_help_1 = require("./cli-help");
19
+ const porkbun_ops_1 = require("./porkbun-ops");
19
20
  // ── Shared helpers ──
20
21
  function extractAgentFlag(args) {
21
22
  const idx = args.indexOf("--agent");
@@ -95,6 +96,8 @@ function usage() {
95
96
  " ouro vault status [--agent <name>] [--store auto|macos-keychain|windows-dpapi|linux-secret-service|plaintext-file]",
96
97
  " ouro vault config set [--agent <name>] --key <path> [--value <value>] [--scope agent|machine]",
97
98
  " ouro vault config status [--agent <name>] [--scope agent|machine|all]",
99
+ " ouro vault ops porkbun set [--agent <name>] --account <account>",
100
+ " ouro vault ops porkbun status [--agent <name>] [--account <account>]",
98
101
  " ouro chat <agent>",
99
102
  " ouro msg --to <agent> [--session <id>] [--task <ref>] <message>",
100
103
  " ouro poke <agent> --task <task-id>",
@@ -458,6 +461,8 @@ function parseVaultCommand(args) {
458
461
  const sub = args[0];
459
462
  if (sub === "config")
460
463
  return parseVaultConfigCommand(args.slice(1));
464
+ if (sub === "ops")
465
+ return parseVaultOpsCommand(args.slice(1));
461
466
  const { agent, rest } = extractAgentFlag(args.slice(1));
462
467
  let email;
463
468
  let serverUrl;
@@ -544,6 +549,33 @@ function parseVaultCommand(args) {
544
549
  }
545
550
  return { kind: "vault.status", ...(agent ? { agent } : {}), ...(store ? { store } : {}) };
546
551
  }
552
+ function parseVaultOpsCommand(args) {
553
+ const provider = args[0];
554
+ const action = args[1];
555
+ if (provider !== "porkbun") {
556
+ throw new Error("Usage: ouro vault ops porkbun set|status [--agent <name>] [--account <account>]");
557
+ }
558
+ if (action !== "set" && action !== "status") {
559
+ throw new Error("Usage: ouro vault ops porkbun set|status [--agent <name>] [--account <account>]");
560
+ }
561
+ const { agent, rest } = extractAgentFlag(args.slice(2));
562
+ let account;
563
+ for (let i = 0; i < rest.length; i += 1) {
564
+ const token = rest[i];
565
+ if (token === "--account") {
566
+ account = (0, porkbun_ops_1.normalizePorkbunOpsAccount)(rest[i + 1]);
567
+ i += 1;
568
+ continue;
569
+ }
570
+ throw new Error(`Usage: ouro vault ops porkbun ${action} [--agent <name>] [--account <account>]`);
571
+ }
572
+ if (action === "set") {
573
+ if (!account)
574
+ throw new Error("Usage: ouro vault ops porkbun set [--agent <name>] --account <account>");
575
+ return { kind: "vault.ops.porkbun.set", ...(agent ? { agent } : {}), account };
576
+ }
577
+ return { kind: "vault.ops.porkbun.status", ...(agent ? { agent } : {}), ...(account ? { account } : {}) };
578
+ }
547
579
  function parseVaultConfigCommand(args) {
548
580
  const sub = args[0];
549
581
  const { agent, rest } = extractAgentFlag(args.slice(1));
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PORKBUN_OPS_CREDENTIAL_PREFIX = exports.PORKBUN_OPS_CREDENTIAL_KIND = void 0;
4
+ exports.normalizePorkbunOpsAccount = normalizePorkbunOpsAccount;
5
+ exports.porkbunOpsCredentialItemName = porkbunOpsCredentialItemName;
6
+ exports.requirePorkbunOpsSecret = requirePorkbunOpsSecret;
7
+ exports.PORKBUN_OPS_CREDENTIAL_KIND = "ops-credential/porkbun";
8
+ exports.PORKBUN_OPS_CREDENTIAL_PREFIX = "ops/registrars/porkbun/accounts";
9
+ const PORKBUN_OPS_ACCOUNT_FORBIDDEN = /[\/\r\n\t]/;
10
+ function normalizePorkbunOpsAccount(account) {
11
+ const normalized = account?.trim() ?? "";
12
+ if (!normalized || PORKBUN_OPS_ACCOUNT_FORBIDDEN.test(normalized)) {
13
+ throw new Error("Porkbun account must be a non-empty account label without slashes or control characters.");
14
+ }
15
+ return normalized;
16
+ }
17
+ function porkbunOpsCredentialItemName(account) {
18
+ return `${exports.PORKBUN_OPS_CREDENTIAL_PREFIX}/${normalizePorkbunOpsAccount(account)}`;
19
+ }
20
+ function requirePorkbunOpsSecret(value, label) {
21
+ const trimmed = value.trim();
22
+ if (!trimmed)
23
+ throw new Error(`${label} cannot be blank`);
24
+ return trimmed;
25
+ }
@@ -59,10 +59,11 @@ const DISPATCH_EXEMPT_PATTERNS = [
59
59
  "repertoire/tools-config",
60
60
  "repertoire/tools-base",
61
61
  // CLI sub-modules: cli-exec.ts is the router with emitNervesEvent calls;
62
- // cli-parse, cli-render, and cli-help are pure functions/data with no side effects.
62
+ // cli-parse, cli-render, cli-help, and their small helpers are pure functions/data with no side effects.
63
63
  "daemon/cli-parse",
64
64
  "daemon/cli-render",
65
65
  "daemon/cli-help",
66
+ "daemon/porkbun-ops",
66
67
  // Shared utility modules: pure helpers consumed by modules that own observability.
67
68
  "arc/json-store",
68
69
  "repertoire/api-client",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ouro.bot/cli",
3
- "version": "0.1.0-alpha.464",
3
+ "version": "0.1.0-alpha.465",
4
4
  "main": "dist/heart/daemon/ouro-entry.js",
5
5
  "bin": {
6
6
  "cli": "dist/heart/daemon/ouro-bot-entry.js",