feat(cli): rework claim to OTP-only — drop device flow + browser + polling

Replace claim_via_device_flow / claimViaDeviceFlow with claim_via_otp /
claimViaOtp. The new flow:
  1. POST /api/v1/auth/email_code/ with the user's email
  2. Prompt for the verification code (or accept via --code for non-TTY)
  3. POST /.../verify/ with {email, code, agent_mode_api_key: <local key>}
  4. Backend's verify_email_code runs upgrade-in-place inline and returns
     {claimed: true, claimed_at, ...}

No browser open, no localhost:3000 frontend dependency, no 10-minute poll
loop. Just two HTTP calls + an OTP prompt. Same upgrade-in-place
semantics on the backend; same key-value-unchanged guarantee for the
caller.

--code flag still supported on `mem0 init --email` for non-interactive
use (CI, agent-driven claim scripts).
This commit is contained in:
Mgeeeek
2026-05-13 23:08:20 +05:30
parent bcba0560c4
commit 1c92c466c4
4 changed files with 181 additions and 165 deletions
+2 -2
View File
@@ -254,7 +254,7 @@ export async function runInit(
} = {},
): Promise<void> {
const { detectAgentCaller } = await import("../agent-detect.js");
const { bootstrapViaBackend, claimViaDeviceFlow } = await import("./agent-mode.js");
const { bootstrapViaBackend, claimViaOtp } = await import("./agent-mode.js");
const { isAgentMode } = await import("../state.js");
const { captureEvent } = await import("../telemetry.js");
@@ -290,7 +290,7 @@ export async function runInit(
const email = opts.email.trim().toLowerCase();
validateEmail(email);
printInfo(`Claiming Agent Mode account to ${email}...`);
await claimViaDeviceFlow(savedConfig, { email });
await claimViaOtp(savedConfig, { email, code: opts.code });
fireInit("email", true);
return;
}