feat(cli): emit JSON envelope on init --agent --json reuse paths
PRD's documented form is `mem0 init --agent --json`, but rules 1/2
(env/config reuse) called printSuccess which is silenced under
agent mode — so the command exited 0 with no output.
Two related fixes:
1. Add `--json` as a subcommand-level option on init (Node only;
Python's argv preprocessor already handles this). Lets the
PRD-style invocation `mem0 init --agent --json` parse without
"unknown option" error.
2. When agent mode is set AND a rule 1/2 reuse fires, emit the
Dev Spec C4 envelope:
{
"status": "success", "command": "init",
"data": {
"api_key_saved": false,
"api_key_source": "env" | "config",
"agent_mode": false,
"message": "Existing Mem0 API key found and reused..."
}
}
Identical shape between Python and Node (parity).
Verified live: `init --agent --json` against prod with a valid
MEM0_API_KEY env returns the envelope above (no bootstrap call).
This commit is contained in:
@@ -21,6 +21,8 @@ import {
|
||||
redactKey,
|
||||
saveConfig,
|
||||
} from "../config.js";
|
||||
import { formatJsonEnvelope } from "../output.js";
|
||||
import { isAgentMode } from "../state.js";
|
||||
|
||||
const { brand, dim } = colors;
|
||||
|
||||
@@ -328,12 +330,30 @@ export async function runInit(
|
||||
const agentCtx =
|
||||
opts.agent === true || isAgentMode() || detectAgentCaller() !== null;
|
||||
if (!opts.apiKey && !opts.email && agentCtx) {
|
||||
const emitReuseEnvelope = (source: "env" | "config") => {
|
||||
if (isAgentMode()) {
|
||||
formatJsonEnvelope({
|
||||
command: "init",
|
||||
data: {
|
||||
api_key_saved: false,
|
||||
api_key_source: source,
|
||||
agent_mode: false,
|
||||
message:
|
||||
"Existing Mem0 API key found and reused. No Agent Mode key was created.",
|
||||
},
|
||||
});
|
||||
} else {
|
||||
printSuccess(
|
||||
source === "env"
|
||||
? "Existing MEM0_API_KEY is valid; reusing it. No new Agent Mode key was minted."
|
||||
: "Existing API key in config is valid; reusing it. No new Agent Mode key was minted.",
|
||||
);
|
||||
}
|
||||
};
|
||||
// Rule 1: env MEM0_API_KEY valid → reuse, no new key.
|
||||
const envKey = (process.env.MEM0_API_KEY || "").trim();
|
||||
if (envKey && (await pingKey(envKey, baseUrl))) {
|
||||
printSuccess(
|
||||
"Existing MEM0_API_KEY is valid; reusing it. No new Agent Mode key was minted.",
|
||||
);
|
||||
emitReuseEnvelope("env");
|
||||
fireInit("existing_key");
|
||||
return;
|
||||
}
|
||||
@@ -342,9 +362,7 @@ export async function runInit(
|
||||
savedConfig.platform.apiKey &&
|
||||
(await pingKey(savedConfig.platform.apiKey, baseUrl))
|
||||
) {
|
||||
printSuccess(
|
||||
"Existing API key in config is valid; reusing it. No new Agent Mode key was minted.",
|
||||
);
|
||||
emitReuseEnvelope("config");
|
||||
fireInit("existing_key");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -211,11 +211,19 @@ program
|
||||
"--source <channel>",
|
||||
"Channel attribution for signup (e.g. github, hn, ph).",
|
||||
)
|
||||
// Accept `--json` at the init level too so the PRD-documented form
|
||||
// `mem0 init --agent --json` works without requiring users to move it
|
||||
// before the subcommand. Effect is identical to the global `--json`:
|
||||
// flip agent-mode output state.
|
||||
.option("--json", "Output as JSON (alias for global `--json`).", false)
|
||||
.addHelpText(
|
||||
"after",
|
||||
"\nExamples:\n $ mem0 init\n $ mem0 init --api-key m0-xxx --user-id alice\n $ mem0 init --email you@example.com\n $ mem0 init --email you@example.com --code 123456\n $ mem0 init --agent # Bootstrap an Agent Mode account (unattended)\n $ mem0 init --email you@example.com # Claims an existing Agent Mode key when one is present",
|
||||
)
|
||||
.action(async (opts) => {
|
||||
// `--json` at init level mirrors the global flag — flip agent_mode
|
||||
// state so downstream formatters use JSON envelopes.
|
||||
if (opts.json) setAgentMode(true);
|
||||
const { runInit } = await import("./commands/init.js");
|
||||
await runInit({
|
||||
apiKey: opts.apiKey,
|
||||
|
||||
Reference in New Issue
Block a user