From 37d5658171366c2235d6722e2a82badf5c31dee9 Mon Sep 17 00:00:00 2001 From: Mgeeeek Date: Thu, 14 May 2026 14:48:01 +0530 Subject: [PATCH] fix(cli): mem0 init --agent now triggers bootstrap (Node) + created_via parity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit External sandbox audit (Sandbox E2E Test Report 2026-05-13) surfaced two CLI issues. 1. Node — `mem0 init --agent` silently falls through to the non-TTY error when no agent env var is set. Commander resolves the program-level `--agent` alias (for --json) before init's own `--agent`; init's opts.agent stays false. Fix: enable Commander's positional options so flags AFTER a subcommand belong to that subcommand. Now `mem0 --agent ` is the JSON-output alias and `mem0 init --agent` is the Agent Mode bootstrap flag. The Python side already had an argv preprocessor doing the equivalent; this brings Node to parity using Commander's built-in mechanism (cleaner than mirroring the preprocessor). Verified: `mem0 init --agent` with bogus MEM0_BASE_URL now hits the bootstrap fetch and surfaces a network error (proving it reached bootstrap_via_backend), where before it printed "Non-interactive terminal detected" and never made an HTTP call. 2. Both — `config.platform.created_via` was inconsistent: set to "agent_mode" / "email" on the agent/claim paths but left empty on normal email signup and api-key paths. Now all four paths set it: "agent_mode" (bootstrap), "email" (OTP signup or claim), "api_key" (--api-key flag or interactive prompt). Downstream consumers can reliably filter on created_via==value. --- cli/node/src/commands/init.ts | 4 ++++ cli/node/src/index.ts | 7 ++++++- cli/python/src/mem0_cli/commands/init_cmd.py | 5 +++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/cli/node/src/commands/init.ts b/cli/node/src/commands/init.ts index a00a35430..f03c45c26 100644 --- a/cli/node/src/commands/init.ts +++ b/cli/node/src/commands/init.ts @@ -196,6 +196,7 @@ async function setupPlatform(config: Mem0Config): Promise { process.exit(1); } config.platform.apiKey = apiKey; + config.platform.createdVia = "api_key"; } async function setupDefaults(config: Mem0Config): Promise { @@ -359,6 +360,7 @@ export async function runInit( config.platform.apiKey = apiKeyVal; config.platform.baseUrl = baseUrl; config.platform.userEmail = email; + config.platform.createdVia = "email"; config.defaults.userId = opts.userId || process.env.USER || process.env.USERNAME || "mem0-cli"; @@ -403,6 +405,7 @@ export async function runInit( // Non-interactive: both flags provided if (opts.apiKey && opts.userId) { config.platform.apiKey = opts.apiKey; + config.platform.createdVia = "api_key"; config.defaults.userId = opts.userId; await validatePlatform(config); saveConfig(config); @@ -450,6 +453,7 @@ export async function runInit( config.platform.apiKey = apiKeyVal; config.platform.baseUrl = baseUrl; config.platform.userEmail = email; + config.platform.createdVia = "email"; config.defaults.userId = opts.userId || process.env.USER || process.env.USERNAME || "mem0-cli"; diff --git a/cli/node/src/index.ts b/cli/node/src/index.ts index ff9bb61aa..f29a8887f 100644 --- a/cli/node/src/index.ts +++ b/cli/node/src/index.ts @@ -141,6 +141,11 @@ program .description( `◆ Mem0 CLI v${CLI_VERSION} · Node.js SDK\n\nThe Memory Layer for AI Agents`, ) + // Positional options: flags AFTER a subcommand name belong to that + // subcommand, not the global program. Without this, `mem0 init --agent` + // routes `--agent` to the program-level alias (for --json) and init's own + // `--agent` (Agent Mode bootstrap) silently never fires. + .enablePositionalOptions() .option("--version", "Show version and exit.") .on("option:version", () => { console.log(` ${colors.brand("◆ Mem0")} CLI v${CLI_VERSION}`); @@ -149,7 +154,7 @@ program .option("--json", "Output as JSON for agent/programmatic use.") .option( "--agent", - "Output as JSON for agent/programmatic use. (alias: --json)", + "Output as JSON for agent/programmatic use. (alias: --json) Place BEFORE the subcommand: `mem0 --agent `. On `init`, `mem0 init --agent` is the Agent Mode bootstrap flag instead.", ) .usage(" [options]") .helpOption("--help", "Show this message and exit.") diff --git a/cli/python/src/mem0_cli/commands/init_cmd.py b/cli/python/src/mem0_cli/commands/init_cmd.py index f0a83b60a..775d41992 100644 --- a/cli/python/src/mem0_cli/commands/init_cmd.py +++ b/cli/python/src/mem0_cli/commands/init_cmd.py @@ -284,6 +284,7 @@ def run_init( config.platform.api_key = api_key_val config.platform.base_url = base_url config.platform.user_email = email + config.platform.created_via = "email" config.defaults.user_id = ( user_id or os.environ.get("USER") or os.environ.get("USERNAME") or "mem0-cli" ) @@ -325,6 +326,7 @@ def run_init( # Fully non-interactive when both flags provided if api_key and user_id: config.platform.api_key = api_key + config.platform.created_via = "api_key" config.defaults.user_id = user_id _validate_platform(config) save_config(config) @@ -365,6 +367,7 @@ def run_init( config.platform.api_key = api_key_val config.platform.base_url = base_url config.platform.user_email = email_addr + config.platform.created_via = "email" config.defaults.user_id = ( user_id or os.environ.get("USER") or os.environ.get("USERNAME") or "mem0-cli" ) @@ -383,6 +386,7 @@ def run_init( # API key flow if api_key: config.platform.api_key = api_key + config.platform.created_via = "api_key" else: _setup_platform(config) @@ -422,6 +426,7 @@ def _setup_platform(config: Mem0Config) -> None: raise typer.Exit(1) config.platform.api_key = api_key + config.platform.created_via = "api_key" def _setup_defaults(config: Mem0Config) -> None: