@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 +1 -0
- package/changelog.json +8 -0
- package/dist/heart/daemon/cli-exec.js +78 -0
- package/dist/heart/daemon/cli-help.js +12 -2
- package/dist/heart/daemon/cli-parse.js +32 -0
- package/dist/heart/daemon/porkbun-ops.js +25 -0
- package/dist/nerves/coverage/file-completeness.js +2 -1
- package/package.json +1 -1
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,
|
|
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",
|