@mnemom/mnemom 0.17.4-next.7 → 0.17.4-next.8

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.
@@ -13,7 +13,8 @@
13
13
  */
14
14
  import { spawnSync } from "node:child_process";
15
15
  import { existsSync } from "node:fs";
16
- import { anthropicKeySource, checkRcCapability, resolveCliBin } from "./agent.js";
16
+ import { anthropicKeySource, checkRcCapability, defaultConsoleKeyDeps, resolveCliBin, } from "./agent.js";
17
+ import { readConsoleKey } from "../lib/console-key.js";
17
18
  import { resolveAgentAuth } from "../lib/subscription-login.js";
18
19
  import { isProdGateway, resolveAnthropicDoor, resolveGatewayHost, singleCellError, } from "../lib/agent.js";
19
20
  import { getApiUrl, getGatewayUrl } from "../lib/config.js";
@@ -52,11 +53,17 @@ export async function agentDoctorCommand(options = {}) {
52
53
  auth = resolveAgentAuth(undefined, env);
53
54
  }
54
55
  catch (err) {
55
- add("miss", `auth: ${err instanceof Error ? err.message : String(err)}`, "`mnemom agent config set auth api-key` (or subscription)");
56
+ add("miss", `auth: ${err instanceof Error ? err.message : String(err)}`, "`mnemom agent config set auth api-key` (or subscription, console)");
56
57
  }
57
58
  if (auth === "subscription") {
58
59
  add("ok", "auth: subscription — Claude Code uses your claude.ai login (Team/Enterprise plans only); no Anthropic key needed");
59
60
  }
61
+ else if (auth === "console") {
62
+ if (readConsoleKey(defaultConsoleKeyDeps(env)))
63
+ add("ok", "auth: console — using the API key your Claude Code Anthropic Console login created");
64
+ else
65
+ add("miss", "auth: console — Claude Code has no Anthropic Console login on this machine", 'run `claude`, then /login → "Anthropic Console account" — or `mnemom agent config set auth api-key`');
66
+ }
60
67
  else {
61
68
  const keySrc = anthropicKeySource(env);
62
69
  if (keySrc === "env")
@@ -28,6 +28,7 @@
28
28
  import { type MnemomKeyDeps } from "../lib/subscription-login.js";
29
29
  import { type SessionRecord } from "../lib/agent-ledger.js";
30
30
  import { type ExperimentalId } from "../lib/experimental.js";
31
+ import { type ConsoleKeyDeps } from "../lib/console-key.js";
31
32
  import { type ContextProfile, type LaunchShape, type SealedContractEnvelope } from "../lib/agent.js";
32
33
  export interface AgentOptions {
33
34
  goal?: string;
@@ -191,6 +192,8 @@ export declare function recordSessionLaunch(ctx: {
191
192
  }): Promise<void>;
192
193
  /** The real I/O behind a subscription launch's Mnemom key (lib/subscription-login.ts). */
193
194
  export declare function defaultMnemomKeyDeps(storePath?: string): MnemomKeyDeps;
195
+ /** The real machine behind lib/console-key.ts: the macOS keychain via `security`, no shell. */
196
+ export declare function defaultConsoleKeyDeps(env: NodeJS.ProcessEnv): ConsoleKeyDeps;
194
197
  /**
195
198
  * Resolve the Anthropic key with NO 1Password dependency (built for external
196
199
  * customer adoption), in order:
@@ -28,7 +28,7 @@
28
28
  import { spawn, spawnSync } from "node:child_process";
29
29
  import { existsSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync, renameSync, } from "node:fs";
30
30
  import { randomUUID } from "node:crypto";
31
- import { tmpdir, homedir, hostname } from "node:os";
31
+ import { tmpdir, homedir, hostname, userInfo } from "node:os";
32
32
  import { basename, join, dirname } from "node:path";
33
33
  import { fileURLToPath } from "node:url";
34
34
  import { getApiUrl, getGatewayUrl, MNEMOM_DIR } from "../lib/config.js";
@@ -41,6 +41,7 @@ import { experimentalNotice } from "../lib/experimental.js";
41
41
  import { fmt } from "../lib/format.js";
42
42
  import { askInput, askSelect, askYesNo, isInteractive } from "../lib/prompt.js";
43
43
  import { authConfigured, chooseAuth, detectClaudeLogin, readClaudeLoginState, } from "../lib/login-detect.js";
44
+ import { requireConsoleKey, readConsoleKey } from "../lib/console-key.js";
44
45
  import { goalAlignmentLine, resolveSessionSetup } from "./agent-session.js";
45
46
  import { AgentIdentityMismatchError, defaultAgentSlug, ensureGovernedAgent, ensureSessionAndBalance, isQuietPreambleExit, resolveDefaultSlug, resolvePreflightedAccount, } from "./agent-setup.js";
46
47
  import { assembleContract, buildGoalModeHeader, buildCustomHeaders, buildHandoffMcpConfigJson, buildSessionConfig, buildSessionConfigB64, applyGatewayHintHeaders, resolveCompactionIntercept, resolveContextHandoff, resolveContextProfile, resolveHandoffGatewayHost, HANDOFF_RC_KEY_ENV_NAME, isProdGateway, launchPreferenceExplicit, launchPreflighted, remoteControlAllowed, applyToolSearchDefault, DISABLE_1M_ENV, readCcSettings, resolveWindowModel, resolveAnthropicDoor, resolveLaunchModel, resolveConversationId, resolveGatewayHost, singleCellError, resolveLaunchShape, resolveRemoteControlShape, passthroughName, sanitizeAgentName, sessionDisplayName, SESSION_NAME_ENV, SESSION_CONFIG_HEADER, } from "../lib/agent.js";
@@ -87,8 +88,10 @@ export async function agentCommand(scenarioArg, options = {}) {
87
88
  // Nothing configured it yet: detect Claude Code's own login and, when there is a real
88
89
  // choice, ask once and save the answer (lib/login-detect.ts). Never on --dry-run.
89
90
  if (!options.dryRun && !authConfigured(options.auth, env)) {
91
+ const loginState = readClaudeLoginState(env, homedir(), (path) => readFileSync(path, "utf8"));
90
92
  auth = await chooseAuth({
91
- login: detectClaudeLogin(readClaudeLoginState(env, homedir(), (path) => readFileSync(path, "utf8"))),
93
+ login: detectClaudeLogin(loginState),
94
+ consoleKeyAvailable: () => readConsoleKey(defaultConsoleKeyDeps(env)) !== undefined,
92
95
  interactive: isInteractive(),
93
96
  select: askSelect,
94
97
  persist: (choice) => {
@@ -214,6 +217,9 @@ export async function agentCommand(scenarioArg, options = {}) {
214
217
  if (auth === "subscription") {
215
218
  say("mnemom agent: auth = subscription — Claude Code would use your claude.ai login (Team/Enterprise plans only) with a Mnemom API key; no Anthropic key.");
216
219
  }
220
+ if (auth === "console") {
221
+ say("mnemom agent: auth = console — the launch would use the API key your Claude Code Anthropic Console login created.");
222
+ }
217
223
  if (expNotice)
218
224
  say(expNotice);
219
225
  if (previewShape === "remote-control") {
@@ -235,9 +241,12 @@ export async function agentCommand(scenarioArg, options = {}) {
235
241
  }
236
242
  // ── resolve the Anthropic key (zero 1Password; never logged) ──
237
243
  // Not on a subscription launch: Claude Code then sends its own claude.ai login instead.
238
- const anthropicKey = auth === "api-key"
239
- ? await resolveAnthropicKey(env, { allowPrompt: true, keySource: options.keySource })
240
- : undefined;
244
+ // A Console launch uses the key Claude Code's Console login created, then runs as api-key.
245
+ const anthropicKey = auth === "subscription"
246
+ ? undefined
247
+ : auth === "console"
248
+ ? requireConsoleKey(defaultConsoleKeyDeps(env))
249
+ : await resolveAnthropicKey(env, { allowPrompt: true, keySource: options.keySource });
241
250
  // ── account + µ-balance gate (no free tier) ─────────────────────────────────
242
251
  // mnemom agent runs governed and on µ, so before we seal a contract or launch we
243
252
  // (1) ensure a Mnemom session — offering the try-me-style sign-in / sign-up when
@@ -675,6 +684,23 @@ export function defaultMnemomKeyDeps(storePath = CODE_STORE) {
675
684
  say,
676
685
  };
677
686
  }
687
+ /** The real machine behind lib/console-key.ts: the macOS keychain via `security`, no shell. */
688
+ export function defaultConsoleKeyDeps(env) {
689
+ return {
690
+ platform: process.platform,
691
+ env,
692
+ username: () => userInfo().username,
693
+ readKeychain: (service, account) => {
694
+ const r = spawnSync("security", ["find-generic-password", "-a", account, "-w", "-s", service], {
695
+ encoding: "utf8",
696
+ timeout: 5_000,
697
+ });
698
+ return r.status === 0 ? r.stdout : undefined;
699
+ },
700
+ claudeJson: readClaudeLoginState(env, homedir(), (path) => readFileSync(path, "utf8"))
701
+ .claudeJson,
702
+ };
703
+ }
678
704
  /**
679
705
  * Resolve the Anthropic key with NO 1Password dependency (built for external
680
706
  * customer adoption), in order:
package/dist/index.js CHANGED
@@ -143,7 +143,7 @@ const agentCmd = program
143
143
  .option("--gateway <url>", "Gateway host override — must be the same cell as the rest of the CLI (default: that cell's gateway; or MNEMOM_AGENT_GATEWAY)")
144
144
  .option("--remote-control", "Interactive Remote Control session in THIS terminal (behind a local proxy)")
145
145
  .option("--server", "Headless `claude remote-control` dispatcher (behind a local proxy)")
146
- .option("--auth <mode>", "How Claude Code authenticates: api-key (default) | subscription (your Claude Team/Enterprise login)")
146
+ .option("--auth <mode>", "How Claude Code authenticates: api-key (default) | subscription (your Claude Team/Enterprise login) | console (the API key your Claude Code Anthropic Console login created)")
147
147
  .option("--model <alias|id>", "Model to launch (CLI alias or concrete id)")
148
148
  .addOption(new Option("--effort <level>", "Reasoning effort").choices([
149
149
  "low",
@@ -0,0 +1,40 @@
1
+ /**
2
+ * `mnemom agent` with an Anthropic Console login (`auth = console`).
3
+ *
4
+ * Claude Code's `/login` → "Anthropic Console account" uses OAuth only to create a real
5
+ * Anthropic API key, which Claude Code stores and then sends as `x-api-key` ("/login
6
+ * managed key"). This module reads that key from where Claude Code keeps it, so the launch
7
+ * runs exactly like `auth = api-key` — same headers, same birth and claim, same identity —
8
+ * with no key for the user to copy. The key is read per launch and never stored by us.
9
+ *
10
+ * Where Claude Code keeps it (Claude Code 2.1.285, confirmed against the binary and a live
11
+ * probe on 2026-10-02):
12
+ * - macOS: the login keychain, service `Claude Code`, account $USER. When
13
+ * CLAUDE_CONFIG_DIR is set the service gains `-<first 8 hex of sha256(the raw
14
+ * CLAUDE_CONFIG_DIR value, NFC)>`; CLAUDE_SECURESTORAGE_CONFIG_DIR, when set, replaces
15
+ * that value (empty = no suffix).
16
+ * - everywhere (and the macOS fallback): `primaryApiKey` in Claude Code's .claude.json.
17
+ *
18
+ * A `claude auth login --console` *profile* (keyless OAuth, ~/.config/anthropic) creates no
19
+ * such key, so it is not read here.
20
+ *
21
+ * Pure apart from the injected deps, so every arm is unit-tested.
22
+ */
23
+ export interface ConsoleKeyDeps {
24
+ platform: NodeJS.Platform;
25
+ env: Record<string, string | undefined>;
26
+ /** os.userInfo().username, for when $USER is unset. */
27
+ username(): string;
28
+ /** The keychain password for (service, account), or undefined when absent. */
29
+ readKeychain(service: string, account: string): string | undefined;
30
+ /** Parsed .claude.json (see readClaudeLoginState), or undefined. */
31
+ claudeJson: unknown;
32
+ }
33
+ /** The keychain service name Claude Code stores the managed key under. */
34
+ export declare function claudeKeychainService(env: Record<string, string | undefined>): string;
35
+ /** The keychain account Claude Code uses: $USER, else the OS username, else a fixed name. */
36
+ export declare function claudeKeychainAccount(env: Record<string, string | undefined>, username: () => string): string;
37
+ /** Claude Code's Console-login API key on this machine, or undefined. Never throws. */
38
+ export declare function readConsoleKey(deps: ConsoleKeyDeps): string | undefined;
39
+ /** The key for an `auth = console` launch; throws with what to do when there is none. */
40
+ export declare function requireConsoleKey(deps: ConsoleKeyDeps): string;
@@ -0,0 +1,77 @@
1
+ /**
2
+ * `mnemom agent` with an Anthropic Console login (`auth = console`).
3
+ *
4
+ * Claude Code's `/login` → "Anthropic Console account" uses OAuth only to create a real
5
+ * Anthropic API key, which Claude Code stores and then sends as `x-api-key` ("/login
6
+ * managed key"). This module reads that key from where Claude Code keeps it, so the launch
7
+ * runs exactly like `auth = api-key` — same headers, same birth and claim, same identity —
8
+ * with no key for the user to copy. The key is read per launch and never stored by us.
9
+ *
10
+ * Where Claude Code keeps it (Claude Code 2.1.285, confirmed against the binary and a live
11
+ * probe on 2026-10-02):
12
+ * - macOS: the login keychain, service `Claude Code`, account $USER. When
13
+ * CLAUDE_CONFIG_DIR is set the service gains `-<first 8 hex of sha256(the raw
14
+ * CLAUDE_CONFIG_DIR value, NFC)>`; CLAUDE_SECURESTORAGE_CONFIG_DIR, when set, replaces
15
+ * that value (empty = no suffix).
16
+ * - everywhere (and the macOS fallback): `primaryApiKey` in Claude Code's .claude.json.
17
+ *
18
+ * A `claude auth login --console` *profile* (keyless OAuth, ~/.config/anthropic) creates no
19
+ * such key, so it is not read here.
20
+ *
21
+ * Pure apart from the injected deps, so every arm is unit-tested.
22
+ */
23
+ import { createHash } from "node:crypto";
24
+ const ACCOUNT_RE = /^[a-zA-Z0-9._-]+$/;
25
+ /** The keychain service name Claude Code stores the managed key under. */
26
+ export function claudeKeychainService(env) {
27
+ const secure = env.CLAUDE_SECURESTORAGE_CONFIG_DIR;
28
+ const dir = secure !== undefined ? secure : (env.CLAUDE_CONFIG_DIR ?? "");
29
+ if (!dir)
30
+ return "Claude Code";
31
+ const hash = createHash("sha256").update(dir.normalize("NFC")).digest("hex").slice(0, 8);
32
+ return `Claude Code-${hash}`;
33
+ }
34
+ /** The keychain account Claude Code uses: $USER, else the OS username, else a fixed name. */
35
+ export function claudeKeychainAccount(env, username) {
36
+ let name;
37
+ try {
38
+ name = env.USER || username();
39
+ }
40
+ catch {
41
+ name = "";
42
+ }
43
+ return ACCOUNT_RE.test(name) ? name : "claude-code-user";
44
+ }
45
+ /** The key is spliced into a newline-joined header block, so CR/LF must never survive. */
46
+ function clean(raw) {
47
+ const v = (raw ?? "").replace(/[\r\n]+/g, "").trim();
48
+ return v || undefined;
49
+ }
50
+ /** Claude Code's Console-login API key on this machine, or undefined. Never throws. */
51
+ export function readConsoleKey(deps) {
52
+ if (deps.platform === "darwin") {
53
+ let fromKeychain;
54
+ try {
55
+ fromKeychain = clean(deps.readKeychain(claudeKeychainService(deps.env), claudeKeychainAccount(deps.env, deps.username)));
56
+ }
57
+ catch {
58
+ fromKeychain = undefined;
59
+ }
60
+ if (fromKeychain)
61
+ return fromKeychain;
62
+ }
63
+ const json = deps.claudeJson;
64
+ const stored = json && typeof json === "object"
65
+ ? json.primaryApiKey
66
+ : undefined;
67
+ return typeof stored === "string" ? clean(stored) : undefined;
68
+ }
69
+ /** The key for an `auth = console` launch; throws with what to do when there is none. */
70
+ export function requireConsoleKey(deps) {
71
+ const key = readConsoleKey(deps);
72
+ if (key)
73
+ return key;
74
+ throw new Error("mnemom agent: auth = console, but Claude Code has no Anthropic Console login on this machine.\n" +
75
+ ' Sign in: run `claude`, then /login → "Anthropic Console account".\n' +
76
+ " Or use a key instead: `mnemom agent config set auth api-key`.");
77
+ }
@@ -135,7 +135,7 @@ export const CONFIG_KEYS = [
135
135
  },
136
136
  {
137
137
  key: "auth",
138
- describe: `How Claude Code authenticates (${AGENT_AUTHS.join("|")}); subscription = your Claude Team/Enterprise login`,
138
+ describe: `How Claude Code authenticates (${AGENT_AUTHS.join("|")}); subscription = your Claude Team/Enterprise login, console = your Claude Code Anthropic Console login's key`,
139
139
  get: (c) => c.auth,
140
140
  set: (c, v) => {
141
141
  c.auth = coerceAgentAuth(v);
@@ -6,7 +6,9 @@
6
6
  * Four ways Claude Code can be signed in, and what the gateway does with each today:
7
7
  * - Claude subscription, Team or Enterprise → `auth = subscription` (supported).
8
8
  * - Claude subscription, Pro / Max (individual) → not supported (Team/Enterprise only).
9
- * - Anthropic Console login → not supported yet.
9
+ * - Anthropic Console login (`/login` → Console account) → `auth = console` (supported): the
10
+ * API key Claude Code created is read from its keychain (lib/console-key.ts). A
11
+ * `claude auth login --console` profile creates no key → not supported yet.
10
12
  * - Third-party provider (Bedrock / Vertex / Foundry) → not supported yet (no gateway door).
11
13
  * An Anthropic API key always works (`auth = api-key`, the default).
12
14
  *
@@ -16,7 +18,7 @@
16
18
  *
17
19
  * Pure apart from the injected deps, so every arm is unit-tested.
18
20
  */
19
- import type { AgentAuth } from "./subscription-login.js";
21
+ import { type AgentAuth } from "./subscription-login.js";
20
22
  export type ThirdPartyProvider = "bedrock" | "vertex" | "foundry";
21
23
  export type ClaudeLogin = {
22
24
  kind: "subscription";
@@ -46,10 +48,13 @@ export type UnsupportedLogin = Extract<ClaudeLogin, {
46
48
  /** Why a detected login can't be used through the gateway. */
47
49
  export declare function unsupportedReason(login: UnsupportedLogin): string;
48
50
  export declare const MENU_SUBSCRIPTION = "Claude subscription \u2014 Team or Enterprise (your claude.ai login)";
51
+ export declare const MENU_CONSOLE = "Anthropic Console \u2014 the API key your Claude Code /login created (API billing)";
49
52
  export declare const MENU_API_KEY = "Anthropic API key";
50
53
  export interface ChooseAuthDeps {
51
54
  login: ClaudeLogin;
52
55
  interactive: boolean;
56
+ /** Whether Claude Code's Console-login key is readable (lib/console-key.ts); asked only for a Console login. */
57
+ consoleKeyAvailable(): boolean;
53
58
  select(question: string, options: string[]): Promise<string | null>;
54
59
  persist(auth: AgentAuth): void;
55
60
  say(line: string): void;
@@ -58,8 +63,9 @@ export interface ChooseAuthDeps {
58
63
  * Pick `auth` when nothing configured it (no --auth, MNEMOM_AGENT_AUTH or launcher.toml).
59
64
  * - No Claude login detected → api-key, silently, nothing saved (today's behaviour).
60
65
  * - A login we can't use → api-key, say why once, save it so the note isn't repeated.
61
- * - Team/Enterprise and non-interactive → api-key, nothing saved (never switch a script's
62
- * auth without asking); interactive → a two-option menu (subscription or API key), answer saved.
66
+ * - Team/Enterprise, or a Console login whose key is readable, and non-interactive →
67
+ * api-key, nothing saved (never switch a script's auth without asking); interactive → a
68
+ * two-option menu (that login or an API key), answer saved.
63
69
  */
64
70
  export declare function chooseAuth(deps: ChooseAuthDeps): Promise<AgentAuth>;
65
71
  /** True when `auth` is already decided: `--auth`, or MNEMOM_AGENT_AUTH (launcher.toml folds in). */
@@ -6,7 +6,9 @@
6
6
  * Four ways Claude Code can be signed in, and what the gateway does with each today:
7
7
  * - Claude subscription, Team or Enterprise → `auth = subscription` (supported).
8
8
  * - Claude subscription, Pro / Max (individual) → not supported (Team/Enterprise only).
9
- * - Anthropic Console login → not supported yet.
9
+ * - Anthropic Console login (`/login` → Console account) → `auth = console` (supported): the
10
+ * API key Claude Code created is read from its keychain (lib/console-key.ts). A
11
+ * `claude auth login --console` profile creates no key → not supported yet.
10
12
  * - Third-party provider (Bedrock / Vertex / Foundry) → not supported yet (no gateway door).
11
13
  * An Anthropic API key always works (`auth = api-key`, the default).
12
14
  *
@@ -16,6 +18,7 @@
16
18
  *
17
19
  * Pure apart from the injected deps, so every arm is unit-tested.
18
20
  */
21
+ import { AGENT_AUTHS } from "./subscription-login.js";
19
22
  const PROVIDER_SWITCHES = [
20
23
  ["CLAUDE_CODE_USE_BEDROCK", "bedrock"],
21
24
  ["CLAUDE_CODE_USE_VERTEX", "vertex"],
@@ -60,14 +63,15 @@ export function unsupportedReason(login) {
60
63
  case "individual":
61
64
  return `your Claude ${login.plan} plan is a personal plan — Mnemom supports subscription login on Team and Enterprise plans only`;
62
65
  case "console":
63
- return "Anthropic Console login is not supported yet";
66
+ return "your Anthropic Console login has no API key Claude Code created with /login (a `claude auth login --console` profile is not supported yet)";
64
67
  case "third-party":
65
68
  return `${PROVIDER_NAMES[login.provider]} is not supported yet`;
66
69
  }
67
70
  }
68
71
  export const MENU_SUBSCRIPTION = "Claude subscription — Team or Enterprise (your claude.ai login)";
72
+ export const MENU_CONSOLE = "Anthropic Console — the API key your Claude Code /login created (API billing)";
69
73
  export const MENU_API_KEY = "Anthropic API key";
70
- const SAVED_HINT = "change it any time with `mnemom agent config set auth api-key|subscription`";
74
+ const SAVED_HINT = `change it any time with \`mnemom agent config set auth ${AGENT_AUTHS.join("|")}\``;
71
75
  function save(deps, auth, line) {
72
76
  try {
73
77
  deps.persist(auth);
@@ -82,13 +86,27 @@ function save(deps, auth, line) {
82
86
  * Pick `auth` when nothing configured it (no --auth, MNEMOM_AGENT_AUTH or launcher.toml).
83
87
  * - No Claude login detected → api-key, silently, nothing saved (today's behaviour).
84
88
  * - A login we can't use → api-key, say why once, save it so the note isn't repeated.
85
- * - Team/Enterprise and non-interactive → api-key, nothing saved (never switch a script's
86
- * auth without asking); interactive → a two-option menu (subscription or API key), answer saved.
89
+ * - Team/Enterprise, or a Console login whose key is readable, and non-interactive →
90
+ * api-key, nothing saved (never switch a script's auth without asking); interactive → a
91
+ * two-option menu (that login or an API key), answer saved.
87
92
  */
88
93
  export async function chooseAuth(deps) {
89
94
  const { login } = deps;
90
95
  if (login.kind === "none")
91
96
  return "api-key";
97
+ if (login.kind === "console" && deps.consoleKeyAvailable()) {
98
+ if (!deps.interactive)
99
+ return "api-key";
100
+ const picked = await deps.select("mnemom agent: Claude Code is signed in with an Anthropic Console account. How should it sign in through Mnemom?", [MENU_CONSOLE, MENU_API_KEY]);
101
+ if (picked === MENU_CONSOLE) {
102
+ return save(deps, "console", "mnemom agent: using your Anthropic Console login's API key.");
103
+ }
104
+ if (picked === MENU_API_KEY) {
105
+ return save(deps, "api-key", "mnemom agent: using an Anthropic API key.");
106
+ }
107
+ deps.say("mnemom agent: no choice made — using an Anthropic API key for this launch.");
108
+ return "api-key";
109
+ }
92
110
  if (login.kind !== "subscription") {
93
111
  return save(deps, "api-key", `mnemom agent: ${unsupportedReason(login)}, so this launch uses an Anthropic API key.`);
94
112
  }
@@ -17,7 +17,8 @@
17
17
  * Pure apart from the injected deps, so every arm is unit-tested.
18
18
  */
19
19
  import type { LaunchShape } from "./agent.js";
20
- export type AgentAuth = "api-key" | "subscription";
20
+ /** `console` = the API key Claude Code's Anthropic Console login created (lib/console-key.ts). */
21
+ export type AgentAuth = "api-key" | "subscription" | "console";
21
22
  export declare const AGENT_AUTHS: readonly AgentAuth[];
22
23
  /** Env override for the setting (the launcher.toml `auth` key folds into it). */
23
24
  export declare const AGENT_AUTH_ENV = "MNEMOM_AGENT_AUTH";
@@ -16,7 +16,7 @@
16
16
  *
17
17
  * Pure apart from the injected deps, so every arm is unit-tested.
18
18
  */
19
- export const AGENT_AUTHS = ["api-key", "subscription"];
19
+ export const AGENT_AUTHS = ["api-key", "subscription", "console"];
20
20
  /** Env override for the setting (the launcher.toml `auth` key folds into it). */
21
21
  export const AGENT_AUTH_ENV = "MNEMOM_AGENT_AUTH";
22
22
  /** Env override for the Mnemom key a subscription launch sends. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mnemom/mnemom",
3
- "version": "0.17.4-next.7",
3
+ "version": "0.17.4-next.8",
4
4
  "description": "Transparent AI agent tracing",
5
5
  "type": "module",
6
6
  "bin": {