@mnemom/mnemom 0.14.6 → 0.15.1-next.0

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.
@@ -0,0 +1,2 @@
1
+ export declare function activityCommand(agentName?: string): Promise<void>;
2
+ export declare const integrityCommand: typeof activityCommand;
@@ -1,7 +1,7 @@
1
1
  import { resolveAgentId, getIntegrity, MnemomApiError } from "../lib/api.js";
2
2
  import { fmt } from "../lib/format.js";
3
3
  import { TRACES_PENDING_NOTE } from "../lib/onboarding.js";
4
- export async function integrityCommand(agentName) {
4
+ export async function activityCommand(agentName) {
5
5
  const agentId = await resolveAgentId(agentName);
6
6
  console.log("\nFetching agent activity...\n");
7
7
  try {
@@ -47,6 +47,9 @@ export async function integrityCommand(agentName) {
47
47
  }
48
48
  }
49
49
  }
50
+ // `mnemom integrity` is retained as a deprecated alias of `mnemom activity`
51
+ // (AAP = Activity). It still works and prints a deprecation notice; no breaking change.
52
+ export const integrityCommand = activityCommand;
50
53
  function generateScoreBar(score) {
51
54
  const filled = Math.round(score * 10);
52
55
  const empty = 10 - filled;
@@ -66,7 +66,7 @@ const FULL_PROOF_RE = /^[0-9a-f]{64}$/;
66
66
  // digest and break the claim handshake entirely, so SHA-256 is mandated by the
67
67
  // protocol — the "insufficient computational effort" alert is a false positive.
68
68
  function sha256Hex(input) {
69
- // lgtm[js/insufficient-password-hash] — protocol proof, not password storage (see note above)
69
+ // codeql[js/insufficient-password-hash] — protocol proof, not password storage; see block comment above
70
70
  return createHash("sha256").update(input, "utf8").digest("hex"); // codeql[js/insufficient-password-hash]
71
71
  }
72
72
  /**
@@ -289,8 +289,25 @@ export async function agentsClaimCommand(idOrName, options = {}) {
289
289
  }
290
290
  console.log(fmt.success(`Claimed ${result.agent_id}.`));
291
291
  console.log(fmt.label(" Landed in:", where));
292
+ if (derivationName) {
293
+ console.log(fmt.label(" Name:", derivationName));
294
+ }
292
295
  if (result.claimed_at) {
293
296
  console.log(fmt.label(" Claimed at:", new Date(result.claimed_at).toLocaleString()));
294
297
  }
298
+ // Bridge to the next step (MNE-610). The dogfood dead-end was: claim with a
299
+ // friendly --name, then `mnemom card publish --agent <name>` returns an
300
+ // opaque "agent not found" while the freshly-claimed agent propagates into
301
+ // the listing the name-resolver reads. Always surface a ready-to-paste
302
+ // command keyed on the CANONICAL agent id, which `resolveAgentId` accepts
303
+ // verbatim (no list lookup) — so the publish step never dead-ends regardless
304
+ // of listing propagation. The friendly name is shown as the eventual
305
+ // shorthand, not the recommended first move.
306
+ console.log();
307
+ console.log(fmt.dim(" Next — publish your alignment card with the canonical id:"));
308
+ console.log(fmt.dim(` mnemom card publish <file.yaml> --agent ${result.agent_id}`));
309
+ if (derivationName) {
310
+ console.log(fmt.dim(` Once it appears in \`mnemom agents\`, you can use the name instead: --agent ${derivationName}`));
311
+ }
295
312
  console.log();
296
313
  }
@@ -64,7 +64,11 @@ function formatRow(key) {
64
64
  }
65
65
  // ─── mnemom api-key list ─────────────────────────────────────────────────
66
66
  export async function apiKeyListCommand(opts) {
67
- await requireAuth();
67
+ const cred = await requireAuth();
68
+ if (cred.type === "api-key") {
69
+ console.log(fmt.warn("API keys are agent-scoped; run mnemom login to manage personal API keys"));
70
+ return;
71
+ }
68
72
  let keys;
69
73
  try {
70
74
  keys = await listApiKeys();
@@ -92,7 +96,11 @@ export async function apiKeyListCommand(opts) {
92
96
  }
93
97
  // ─── mnemom api-key create ───────────────────────────────────────────────
94
98
  export async function apiKeyCreateCommand(opts) {
95
- await requireAuth();
99
+ const cred = await requireAuth();
100
+ if (cred.type === "api-key") {
101
+ console.log(fmt.warn("API keys are agent-scoped; run mnemom login to manage personal API keys"));
102
+ return;
103
+ }
96
104
  if (!opts.name || opts.name.trim() === "") {
97
105
  console.error(fmt.error("--name is required. Example: --name 'ci-prod'"));
98
106
  process.exit(1);
@@ -133,7 +141,11 @@ export async function apiKeyCreateCommand(opts) {
133
141
  }
134
142
  // ─── mnemom api-key rotate ───────────────────────────────────────────────
135
143
  export async function apiKeyRotateCommand(keyId, opts) {
136
- await requireAuth();
144
+ const cred = await requireAuth();
145
+ if (cred.type === "api-key") {
146
+ console.log(fmt.warn("API keys are agent-scoped; run mnemom login to manage personal API keys"));
147
+ return;
148
+ }
137
149
  if (!keyId) {
138
150
  console.error(fmt.error("Usage: mnemom api-key rotate <key_id>"));
139
151
  process.exit(1);
@@ -163,7 +175,11 @@ export async function apiKeyRotateCommand(keyId, opts) {
163
175
  }
164
176
  // ─── mnemom api-key revoke ───────────────────────────────────────────────
165
177
  export async function apiKeyRevokeCommand(keyId) {
166
- await requireAuth();
178
+ const cred = await requireAuth();
179
+ if (cred.type === "api-key") {
180
+ console.log(fmt.warn("API keys are agent-scoped; run mnemom login to manage personal API keys"));
181
+ return;
182
+ }
167
183
  if (!keyId) {
168
184
  console.error(fmt.error("Usage: mnemom api-key revoke <key_id>"));
169
185
  process.exit(1);
@@ -1,38 +1,13 @@
1
- import { getAuthInfo, clearAuthTokens, loginWithBrowser, loginWithPassword } from "../lib/auth.js";
1
+ import { getAuthInfo, clearAuthTokens, loginWithBrowser, loginWithDeviceFlow, resolveAuth, } from "../lib/auth.js";
2
2
  import { fmt } from "../lib/format.js";
3
- import { askInput } from "../lib/prompt.js";
4
3
  export async function loginCommand(options = {}) {
5
4
  try {
6
- let tokens;
7
- if (options.noBrowser) {
8
- // Non-interactive hint: when stdin is piped, credentials are read as two
9
- // lines (email, then password). If either is missing we fail loudly with
10
- // a non-zero exit and never touch the stored session (MNE-269).
11
- const piped = !process.stdin.isTTY;
12
- const pipeHint = "Pipe credentials as two lines: printf 'EMAIL\\nPASSWORD\\n' | mnemom login --no-browser";
13
- const email = await askInput("Email:");
14
- if (!email) {
15
- console.log(fmt.error("Email is required."));
16
- if (piped)
17
- console.log(fmt.error(`No email received on stdin. ${pipeHint}`));
18
- process.exit(1);
19
- }
20
- const password = await askInput("Password:", true);
21
- if (!password) {
22
- console.log(fmt.error("Password is required."));
23
- if (piped)
24
- console.log(fmt.error(`No password received on stdin. ${pipeHint}`));
25
- process.exit(1);
26
- }
27
- tokens = await loginWithPassword(email, password);
28
- }
29
- else {
30
- tokens = await loginWithBrowser();
31
- }
5
+ // --no-browser → RFC 8628 device flow (headless / SSH / no local browser).
6
+ // Default → OAuth 2.1 authorization-code + PKCE with a loopback redirect.
7
+ const tokens = options.noBrowser ? await loginWithDeviceFlow() : await loginWithBrowser();
32
8
  console.log();
33
9
  console.log(fmt.success("Logged in successfully!"));
34
- console.log(fmt.label(" Email: ", ` ${tokens.email}`));
35
- console.log(fmt.label(" User ID:", ` ${tokens.userId}`));
10
+ printGrant(tokens);
36
11
  console.log();
37
12
  }
38
13
  catch (error) {
@@ -41,11 +16,37 @@ export async function loginCommand(options = {}) {
41
16
  process.exit(1);
42
17
  }
43
18
  }
19
+ /**
20
+ * Print what the issued token actually grants. OAuth access tokens are scoped
21
+ * and (deliberately) carry no user identity, so we show scope + expiry rather
22
+ * than fabricating an email/user id we don't have.
23
+ */
24
+ function printGrant(tokens) {
25
+ if (tokens.email)
26
+ console.log(fmt.label(" Email: ", ` ${tokens.email}`));
27
+ if (tokens.scope)
28
+ console.log(fmt.label(" Scope: ", ` ${tokens.scope}`));
29
+ const expiresDate = new Date(tokens.expiresAt * 1000).toISOString();
30
+ console.log(fmt.label(" Expires:", ` ${expiresDate}`));
31
+ }
44
32
  export async function logoutCommand() {
45
33
  clearAuthTokens();
46
34
  console.log(fmt.success("Logged out."));
47
35
  }
48
36
  export async function whoamiCommand() {
37
+ const cred = await resolveAuth();
38
+ if (cred.type === "none") {
39
+ console.log("\nNot logged in. Run `mnemom login` to authenticate.\n");
40
+ return;
41
+ }
42
+ if (cred.type === "api-key") {
43
+ console.log(fmt.header("Auth Status"));
44
+ console.log();
45
+ console.log(fmt.label(" Credential Type:", " API key"));
46
+ console.log(fmt.label(" Status: ", " valid (no expiry)"));
47
+ console.log();
48
+ return;
49
+ }
49
50
  const auth = getAuthInfo();
50
51
  if (!auth) {
51
52
  console.log("\nNot logged in. Run `mnemom login` to authenticate.\n");
@@ -56,8 +57,14 @@ export async function whoamiCommand() {
56
57
  const expiresDate = new Date(auth.expiresAt * 1000).toISOString();
57
58
  console.log(fmt.header("Auth Status"));
58
59
  console.log();
59
- console.log(fmt.label(" Email: ", ` ${auth.email}`));
60
- console.log(fmt.label(" User ID:", ` ${auth.userId}`));
60
+ // OAuth access tokens are opaque and carry no identity; legacy sessions may
61
+ // still have email/userId. Show whatever the stored grant actually has.
62
+ if (auth.email)
63
+ console.log(fmt.label(" Email: ", ` ${auth.email}`));
64
+ if (auth.userId)
65
+ console.log(fmt.label(" User ID:", ` ${auth.userId}`));
66
+ if (auth.scope)
67
+ console.log(fmt.label(" Scope: ", ` ${auth.scope}`));
61
68
  console.log(fmt.label(" Token: ", expired ? " expired" : ` valid until ${expiresDate}`));
62
69
  console.log();
63
70
  }
@@ -654,8 +654,23 @@ export async function cardPublishCommand(file, agentName, options = {}) {
654
654
  console.log();
655
655
  }
656
656
  catch (error) {
657
- const message = error instanceof Error ? error.message : String(error);
658
- console.log("\n" + fmt.error(`Failed to publish card: ${message}`) + "\n");
657
+ if (error instanceof MnemomApiError) {
658
+ if (error.effectiveStatus === 404) {
659
+ console.log("\n" +
660
+ fmt.error("Agent found but not writable: you can see this agent locally, but cannot publish to it in its current organization context.") +
661
+ "\n");
662
+ }
663
+ else if (error.effectiveStatus === 401) {
664
+ console.log("\n" + fmt.error(`Authentication failed: ${error.message}`) + "\n");
665
+ }
666
+ else {
667
+ console.log("\n" + fmt.error(`Failed to publish card: ${error.message}`) + "\n");
668
+ }
669
+ }
670
+ else {
671
+ const message = error instanceof Error ? error.message : String(error);
672
+ console.log("\n" + fmt.error(`Failed to publish card: ${message}`) + "\n");
673
+ }
659
674
  process.exit(1);
660
675
  }
661
676
  }
@@ -10,7 +10,11 @@ import { fmt } from "../lib/format.js";
10
10
  * machine-readable output.
11
11
  */
12
12
  export async function orgListCommand(opts) {
13
- await requireAuth();
13
+ const cred = await requireAuth();
14
+ if (cred.type === "api-key") {
15
+ console.log(fmt.warn("API keys are agent-scoped; run mnemom login for org/key management"));
16
+ return;
17
+ }
14
18
  let orgs;
15
19
  try {
16
20
  orgs = await listMyOrgs();
@@ -56,7 +60,16 @@ export async function orgListCommand(opts) {
56
60
  * exactly one membership, that one).
57
61
  */
58
62
  export async function orgShowCommand(orgIdArg, opts) {
59
- await requireAuth();
63
+ const cred = await requireAuth();
64
+ if (cred.type === "api-key") {
65
+ if (opts.personal || orgIdArg) {
66
+ console.log(fmt.warn("API keys cannot filter by organization. Run mnemom login to authenticate as a user and list org-scoped agents."));
67
+ }
68
+ else {
69
+ console.log(fmt.warn("API keys are agent-scoped; run mnemom login for org/key management"));
70
+ }
71
+ return;
72
+ }
60
73
  let target;
61
74
  try {
62
75
  if (opts.personal) {
@@ -9,7 +9,8 @@ export interface ValidationCheck {
9
9
  * Required: card_version, agent_id, mode (off|observe|nudge|enforce).
10
10
  * Optional: thresholds (warn ≤ quarantine ≤ block, all in [0,1]),
11
11
  * screen_surfaces (object of bools with the four named keys),
12
- * trusted_sources (object of typed buckets, per-bucket deny-lists).
12
+ * trusted_sources (object of typed buckets, per-bucket deny-lists),
13
+ * protected_surface (org-declared asset policy — MNE-830/833).
13
14
  */
14
15
  export declare function validateProtectionCard(card: Record<string, unknown>): ValidationCheck[];
15
16
  export declare function protectionShowCommand(agentName?: string): Promise<void>;
@@ -9,6 +9,8 @@ import { fmt } from "../lib/format.js";
9
9
  import { askYesNo, isInteractive } from "../lib/prompt.js";
10
10
  const PROTECTION_MODES = ["off", "observe", "nudge", "enforce"];
11
11
  const SURFACE_KEYS = ["incoming", "outgoing", "tool_calls", "tool_responses"];
12
+ // Mirrors mnemom-api/src/composition/validate.ts OP_SEVERITIES (MNE-833).
13
+ const OP_SEVERITIES = ["low", "medium", "high", "critical"];
12
14
  // Per ADR-037 Decision 4: deny public LLM endpoints + public DNS providers,
13
15
  // and the any-host CIDRs, at write time.
14
16
  // T8-4 (2026-05-19) extended the corpus per
@@ -133,13 +135,152 @@ function validateTrustedBucket(name, bucket, checks, perEntry) {
133
135
  });
134
136
  }
135
137
  }
138
+ // ── protected_surface helpers (MNE-833) ─────────────────────────────────────
139
+ // Mirrors mnemom-api/src/composition/validate.ts validateProtectedSurface +
140
+ // validateOpArray. Both codebases live in different repos; keep in sync.
141
+ function validateOpArray(name, value, checks, withSeverity) {
142
+ if (value === undefined)
143
+ return;
144
+ if (!Array.isArray(value)) {
145
+ checks.push({
146
+ name: `protected_surface.${name}`,
147
+ passed: false,
148
+ message: `protected_surface.${name} must be an array.`,
149
+ });
150
+ return;
151
+ }
152
+ value.forEach((entry, i) => {
153
+ if (!isObject(entry)) {
154
+ checks.push({
155
+ name: `protected_surface.${name}[${i}]`,
156
+ passed: false,
157
+ message: `each protected_surface.${name} entry must be an object.`,
158
+ });
159
+ return;
160
+ }
161
+ const op = entry;
162
+ if (typeof op.pattern !== "string" || op.pattern.length === 0) {
163
+ checks.push({
164
+ name: `protected_surface.${name}[${i}].pattern`,
165
+ passed: false,
166
+ message: `protected_surface.${name}[].pattern is required (non-empty string).`,
167
+ });
168
+ }
169
+ if (op.applies_to !== undefined) {
170
+ if (!Array.isArray(op.applies_to)) {
171
+ checks.push({
172
+ name: `protected_surface.${name}[${i}].applies_to`,
173
+ passed: false,
174
+ message: `protected_surface.${name}[].applies_to must be an array of asset-identity strings.`,
175
+ });
176
+ }
177
+ else if (!op.applies_to.every((x) => typeof x === "string")) {
178
+ checks.push({
179
+ name: `protected_surface.${name}[${i}].applies_to`,
180
+ passed: false,
181
+ message: `protected_surface.${name}[].applies_to entries must be strings.`,
182
+ });
183
+ }
184
+ }
185
+ if (withSeverity &&
186
+ op.severity !== undefined &&
187
+ !OP_SEVERITIES.includes(String(op.severity))) {
188
+ checks.push({
189
+ name: `protected_surface.${name}[${i}].severity`,
190
+ passed: false,
191
+ message: `protected_surface.${name}[].severity must be one of: ${OP_SEVERITIES.join(", ")}.`,
192
+ });
193
+ }
194
+ if (op.reason !== undefined && typeof op.reason !== "string") {
195
+ checks.push({
196
+ name: `protected_surface.${name}[${i}].reason`,
197
+ passed: false,
198
+ message: `protected_surface.${name}[].reason must be a string.`,
199
+ });
200
+ }
201
+ });
202
+ }
203
+ function validateProtectedSurface(input, checks) {
204
+ if (!isObject(input)) {
205
+ checks.push({
206
+ name: "protected_surface",
207
+ passed: false,
208
+ message: "protected_surface must be an object with assets, forbidden_operations, escalation_required arrays.",
209
+ });
210
+ return;
211
+ }
212
+ const ps = input;
213
+ // assets[] — each needs a non-empty string kind + selector (intrinsic identity).
214
+ if (ps.assets !== undefined) {
215
+ if (!Array.isArray(ps.assets)) {
216
+ checks.push({
217
+ name: "protected_surface.assets",
218
+ passed: false,
219
+ message: "protected_surface.assets must be an array.",
220
+ });
221
+ }
222
+ else {
223
+ ps.assets.forEach((entry, i) => {
224
+ if (!isObject(entry)) {
225
+ checks.push({
226
+ name: `protected_surface.assets[${i}]`,
227
+ passed: false,
228
+ message: "each protected_surface.assets entry must be an object.",
229
+ });
230
+ return;
231
+ }
232
+ const a = entry;
233
+ if (typeof a.kind !== "string" || a.kind.length === 0) {
234
+ checks.push({
235
+ name: `protected_surface.assets[${i}].kind`,
236
+ passed: false,
237
+ message: "protected_surface.assets[].kind is required (non-empty string).",
238
+ });
239
+ }
240
+ if (typeof a.selector !== "string" || a.selector.length === 0) {
241
+ checks.push({
242
+ name: `protected_surface.assets[${i}].selector`,
243
+ passed: false,
244
+ message: "protected_surface.assets[].selector is required (non-empty string).",
245
+ });
246
+ }
247
+ if (a.label !== undefined && typeof a.label !== "string") {
248
+ checks.push({
249
+ name: `protected_surface.assets[${i}].label`,
250
+ passed: false,
251
+ message: "protected_surface.assets[].label must be a string.",
252
+ });
253
+ }
254
+ if (a.reason !== undefined && typeof a.reason !== "string") {
255
+ checks.push({
256
+ name: `protected_surface.assets[${i}].reason`,
257
+ passed: false,
258
+ message: "protected_surface.assets[].reason must be a string.",
259
+ });
260
+ }
261
+ });
262
+ }
263
+ }
264
+ validateOpArray("forbidden_operations", ps.forbidden_operations, checks, /* withSeverity */ true);
265
+ validateOpArray("escalation_required", ps.escalation_required, checks, /* withSeverity */ false);
266
+ for (const key of Object.keys(ps)) {
267
+ if (!["assets", "forbidden_operations", "escalation_required"].includes(key)) {
268
+ checks.push({
269
+ name: `protected_surface.${key}`,
270
+ passed: false,
271
+ message: `protected_surface.${key} is not a recognized key (allowed: assets, forbidden_operations, escalation_required).`,
272
+ });
273
+ }
274
+ }
275
+ }
136
276
  /**
137
277
  * Validate a protection card against ADR-037 canonical form.
138
278
  *
139
279
  * Required: card_version, agent_id, mode (off|observe|nudge|enforce).
140
280
  * Optional: thresholds (warn ≤ quarantine ≤ block, all in [0,1]),
141
281
  * screen_surfaces (object of bools with the four named keys),
142
- * trusted_sources (object of typed buckets, per-bucket deny-lists).
282
+ * trusted_sources (object of typed buckets, per-bucket deny-lists),
283
+ * protected_surface (org-declared asset policy — MNE-830/833).
143
284
  */
144
285
  export function validateProtectionCard(card) {
145
286
  const checks = [];
@@ -324,6 +465,10 @@ export function validateProtectionCard(card) {
324
465
  }
325
466
  }
326
467
  }
468
+ // ── protected_surface (optional, MNE-830/833) ──
469
+ if (card.protected_surface !== undefined) {
470
+ validateProtectedSurface(card.protected_surface, checks);
471
+ }
327
472
  return checks;
328
473
  }
329
474
  // ============================================================================
@@ -438,8 +583,23 @@ export async function protectionPublishCommand(file, agentName, options = {}) {
438
583
  console.log();
439
584
  }
440
585
  catch (error) {
441
- const message = error instanceof Error ? error.message : String(error);
442
- console.log("\n" + fmt.error(`Failed to publish protection card: ${message}`) + "\n");
586
+ if (error instanceof MnemomApiError) {
587
+ if (error.effectiveStatus === 404) {
588
+ console.log("\n" +
589
+ fmt.error("Agent found but not writable: you can see this agent locally, but cannot publish to it in its current organization context.") +
590
+ "\n");
591
+ }
592
+ else if (error.effectiveStatus === 401) {
593
+ console.log("\n" + fmt.error(`Authentication failed: ${error.message}`) + "\n");
594
+ }
595
+ else {
596
+ console.log("\n" + fmt.error(`Failed to publish protection card: ${error.message}`) + "\n");
597
+ }
598
+ }
599
+ else {
600
+ const message = error instanceof Error ? error.message : String(error);
601
+ console.log("\n" + fmt.error(`Failed to publish protection card: ${message}`) + "\n");
602
+ }
443
603
  process.exit(1);
444
604
  }
445
605
  }
@@ -64,10 +64,13 @@ async function checkAuthStatus() {
64
64
  }
65
65
  const auth = getAuthInfo();
66
66
  if (auth) {
67
+ // OAuth tokens carry no identity; fall back to the granted scope (or a
68
+ // generic message) rather than printing "Logged in as undefined".
69
+ const who = auth.email ?? (auth.scope ? `scope ${auth.scope}` : "OAuth session");
67
70
  return {
68
71
  name: "Authentication",
69
72
  status: "ok",
70
- message: `Logged in as ${auth.email}`,
73
+ message: `Logged in as ${who}`,
71
74
  };
72
75
  }
73
76
  // API key auth (no email available)
@@ -0,0 +1,52 @@
1
+ /**
2
+ * `mnemom try-me <token>` — the universal, deterministic Dojo-onboarding runner
3
+ * (MNE-934, epic MNE-931).
4
+ *
5
+ * Executes the shipped v5.0 briefing manifest's flow so an arbitrary agent/human
6
+ * on a fresh machine doesn't have to improvise it: resolve → name → be born →
7
+ * hand off (human claims in the browser) → set alignment → open a one-time grant
8
+ * (human approves in the browser) → set protection → hand off to the Dojo.
9
+ *
10
+ * DEMO-SAFE BY CONSTRUCTION:
11
+ * - Additive: a NEW verb; it modifies no existing command and touches no
12
+ * backend/website. It consumes Alex's shipped endpoints READ-ONLY (resolve,
13
+ * gateway birth, public claim poll) + the canonical card-write client.
14
+ * - The two privileged human acts stay in the human's browser: the claim
15
+ * sign-in (step 4) and the one-time protection grant (step 6). The command
16
+ * only orchestrates + polls — it never forges the human's session.
17
+ *
18
+ * AUTH MODEL (see the runner report / MNE-934): the canonical card-write PUTs
19
+ * (`/v1/{alignment,protection}/agent/:id`) authorize on the human's ORG
20
+ * MEMBERSHIP (ADR-062) and accept the human's `mnemom login` JWT or
21
+ * `MNEMOM_API_KEY` — NOT the birth token. So before the card writes the runner
22
+ * ensures a CLI session (offering `mnemom login`, one-click after the claim
23
+ * sign-in). That session IS the human's own — it is the headless twin of the
24
+ * host-connector authorization in the MCP flow, not a forged credential.
25
+ */
26
+ import { type BriefingManifest } from "../lib/try-me.js";
27
+ export interface TryMeOptions {
28
+ /** Print the resolved plan and exit — no birth, claim, card writes, or sim. */
29
+ dryRun?: boolean;
30
+ /** Machine-readable output (implies non-interactive). */
31
+ json?: boolean;
32
+ /** Non-interactive: auto-pick defaults and auto-open URLs (no prompts). */
33
+ yes?: boolean;
34
+ /** Pre-choose the agent's name (skips the name prompt). */
35
+ name?: string;
36
+ /** Resume from an already-born agent (skip birth) — e.g. a manual/legacy birth. */
37
+ agent?: string;
38
+ /** Override the API base used to resolve the token (default: env). */
39
+ api?: string;
40
+ /** Commander `--no-open` sets this false → never auto-open URLs, just print. */
41
+ open?: boolean;
42
+ /** Seconds to keep polling the claim / grant before giving up (default 600). */
43
+ pollTimeout?: number;
44
+ }
45
+ /**
46
+ * Entry point for `mnemom try-me <token>`. Throws on fatal misconfiguration
47
+ * (caught by the index.ts wrapper, which prints + exits non-zero); soft failures
48
+ * are surfaced as human guidance.
49
+ */
50
+ export declare function tryMeCommand(token: string, options?: TryMeOptions): Promise<void>;
51
+ /** Render the resolved plan as human-readable text (no side effects). */
52
+ export declare function renderPlan(manifest: BriefingManifest): string;