@mnemom/mnemom 0.17.0-next.6 → 0.17.0-next.7
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/dist/commands/agent-config.d.ts +17 -0
- package/dist/commands/agent-config.js +173 -0
- package/dist/commands/{code-doctor.d.ts → agent-doctor.d.ts} +2 -2
- package/dist/commands/{code-doctor.js → agent-doctor.js} +27 -22
- package/dist/commands/{code-invite.d.ts → agent-invite.d.ts} +18 -18
- package/dist/commands/{code-invite.js → agent-invite.js} +30 -30
- package/dist/commands/{code-session.d.ts → agent-session.d.ts} +2 -2
- package/dist/commands/{code-session.js → agent-session.js} +8 -8
- package/dist/commands/{code-setup.d.ts → agent-setup.d.ts} +13 -13
- package/dist/commands/{code-setup.js → agent-setup.js} +46 -42
- package/dist/commands/{code.d.ts → agent.d.ts} +14 -14
- package/dist/commands/{code.js → agent.js} +76 -76
- package/dist/commands/agents.d.ts +2 -2
- package/dist/commands/agents.js +5 -5
- package/dist/commands/onboard.js +1 -1
- package/dist/commands/wrap.js +1 -1
- package/dist/index.js +42 -47
- package/dist/lib/{code.d.ts → agent.d.ts} +9 -9
- package/dist/lib/{code.js → agent.js} +14 -14
- package/dist/lib/api.d.ts +4 -4
- package/dist/lib/api.js +9 -9
- package/dist/lib/{code-config.d.ts → launcher-config.d.ts} +23 -23
- package/dist/lib/{code-config.js → launcher-config.js} +31 -31
- package/dist/lib/version-gate.js +1 -1
- package/dist/rc-proxy.mjs +297 -134
- package/package.json +1 -1
- package/dist/commands/code-config.d.ts +0 -17
- package/dist/commands/code-config.js +0 -147
package/dist/index.js
CHANGED
|
@@ -20,12 +20,12 @@ import { apiKeyListCommand, apiKeyCreateCommand, apiKeyRotateCommand, apiKeyRevo
|
|
|
20
20
|
import { webhooksListCommand, webhooksGetCommand, webhooksCreateCommand, webhooksUpdateCommand, webhooksDeleteCommand, webhooksRotateSecretCommand, webhooksTriggerCommand, webhooksListDeliveriesCommand, webhooksRedeliverCommand, webhooksReplayCommand, } from "./commands/webhooks.js";
|
|
21
21
|
import { listenCommand } from "./commands/listen.js";
|
|
22
22
|
import { tryMeCommand } from "./commands/try-me.js";
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import { applyConfigToEnv,
|
|
23
|
+
import { agentCommand } from "./commands/agent.js";
|
|
24
|
+
import { agentConfigCommand } from "./commands/agent-config.js";
|
|
25
|
+
import { agentDoctorCommand } from "./commands/agent-doctor.js";
|
|
26
|
+
import { agentSetupCommand } from "./commands/agent-setup.js";
|
|
27
|
+
import { agentInviteCommand, runAgentInvocation } from "./commands/agent-invite.js";
|
|
28
|
+
import { applyConfigToEnv, loadLauncherConfig } from "./lib/launcher-config.js";
|
|
29
29
|
import { wrapCommand } from "./commands/wrap.js";
|
|
30
30
|
import { onboardCommand } from "./commands/onboard.js";
|
|
31
31
|
import { skillsListCommand, skillsDescribeCommand } from "./commands/skills.js";
|
|
@@ -82,7 +82,7 @@ program
|
|
|
82
82
|
});
|
|
83
83
|
// ── code — first-class governed coding-agent launcher ────────────────────────
|
|
84
84
|
//
|
|
85
|
-
// `mnemom
|
|
85
|
+
// `mnemom agent [session]` launches your coding-agent CLI (Claude Code in v1) with
|
|
86
86
|
// its dev-time model traffic routed through the Mnemom gateway's /anthropic door
|
|
87
87
|
// for observability + governance, under a governed agent identity (the
|
|
88
88
|
// program-level `--agent`, default "code-agent") and an optional per-conversation
|
|
@@ -90,7 +90,7 @@ program
|
|
|
90
90
|
// (default), --remote-control (interactive RC in this terminal), --server
|
|
91
91
|
// (headless RC dispatcher) — with yolo on by default. `--cli` selects the
|
|
92
92
|
// executable (name or full path; default claude). The us-2/prod door is the
|
|
93
|
-
// DEFAULT; set
|
|
93
|
+
// DEFAULT; set MNEMOM_AGENT_GATEWAY (or --gateway) to point elsewhere. The
|
|
94
94
|
// Anthropic key is resolved with zero 1Password dependency (env → ~/.mnemom store
|
|
95
95
|
// → interactive prompt) inside the launched process and never logged. See
|
|
96
96
|
// commands/code.ts.
|
|
@@ -99,10 +99,10 @@ const collectRepeatable = (value, previous) => {
|
|
|
99
99
|
previous.push(value);
|
|
100
100
|
return previous;
|
|
101
101
|
};
|
|
102
|
-
program
|
|
103
|
-
.command("
|
|
104
|
-
.description("Launch
|
|
105
|
-
"Sub-verbs: `
|
|
102
|
+
const agentCmd = program
|
|
103
|
+
.command("agent [session] [passthrough...]")
|
|
104
|
+
.description("Launch your governed agent (Claude Code in v1) through the Mnemom gateway — governed identity + optional sealed goal contract. Plain `mnemom agent` asks for a session name and an optional goal. " +
|
|
105
|
+
"Sub-verbs: `setup` provisions your governed agent; `doctor` preflights prerequisites; `config …` manages persistent settings (~/.mnemom/launcher.toml); `invite <token>` redeems a Mnemom Agent invitation; `list` / `claim` / `move` manage the agents in your orgs.")
|
|
106
106
|
.option("--goal <statement>", "Contract goal statement (required if any contract flag is given)")
|
|
107
107
|
.option("--requirement <text>", "Contract requirement (repeatable)", collectRepeatable, [])
|
|
108
108
|
.option("--allow <glob>", "Allowed path/glob (repeatable)", collectRepeatable, [])
|
|
@@ -113,7 +113,7 @@ program
|
|
|
113
113
|
.option("--stall <n>", "Guardrail: consecutive no-write turns (positive integer)")
|
|
114
114
|
.option("--conversation-id <id>", "x-mnemom-conversation-id (default: auto-generated)")
|
|
115
115
|
.option("--cli <name|path>", "Coding-agent CLI to launch: a name or full path (default: claude)")
|
|
116
|
-
.option("--gateway <url>", "Gateway host override (default: https://gateway.mnemom.ai; or
|
|
116
|
+
.option("--gateway <url>", "Gateway host override (default: https://gateway.mnemom.ai; or MNEMOM_AGENT_GATEWAY)")
|
|
117
117
|
.option("--remote-control", "Interactive Remote Control session in THIS terminal (behind a local proxy)")
|
|
118
118
|
.option("--server", "Headless `claude remote-control` dispatcher (behind a local proxy)")
|
|
119
119
|
.option("--model <alias|id>", "Model to launch (CLI alias or concrete id)")
|
|
@@ -125,7 +125,7 @@ program
|
|
|
125
125
|
"max",
|
|
126
126
|
]))
|
|
127
127
|
.option("--trim-mcp", "Launch the CLI with no MCP servers (--strict-mcp-config + empty --mcp-config)")
|
|
128
|
-
.option("--invite <token>", "Redeem a Mnemom
|
|
128
|
+
.option("--invite <token>", "Redeem a Mnemom Agent invitation (pinv_…): unlocks Mnemom Agent for you + credits your starter µ; launches too when a session name is given")
|
|
129
129
|
.option("--setup", "Provision + claim the governed agent before launch (non-interactive opt-in)")
|
|
130
130
|
.option("--no-setup", "Skip governed-agent provisioning entirely for this launch")
|
|
131
131
|
.option("--no-yolo", "Do NOT pass --dangerously-skip-permissions (yolo is on by default)")
|
|
@@ -133,41 +133,44 @@ program
|
|
|
133
133
|
.option("--dry-run", "Print the resolved launch plan and exit — no key read, no spawn")
|
|
134
134
|
.action(async (scenario, passthrough, opts) => {
|
|
135
135
|
try {
|
|
136
|
-
// Invitation redemption — `mnemom
|
|
137
|
-
// `mnemom
|
|
138
|
-
//
|
|
136
|
+
// Invitation redemption — `mnemom agent invite <token>` (sub-verb) or
|
|
137
|
+
// `mnemom agent --invite <token> [session]` — composes with the launch in
|
|
138
|
+
// runAgentInvocation (commands/code-invite.ts, unit-tested); everything below
|
|
139
139
|
// is the launch half, running only when a real scenario was given.
|
|
140
|
-
await
|
|
140
|
+
await runAgentInvocation({ scenario, passthrough, inviteFlag: opts.invite }, {
|
|
141
|
+
redeem: (token) => agentInviteCommand(token),
|
|
142
|
+
launch: (scenario) => launchAgent(scenario),
|
|
143
|
+
});
|
|
141
144
|
}
|
|
142
145
|
catch (error) {
|
|
143
146
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
144
147
|
process.exit(1);
|
|
145
148
|
}
|
|
146
|
-
async function
|
|
147
|
-
// Sub-verb: `mnemom
|
|
149
|
+
async function launchAgent(scenario) {
|
|
150
|
+
// Sub-verb: `mnemom agent config …` manages persistent settings and never
|
|
148
151
|
// launches. (A scenario literally named "config" is reserved for this.)
|
|
149
152
|
if (scenario === "config") {
|
|
150
|
-
await
|
|
153
|
+
await agentConfigCommand(passthrough);
|
|
151
154
|
return;
|
|
152
155
|
}
|
|
153
156
|
if (opts.gateway)
|
|
154
|
-
process.env.
|
|
155
|
-
// Persistent settings (~/.mnemom/
|
|
156
|
-
// precedence is flag > env >
|
|
157
|
+
process.env.MNEMOM_AGENT_GATEWAY = opts.gateway;
|
|
158
|
+
// Persistent settings (~/.mnemom/launcher.toml) sit UNDER env and flags:
|
|
159
|
+
// precedence is flag > env > launcher.toml > built-in. Env-backed settings are
|
|
157
160
|
// folded into env only when unset (so env/flags still win); the resolvers
|
|
158
161
|
// in lib/code.ts keep the built-in default as the final fallback.
|
|
159
|
-
const cfg =
|
|
162
|
+
const cfg = loadLauncherConfig();
|
|
160
163
|
applyConfigToEnv(cfg, process.env);
|
|
161
|
-
// Sub-verb: `mnemom
|
|
164
|
+
// Sub-verb: `mnemom agent doctor` runs a read-only preflight and never
|
|
162
165
|
// launches. Placed after config load so it reports the effective settings.
|
|
163
166
|
if (scenario === "doctor") {
|
|
164
|
-
await
|
|
167
|
+
await agentDoctorCommand({ cli: opts.cli });
|
|
165
168
|
return;
|
|
166
169
|
}
|
|
167
|
-
// Sub-verb: `mnemom
|
|
170
|
+
// Sub-verb: `mnemom agent setup` provisions/claims the governed agent and
|
|
168
171
|
// never launches. The agent slug follows the same precedence as a launch.
|
|
169
172
|
if (scenario === "setup") {
|
|
170
|
-
await
|
|
173
|
+
await agentSetupCommand({ agent: program.opts().agent ?? cfg.agent });
|
|
171
174
|
return;
|
|
172
175
|
}
|
|
173
176
|
const numToStr = (n) => n === undefined ? undefined : String(n);
|
|
@@ -179,7 +182,7 @@ program
|
|
|
179
182
|
// shadows a subcommand `--agent` under commander@12 — the MNE-238 class),
|
|
180
183
|
// exactly as status/logs/onboard read it.
|
|
181
184
|
const parentOpts = program.opts();
|
|
182
|
-
await
|
|
185
|
+
await agentCommand(scenario, {
|
|
183
186
|
goal: opts.goal,
|
|
184
187
|
requirement: opts.requirement,
|
|
185
188
|
allow: opts.allow,
|
|
@@ -625,10 +628,10 @@ policyCmd
|
|
|
625
628
|
await policyEvaluateCommand(file, options);
|
|
626
629
|
});
|
|
627
630
|
// ============================================================================
|
|
628
|
-
// Agent management
|
|
631
|
+
// Agent management — sub-verbs of `mnemom agent` (the launcher above): list / claim / move.
|
|
629
632
|
// ============================================================================
|
|
630
|
-
|
|
631
|
-
.command("
|
|
633
|
+
agentCmd
|
|
634
|
+
.command("list")
|
|
632
635
|
.description("List agents across the orgs you belong to (ADR-062 org-scoped)")
|
|
633
636
|
.option("--org <id>", "Scope to a single org (default: all orgs you belong to)")
|
|
634
637
|
.action(async (opts) => {
|
|
@@ -640,7 +643,7 @@ const agentsCmd = program
|
|
|
640
643
|
process.exit(1);
|
|
641
644
|
}
|
|
642
645
|
});
|
|
643
|
-
|
|
646
|
+
agentCmd
|
|
644
647
|
.command("claim <id-or-name>")
|
|
645
648
|
.description("Claim an agent into an org (ADR-062 claim-to-org)")
|
|
646
649
|
.option("--org <slug>", "Org slug or id to claim into (default: your ACTIVE org from `mnemom org use`, else your personal org)")
|
|
@@ -650,18 +653,10 @@ agentsCmd
|
|
|
650
653
|
.option("--json", "Output JSON instead of human-readable text")
|
|
651
654
|
.action(async (idOrName, opts) => {
|
|
652
655
|
try {
|
|
653
|
-
//
|
|
654
|
-
//
|
|
655
|
-
//
|
|
656
|
-
|
|
657
|
-
// `agents claim <id> --org <slug>` had its --org silently swallowed by
|
|
658
|
-
// `agentsCmd` before this subcommand's own `--org` option ever saw it
|
|
659
|
-
// (MNE-2496: confirmed live, the agent always landed in the caller's
|
|
660
|
-
// personal org regardless of --org). Same shadow class as the global
|
|
661
|
-
// `--agent` fix at MNE-238 (see the `advisories list`/`show` actions
|
|
662
|
-
// below) — resolve the local value first, falling back to the
|
|
663
|
-
// parent's captured value so either parse order still works.
|
|
664
|
-
const org = opts.org ?? agentsCmd.opts().org;
|
|
656
|
+
// The parent `agent` command defines no `--org`, so the MNE-2496 shadow
|
|
657
|
+
// (a parent-owned flag swallowing the subcommand.s) cannot recur here;
|
|
658
|
+
// `list` owns its own `--org` as a sibling sub-verb.
|
|
659
|
+
const org = opts.org;
|
|
665
660
|
await agentsClaimCommand(idOrName, {
|
|
666
661
|
org,
|
|
667
662
|
key: opts.key,
|
|
@@ -675,7 +670,7 @@ agentsCmd
|
|
|
675
670
|
process.exit(1);
|
|
676
671
|
}
|
|
677
672
|
});
|
|
678
|
-
|
|
673
|
+
agentCmd
|
|
679
674
|
.command("move <id-or-name>")
|
|
680
675
|
.description("Move an agent to another org — requires owner/admin in BOTH the current and destination org " +
|
|
681
676
|
"(role-based; no agent key needed, unlike re-claim)")
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lib/code.ts — the pure, IO-free core of `mnemom
|
|
2
|
+
* lib/code.ts — the pure, IO-free core of `mnemom agent`, the CLI's first-class
|
|
3
3
|
* governed-coding-agent launcher.
|
|
4
4
|
*
|
|
5
|
-
* `mnemom
|
|
5
|
+
* `mnemom agent` launches your coding-agent CLI (Claude Code in v1) with its
|
|
6
6
|
* dev-time model traffic routed through the Mnemom gateway for observability and
|
|
7
7
|
* governance, under a governed agent identity and (optionally) a governed
|
|
8
8
|
* per-conversation CONTRACT (goal / requirements / path allow-forbid lists +
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* key resolution, env assembly, and spawning the coding-agent CLI.
|
|
17
17
|
*
|
|
18
18
|
* The us-2/PROD gateway is the DEFAULT door (https://gateway.mnemom.ai). An
|
|
19
|
-
* explicit
|
|
19
|
+
* explicit MNEMOM_AGENT_GATEWAY still wins (so any other cell is reachable when
|
|
20
20
|
* NAMED), but prod is never selected silently — see `resolveGatewayHost`.
|
|
21
21
|
*/
|
|
22
22
|
/** The us-2/prod gateway host. The default door — never any other cell silently. */
|
|
@@ -53,15 +53,15 @@ export interface ContractFlags {
|
|
|
53
53
|
export type LaunchShape = "terminal" | "remote-control" | "server";
|
|
54
54
|
/**
|
|
55
55
|
* Resolve the gateway HOST (scheme + host, no path). An explicit, non-empty
|
|
56
|
-
* `
|
|
56
|
+
* `MNEMOM_AGENT_GATEWAY` wins verbatim; otherwise the us-2/prod host. The default
|
|
57
57
|
* is PROD — an unset var resolves to prod, and any other cell is reached only by
|
|
58
58
|
* NAMING it. Trailing slash trimmed so door concatenation is clean.
|
|
59
59
|
*/
|
|
60
60
|
export declare function resolveGatewayHost(env?: NodeJS.ProcessEnv): string;
|
|
61
61
|
/**
|
|
62
62
|
* The Anthropic door the CLI points Claude Code at:
|
|
63
|
-
* `${
|
|
64
|
-
* `
|
|
63
|
+
* `${MNEMOM_AGENT_GATEWAY}/anthropic`, or the full-door override
|
|
64
|
+
* `MNEMOM_AGENT_ANTHROPIC_GATEWAY` when set. v1 is Anthropic-only (no router door
|
|
65
65
|
* / Mnemom key), so the /anthropic door carries the whole contract: x-api-key +
|
|
66
66
|
* x-mnemom-{agent,conversation-id,contract}.
|
|
67
67
|
*/
|
|
@@ -117,10 +117,10 @@ export interface SealedContractEnvelope {
|
|
|
117
117
|
*/
|
|
118
118
|
export declare function assembleContract(flags: ContractFlags): SealedContractEnvelope | null;
|
|
119
119
|
/**
|
|
120
|
-
* Resolve the launch shape from the flags and the `
|
|
120
|
+
* Resolve the launch shape from the flags and the `MNEMOM_AGENT_REMOTE_CONTROL`
|
|
121
121
|
* env var (the flags win). Default is `terminal` — a plain governed launch in
|
|
122
122
|
* THIS terminal. `--remote-control` → `remote-control` (interactive RC in this
|
|
123
|
-
* terminal); `--server` (or `
|
|
123
|
+
* terminal); `--server` (or `MNEMOM_AGENT_REMOTE_CONTROL=server`) → `server` (the
|
|
124
124
|
* headless `claude remote-control` dispatcher). Throws on an invalid env value.
|
|
125
125
|
*/
|
|
126
126
|
export declare function resolveLaunchShape(opts: {
|
|
@@ -129,7 +129,7 @@ export declare function resolveLaunchShape(opts: {
|
|
|
129
129
|
}, env?: NodeJS.ProcessEnv): LaunchShape;
|
|
130
130
|
/**
|
|
131
131
|
* Did anyone EXPLICITLY choose a launch shape — a `--remote-control`/`--server`
|
|
132
|
-
* flag, or a non-empty `
|
|
132
|
+
* flag, or a non-empty `MNEMOM_AGENT_REMOTE_CONTROL` (which config.launch also
|
|
133
133
|
* sets)? When false, the command is free to AUTO-select the best shape: prefer
|
|
134
134
|
* Remote-Control-in-terminal when the machine can do it, else terminal-only. An
|
|
135
135
|
* explicit `terminal` choice (config `launch = "terminal"` → env "0") is
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lib/code.ts — the pure, IO-free core of `mnemom
|
|
2
|
+
* lib/code.ts — the pure, IO-free core of `mnemom agent`, the CLI's first-class
|
|
3
3
|
* governed-coding-agent launcher.
|
|
4
4
|
*
|
|
5
|
-
* `mnemom
|
|
5
|
+
* `mnemom agent` launches your coding-agent CLI (Claude Code in v1) with its
|
|
6
6
|
* dev-time model traffic routed through the Mnemom gateway for observability and
|
|
7
7
|
* governance, under a governed agent identity and (optionally) a governed
|
|
8
8
|
* per-conversation CONTRACT (goal / requirements / path allow-forbid lists +
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
* key resolution, env assembly, and spawning the coding-agent CLI.
|
|
17
17
|
*
|
|
18
18
|
* The us-2/PROD gateway is the DEFAULT door (https://gateway.mnemom.ai). An
|
|
19
|
-
* explicit
|
|
19
|
+
* explicit MNEMOM_AGENT_GATEWAY still wins (so any other cell is reachable when
|
|
20
20
|
* NAMED), but prod is never selected silently — see `resolveGatewayHost`.
|
|
21
21
|
*/
|
|
22
22
|
import { createHash, randomUUID } from "node:crypto";
|
|
@@ -24,24 +24,24 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
24
24
|
export const PROD_GATEWAY_HOST = "https://gateway.mnemom.ai";
|
|
25
25
|
/**
|
|
26
26
|
* Resolve the gateway HOST (scheme + host, no path). An explicit, non-empty
|
|
27
|
-
* `
|
|
27
|
+
* `MNEMOM_AGENT_GATEWAY` wins verbatim; otherwise the us-2/prod host. The default
|
|
28
28
|
* is PROD — an unset var resolves to prod, and any other cell is reached only by
|
|
29
29
|
* NAMING it. Trailing slash trimmed so door concatenation is clean.
|
|
30
30
|
*/
|
|
31
31
|
export function resolveGatewayHost(env = process.env) {
|
|
32
|
-
const raw = (env.
|
|
32
|
+
const raw = (env.MNEMOM_AGENT_GATEWAY ?? "").trim();
|
|
33
33
|
const host = raw.length > 0 ? raw : PROD_GATEWAY_HOST;
|
|
34
34
|
return host.replace(/\/+$/, "");
|
|
35
35
|
}
|
|
36
36
|
/**
|
|
37
37
|
* The Anthropic door the CLI points Claude Code at:
|
|
38
|
-
* `${
|
|
39
|
-
* `
|
|
38
|
+
* `${MNEMOM_AGENT_GATEWAY}/anthropic`, or the full-door override
|
|
39
|
+
* `MNEMOM_AGENT_ANTHROPIC_GATEWAY` when set. v1 is Anthropic-only (no router door
|
|
40
40
|
* / Mnemom key), so the /anthropic door carries the whole contract: x-api-key +
|
|
41
41
|
* x-mnemom-{agent,conversation-id,contract}.
|
|
42
42
|
*/
|
|
43
43
|
export function resolveAnthropicDoor(env = process.env) {
|
|
44
|
-
const override = (env.
|
|
44
|
+
const override = (env.MNEMOM_AGENT_ANTHROPIC_GATEWAY ?? "").trim();
|
|
45
45
|
if (override.length > 0)
|
|
46
46
|
return override.replace(/\/+$/, "");
|
|
47
47
|
return `${resolveGatewayHost(env)}/anthropic`;
|
|
@@ -183,16 +183,16 @@ function cleanList(values) {
|
|
|
183
183
|
return (values ?? []).map((v) => v.trim()).filter((v) => v.length > 0);
|
|
184
184
|
}
|
|
185
185
|
/**
|
|
186
|
-
* Resolve the launch shape from the flags and the `
|
|
186
|
+
* Resolve the launch shape from the flags and the `MNEMOM_AGENT_REMOTE_CONTROL`
|
|
187
187
|
* env var (the flags win). Default is `terminal` — a plain governed launch in
|
|
188
188
|
* THIS terminal. `--remote-control` → `remote-control` (interactive RC in this
|
|
189
|
-
* terminal); `--server` (or `
|
|
189
|
+
* terminal); `--server` (or `MNEMOM_AGENT_REMOTE_CONTROL=server`) → `server` (the
|
|
190
190
|
* headless `claude remote-control` dispatcher). Throws on an invalid env value.
|
|
191
191
|
*/
|
|
192
192
|
export function resolveLaunchShape(opts, env = process.env) {
|
|
193
193
|
let rc = false;
|
|
194
194
|
let server = false;
|
|
195
|
-
const envRc = (env.
|
|
195
|
+
const envRc = (env.MNEMOM_AGENT_REMOTE_CONTROL ?? "").trim();
|
|
196
196
|
switch (envRc) {
|
|
197
197
|
case "":
|
|
198
198
|
case "0":
|
|
@@ -206,7 +206,7 @@ export function resolveLaunchShape(opts, env = process.env) {
|
|
|
206
206
|
server = true;
|
|
207
207
|
break;
|
|
208
208
|
default:
|
|
209
|
-
throw new Error(`
|
|
209
|
+
throw new Error(`MNEMOM_AGENT_REMOTE_CONTROL must be 0, 1, terminal or server (got '${envRc}').`);
|
|
210
210
|
}
|
|
211
211
|
if (opts.remoteControl)
|
|
212
212
|
rc = true;
|
|
@@ -222,7 +222,7 @@ export function resolveLaunchShape(opts, env = process.env) {
|
|
|
222
222
|
}
|
|
223
223
|
/**
|
|
224
224
|
* Did anyone EXPLICITLY choose a launch shape — a `--remote-control`/`--server`
|
|
225
|
-
* flag, or a non-empty `
|
|
225
|
+
* flag, or a non-empty `MNEMOM_AGENT_REMOTE_CONTROL` (which config.launch also
|
|
226
226
|
* sets)? When false, the command is free to AUTO-select the best shape: prefer
|
|
227
227
|
* Remote-Control-in-terminal when the machine can do it, else terminal-only. An
|
|
228
228
|
* explicit `terminal` choice (config `launch = "terminal"` → env "0") is
|
|
@@ -231,7 +231,7 @@ export function resolveLaunchShape(opts, env = process.env) {
|
|
|
231
231
|
export function launchPreferenceExplicit(opts, env = process.env) {
|
|
232
232
|
if (opts.remoteControl || opts.server)
|
|
233
233
|
return true;
|
|
234
|
-
return (env.
|
|
234
|
+
return (env.MNEMOM_AGENT_REMOTE_CONTROL ?? "").trim() !== "";
|
|
235
235
|
}
|
|
236
236
|
/**
|
|
237
237
|
* Build the `ANTHROPIC_CUSTOM_HEADERS` value for the terminal-only launch: the
|
package/dist/lib/api.d.ts
CHANGED
|
@@ -378,7 +378,7 @@ export declare function moveAgent(agentId: string, destOrgId: string, opts?: {
|
|
|
378
378
|
*/
|
|
379
379
|
export declare function getMyPersonalOrg(): Promise<PersonalOrgRef>;
|
|
380
380
|
/** The authenticated user's identity — `GET /v1/auth/me`. Carries the email the
|
|
381
|
-
* stored OAuth token does not, so the CLI can derive a real `
|
|
381
|
+
* stored OAuth token does not, so the CLI can derive a real `agent-<handle>`. */
|
|
382
382
|
export interface MeResponse {
|
|
383
383
|
user_id: string;
|
|
384
384
|
email?: string | null;
|
|
@@ -1204,7 +1204,7 @@ export interface OrgUsageQuery {
|
|
|
1204
1204
|
* the user "org not found" on what is most often just the flag being off.
|
|
1205
1205
|
*/
|
|
1206
1206
|
export declare function getOrgUsage(orgId: string, opts?: OrgUsageQuery): Promise<OrgUsageResponse>;
|
|
1207
|
-
/** `GET /v1/code/entitlement` 200 body — why Mnemom
|
|
1207
|
+
/** `GET /v1/code/entitlement` 200 body — why Mnemom Agent is enabled for the org. */
|
|
1208
1208
|
export interface CodeEntitlement {
|
|
1209
1209
|
org_id: string;
|
|
1210
1210
|
enabled: true;
|
|
@@ -1213,7 +1213,7 @@ export interface CodeEntitlement {
|
|
|
1213
1213
|
/** The machine-readable code on the gate's 403 when the org is not enabled. */
|
|
1214
1214
|
export declare const CODE_NOT_ENABLED = "code_not_enabled";
|
|
1215
1215
|
/**
|
|
1216
|
-
* Is Mnemom
|
|
1216
|
+
* Is Mnemom Agent enabled for `orgId` (default: the caller's primary org)?
|
|
1217
1217
|
* Resolves on 200; throws MnemomApiError with `.code === "code_not_enabled"`
|
|
1218
1218
|
* (and `.details.hint`) when the org is not enabled, or a plain MnemomApiError
|
|
1219
1219
|
* for membership/transport failures.
|
|
@@ -1229,6 +1229,6 @@ export interface AcceptProductInviteResult {
|
|
|
1229
1229
|
products: string[];
|
|
1230
1230
|
grant?: "fired" | "deferred";
|
|
1231
1231
|
}
|
|
1232
|
-
/** Redeem a `pinv_…` product invite (a Mnemom
|
|
1232
|
+
/** Redeem a `pinv_…` product invite (a Mnemom Agent invitation) for the signed-in user. */
|
|
1233
1233
|
export declare function acceptProductInvite(token: string): Promise<AcceptProductInviteResult>;
|
|
1234
1234
|
export {};
|
package/dist/lib/api.js
CHANGED
|
@@ -898,7 +898,7 @@ export async function resolveAgentId(agentName) {
|
|
|
898
898
|
const name = agentName ?? process.env.MNEMOM_AGENT;
|
|
899
899
|
if (!name) {
|
|
900
900
|
console.error("\nAgent required. Use --agent <name> or set MNEMOM_AGENT.\n");
|
|
901
|
-
console.error("List your agents with: mnemom
|
|
901
|
+
console.error("List your agents with: mnemom agent list\n");
|
|
902
902
|
process.exit(1);
|
|
903
903
|
}
|
|
904
904
|
// If it looks like an agent ID, use directly (no server call needed)
|
|
@@ -919,9 +919,9 @@ export async function resolveAgentId(agentName) {
|
|
|
919
919
|
}
|
|
920
920
|
}
|
|
921
921
|
console.error(`\nAgent not found: ${name}`);
|
|
922
|
-
console.error("List your agents with: mnemom
|
|
922
|
+
console.error("List your agents with: mnemom agent list\n");
|
|
923
923
|
console.error(`\nThis can happen when the agent was auto-created by the gateway and has not been claimed to your account yet.`);
|
|
924
|
-
console.error(`To claim it, run: mnemom
|
|
924
|
+
console.error(`To claim it, run: mnemom agent claim <agent-id> --name ${name} --key <your-provider-key>`);
|
|
925
925
|
console.error(`The <agent-id> (mnm-...) is the X-Mnemom-Agent value returned in the gateway response headers.`);
|
|
926
926
|
console.error(`See: https://docs.mnemom.ai/quickstart/gateway\n`);
|
|
927
927
|
process.exit(1);
|
|
@@ -1495,12 +1495,12 @@ export async function getOrgUsage(orgId, opts = {}) {
|
|
|
1495
1495
|
const qs = params.toString() ? `?${params.toString()}` : "";
|
|
1496
1496
|
return gFetch(`/v1/orgs/${encodeURIComponent(orgId)}/usage/by-person${qs}`, {}, { fallback: "Failed to fetch usage" });
|
|
1497
1497
|
}
|
|
1498
|
-
// ─── Mnemom
|
|
1498
|
+
// ─── Mnemom Agent — feature gate + invitation redemption ──────────────────────
|
|
1499
1499
|
//
|
|
1500
|
-
// `mnemom
|
|
1500
|
+
// `mnemom agent` is rolling out to an invited cohort. Two api calls back that:
|
|
1501
1501
|
// the per-org gate (`GET /v1/code/entitlement`) the launch preamble checks, and
|
|
1502
1502
|
// the product-invite accept (`POST /v1/invites/accept`) behind
|
|
1503
|
-
// `mnemom
|
|
1503
|
+
// `mnemom agent --invite <token>`. Both go through `codeFetch` rather than
|
|
1504
1504
|
// `gFetch`: gFetch flattens EVERY 403 into "Permission denied (need org admin /
|
|
1505
1505
|
// membership)", but the gate's 403 carries a machine-readable
|
|
1506
1506
|
// `code_not_enabled` + a hint the command layer must print verbatim, and the
|
|
@@ -1529,16 +1529,16 @@ async function codeFetch(path, init = {}, fallback) {
|
|
|
1529
1529
|
/** The machine-readable code on the gate's 403 when the org is not enabled. */
|
|
1530
1530
|
export const CODE_NOT_ENABLED = "code_not_enabled";
|
|
1531
1531
|
/**
|
|
1532
|
-
* Is Mnemom
|
|
1532
|
+
* Is Mnemom Agent enabled for `orgId` (default: the caller's primary org)?
|
|
1533
1533
|
* Resolves on 200; throws MnemomApiError with `.code === "code_not_enabled"`
|
|
1534
1534
|
* (and `.details.hint`) when the org is not enabled, or a plain MnemomApiError
|
|
1535
1535
|
* for membership/transport failures.
|
|
1536
1536
|
*/
|
|
1537
1537
|
export async function getCodeEntitlement(orgId) {
|
|
1538
1538
|
const q = orgId ? `?org_id=${encodeURIComponent(orgId)}` : "";
|
|
1539
|
-
return codeFetch(`/v1/code/entitlement${q}`, {}, "Could not check Mnemom
|
|
1539
|
+
return codeFetch(`/v1/code/entitlement${q}`, {}, "Could not check Mnemom Agent access");
|
|
1540
1540
|
}
|
|
1541
|
-
/** Redeem a `pinv_…` product invite (a Mnemom
|
|
1541
|
+
/** Redeem a `pinv_…` product invite (a Mnemom Agent invitation) for the signed-in user. */
|
|
1542
1542
|
export async function acceptProductInvite(token) {
|
|
1543
1543
|
return codeFetch("/v1/invites/accept", { method: "POST", body: JSON.stringify({ token }) }, "Could not redeem the invitation");
|
|
1544
1544
|
}
|
|
@@ -1,27 +1,27 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* lib/code-config.ts — persistent per-customer settings for `mnemom
|
|
2
|
+
* lib/code-config.ts — persistent per-customer settings for `mnemom agent`.
|
|
3
3
|
*
|
|
4
|
-
* Settings live in a human-editable TOML file at ~/.mnemom/
|
|
4
|
+
* Settings live in a human-editable TOML file at ~/.mnemom/launcher.toml (the
|
|
5
5
|
* Cargo/Codex `config.toml` convention — comments allowed, easy to hand-edit) so
|
|
6
6
|
* a customer never has to retype their flags. The SECRET Anthropic key is
|
|
7
|
-
* deliberately NOT stored here: it stays in ~/.mnemom/
|
|
7
|
+
* deliberately NOT stored here: it stays in ~/.mnemom/launcher.json at 0600 (see
|
|
8
8
|
* commands/code.ts), so the file customers open, edit, and share never carries a
|
|
9
9
|
* credential — the same split gh (config.yml/hosts.yml), aws (config/credentials)
|
|
10
10
|
* and Codex (config.toml/auth.json) use.
|
|
11
11
|
*
|
|
12
|
-
* Precedence, highest wins: command-line FLAG > ENV >
|
|
13
|
-
* `
|
|
12
|
+
* Precedence, highest wins: command-line FLAG > ENV > launcher.toml > built-in.
|
|
13
|
+
* `loadLauncherConfig` is pure parse+validate; `applyConfigToEnv` folds the
|
|
14
14
|
* env-backed settings UNDER any real env var (so env still wins and the
|
|
15
15
|
* resolvers in lib/code.ts keep the built-in default as the final fallback);
|
|
16
16
|
* the caller folds the plain-value settings under the CLI flags.
|
|
17
17
|
*/
|
|
18
|
-
import { type LaunchShape } from "./
|
|
19
|
-
/** The human-editable settings file. Secret key lives elsewhere (
|
|
20
|
-
export declare const
|
|
18
|
+
import { type LaunchShape } from "./agent.js";
|
|
19
|
+
/** The human-editable settings file. Secret key lives elsewhere (launcher.json). */
|
|
20
|
+
export declare const LAUNCHER_CONFIG_PATH: string;
|
|
21
21
|
/** Where the CLI resolves the Anthropic key from; advisory ordering/restriction. */
|
|
22
22
|
export type KeySource = "env" | "store" | "prompt";
|
|
23
23
|
/** The validated settings, camelCased for TS (TOML keys are snake_case). */
|
|
24
|
-
export interface
|
|
24
|
+
export interface LauncherConfig {
|
|
25
25
|
gateway?: string;
|
|
26
26
|
model?: string;
|
|
27
27
|
agent?: string;
|
|
@@ -36,43 +36,43 @@ export interface CodeConfig {
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
|
-
* A settable key: its dotted config name, the getter/setter into a
|
|
39
|
+
* A settable key: its dotted config name, the getter/setter into a LauncherConfig,
|
|
40
40
|
* and a one-line description for `config list`/help. Kept as data so get/set/list
|
|
41
41
|
* stay a single source of truth.
|
|
42
42
|
*/
|
|
43
43
|
export interface ConfigKeySpec {
|
|
44
44
|
key: string;
|
|
45
45
|
describe: string;
|
|
46
|
-
get(cfg:
|
|
47
|
-
set(cfg:
|
|
46
|
+
get(cfg: LauncherConfig): string | number | undefined;
|
|
47
|
+
set(cfg: LauncherConfig, raw: string): void;
|
|
48
48
|
}
|
|
49
49
|
/** The full set of settable keys — drives get/set/unset/list and validation. */
|
|
50
50
|
export declare const CONFIG_KEYS: ConfigKeySpec[];
|
|
51
51
|
export declare function configKeySpec(key: string): ConfigKeySpec | undefined;
|
|
52
52
|
/**
|
|
53
|
-
* Parse + validate a TOML settings document into a
|
|
53
|
+
* Parse + validate a TOML settings document into a LauncherConfig. Pure (no fs), so
|
|
54
54
|
* it is unit-testable. Unknown top-level keys are ignored (forward-compatible);
|
|
55
55
|
* known keys with the wrong shape throw a human-readable error.
|
|
56
56
|
*/
|
|
57
|
-
export declare function
|
|
57
|
+
export declare function parseLauncherConfig(text: string): LauncherConfig;
|
|
58
58
|
/**
|
|
59
|
-
* Load the settings from ~/.mnemom/
|
|
59
|
+
* Load the settings from ~/.mnemom/launcher.toml (or `path`). A missing file is an
|
|
60
60
|
* empty config (never an error — first run has none). A malformed or invalid
|
|
61
61
|
* file throws with the path so the customer can fix it, rather than silently
|
|
62
62
|
* launching with the wrong settings.
|
|
63
63
|
*/
|
|
64
|
-
export declare function
|
|
65
|
-
/** Serialize a
|
|
66
|
-
export declare function
|
|
67
|
-
/** Persist a
|
|
68
|
-
export declare function
|
|
64
|
+
export declare function loadLauncherConfig(path?: string): LauncherConfig;
|
|
65
|
+
/** Serialize a LauncherConfig back to TOML (snake_case keys), with a header comment. */
|
|
66
|
+
export declare function serializeLauncherConfig(cfg: LauncherConfig): string;
|
|
67
|
+
/** Persist a LauncherConfig to `path` (default launcher.toml), atomically (temp+rename), 0600. */
|
|
68
|
+
export declare function writeLauncherConfig(cfg: LauncherConfig, path?: string): void;
|
|
69
69
|
/**
|
|
70
70
|
* Fold the ENV-backed settings from config UNDER the environment: set the
|
|
71
|
-
*
|
|
71
|
+
* MNEMOM_AGENT_* var ONLY when it is not already present, so a real env var (and
|
|
72
72
|
* therefore a flag that set one) still wins. The resolvers in lib/code.ts then
|
|
73
73
|
* apply the built-in default when neither env nor config supplied a value.
|
|
74
74
|
*
|
|
75
|
-
* launch maps to
|
|
75
|
+
* launch maps to MNEMOM_AGENT_REMOTE_CONTROL using that var's existing contract
|
|
76
76
|
* (see resolveLaunchShape): terminal→"0", remote-control→"1", server→"server".
|
|
77
77
|
*/
|
|
78
|
-
export declare function applyConfigToEnv(cfg:
|
|
78
|
+
export declare function applyConfigToEnv(cfg: LauncherConfig, env?: NodeJS.ProcessEnv): void;
|