create-metamynd-agent 0.14.4 → 0.14.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.
Files changed (3) hide show
  1. package/README.md +6 -3
  2. package/index.mjs +96 -28
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -433,9 +433,12 @@ signed value only and ignores one in the context. Scaffolds pin `@metamynd/agent
433
433
 
434
434
  The starter rules include a high-risk review. A request that sends **no** `riskLevel` (or an unrecognised one)
435
435
  is no longer waved through: it is **escalated** (`CONTEXT_UNVERIFIABLE`) for a human, because an agent that omits
436
- its risk is indistinguishable from one hiding it. The scaffolded financial examples send `riskLevel` (`'low'`
437
- unless you say otherwise) — that default is a placeholder, not an assessment — and the neutral template passes
438
- your own `args` as the context, so include it there. A real integration should send an honest one — or, better, not depend on the agent at all: a mandate
436
+ its risk is indistinguishable from one hiding it. The scaffolded examples pass the tool call's own `riskLevel`
437
+ through **unchanged** — there is no default, so a call that does not say is sent for review rather than treated as
438
+ `'low'` (the demo steps each state their risk explicitly). The neutral template passes your own `args` as the
439
+ context, so include it there. Either way `riskLevel` is **the agent's own claim**: it travels in the request
440
+ context, and even when the agent's key signs that context, the signature proves who said it, not that it is true —
441
+ nothing checks the value unless your owner configures provenance for it. A real integration should send an honest one — or, better, not depend on the agent at all: a mandate
439
442
  permission can carry an owner-set `riskTier` that no claim can lower, and a gateway route can derive the risk
440
443
  itself with `route.trustedContext` (`@metamynd/agentsafe-http-gateway` 0.10.0). See MAGP §6.3.
441
444
 
package/index.mjs CHANGED
@@ -225,7 +225,8 @@ ${c.b('Options')}
225
225
  --force, -f Scaffold into a non-empty directory, overwriting existing files
226
226
  --api <url> API base (default ${DEFAULT_API})
227
227
  --email <email> Owner login email
228
- --password <pw> Owner password (prefer the interactive prompt or METAMYND_PASSWORD)
228
+ --password <pw> Owner password (prefer the interactive prompt or METAMYND_PASSWORD).
229
+ One session per account: logging in signs it out of the dashboard.
229
230
  --name <name> Agent name (e.g. "Support Bot")
230
231
  --scope <scope> Mandate action scope (e.g. flight-purchase)
231
232
  --per-txn-max <n> Per-transaction cap (default 500)
@@ -374,6 +375,16 @@ function loadConfigFile(path) {
374
375
  return json;
375
376
  }
376
377
 
378
+ // Written into every financial scaffold's README. The generated code passes the tool call's riskLevel through
379
+ // unchanged (no `?? 'low'`): a missing one must reach the gate as missing, where it escalates by design.
380
+ const RISK_LEVEL_NOTE = `## Risk level: the agent's own claim
381
+
382
+ \`riskLevel\` is **the agent's own claim**. It travels in the request's context: the agent's key may sign that context,
383
+ which proves who said it, not that it is true, and nothing checks the value unless your owner configures provenance for it (an owner-set \`riskTier\` on the mandate permission, or a
384
+ gateway route's \`trustedContext\`). \`index.mjs\` passes the tool call's own \`riskLevel\` through unchanged —
385
+ there is **no default**. A call that does not state one (or states one the gate does not recognise) is **sent
386
+ for review** (\`CONTEXT_UNVERIFIABLE\`), never treated as \`low\`. The demo steps each state their risk explicitly.`;
387
+
377
388
  // A rule needs `when.predicate` (the atom) and `then` (the decision the gate should return
378
389
  // when it fires) — everything else is optional sugar. See backend's atom-catalog.ts for the
379
390
  // full predicate list (amount-over, risk-at-or-above, jurisdiction-not-allowed, ...).
@@ -476,10 +487,27 @@ function defaultNeutralDemo() {
476
487
  return demo;
477
488
  }
478
489
 
490
+ /**
491
+ * Where an agent's rules are edited in the dashboard. SOPs belong to the legal entity, so the page is
492
+ * VeriFAI → Legal Entities (/dashboard/organization), SOPs tab; the AgentSafe sidebar group links the same
493
+ * tab as "SOPs". This said "Legal Entity → SOPs", a path no menu had (2026-10-02 eval, L-1).
494
+ */
495
+ const SOPS_PATH = 'Dashboard → VeriFAI → Legal Entities → SOPs tab (also linked as AgentSafe → SOPs)';
496
+ /** The same path for the generated demo's console output, which stays ASCII. */
497
+ const SOPS_PATH_ASCII = 'Dashboard -> VeriFAI -> Legal Entities -> SOPs';
498
+ /**
499
+ * A --sandbox scaffold runs as the SHARED sandbox agent, which no user has dashboard access to, so "change
500
+ * the rules in the dashboard" sent them somewhere they could not go (L-7). Say how to get an agent whose
501
+ * rules they CAN change instead.
502
+ */
503
+ const SANDBOX_RULES_FIXED = "This is the shared sandbox agent: its rules are fixed and nobody can edit them. To change the rules, provision your own agent — re-run without --sandbox (it signs you up and creates an agent whose SOPs you own, edited at " + SOPS_PATH + "), or use --harness for a free local agent whose rules you edit by hand.";
504
+
479
505
  /** A --config file's rules cannot reach an agent the caller does not provision themselves: say so instead of implying they apply. */
480
- function warnRulesNotApplied(fileConfig, where) {
506
+ function warnRulesNotApplied(fileConfig, where, { shared = false } = {}) {
481
507
  if (policyMolecules(fileConfig).length === 0) return;
482
- console.log(` ${c.yellow('!')} the rules in ${c.b('the config file')} are not applied to ${where} — its rules are the platform's defaults. Set your own in the dashboard (Legal Entity → SOPs), or provision your own agent (drop this flag) to author them here.`);
508
+ console.log(shared
509
+ ? ` ${c.yellow('!')} the rules in ${c.b('the config file')} are not applied to ${where} — its rules are the platform's defaults, and nobody can change them. Provision your own agent (drop this flag) to author them here.`
510
+ : ` ${c.yellow('!')} the rules in ${c.b('the config file')} are not applied to ${where} — its rules are the platform's defaults. Its owner sets them in the dashboard (${SOPS_PATH}), or provision your own agent (drop this flag) to author them here.`);
483
511
  }
484
512
 
485
513
  /**
@@ -1032,7 +1060,7 @@ function keepConfigAndFail(outDir, config, why) {
1032
1060
  * it — the same shape of gap --harness's README documents. See exampleIndex() below, which is
1033
1061
  * what the real (non-sandbox) flow scaffolds by default instead.
1034
1062
  */
1035
- function exampleIndexNoGateway(scope, perTxnMax, currency, merchant) {
1063
+ function exampleIndexNoGateway(scope, perTxnMax, currency, merchant, sandbox = false) {
1036
1064
  const under = Math.max(1, Math.round(perTxnMax * 0.5));
1037
1065
  const over = Math.round(perTxnMax + 100);
1038
1066
  return `// index.mjs — your agent, governed by MetaMynd/AgentSafe.
@@ -1061,7 +1089,10 @@ const gatedBookFlight = guard.guardTool(
1061
1089
  amount: a.amount,
1062
1090
  currency: '${currency}',
1063
1091
  merchant: a.merchant,
1064
- context: { tool: 'book-flight', riskLevel: a.riskLevel ?? 'low' },
1092
+ // riskLevel is the agent's OWN claim: signing it proves who said it, not that it is true, and nothing checks it unless
1093
+ // the owner configures provenance. Passed through as-is: when the agent does not say, it stays absent and the gate sends
1094
+ // the action for review — never 'low'.
1095
+ context: { tool: 'book-flight', riskLevel: a.riskLevel },
1065
1096
  }),
1066
1097
  );
1067
1098
 
@@ -1176,8 +1207,12 @@ console.log(bold(' Without MetaMynd, you can be bypassed.') + ' bookFlight() ru
1176
1207
  console.log(dim(' call it directly instead of gatedBookFlight and nothing above stops you.'));
1177
1208
  console.log(dim(' Re-scaffold without --sandbox/--no-gateway for the default shape, which does.'));
1178
1209
  console.log('');
1179
- console.log(' Change the cap in the dashboard (Legal Entity -> SOPs) and run again.');
1180
- console.log(dim(' The outcome changes. This file does not. That is the point.'));
1210
+ ${sandbox ? `console.log(' This is the SHARED sandbox agent: its rules are fixed and nobody can edit them.');
1211
+ console.log(dim(' To change the cap, provision your own agent: re-run create-metamynd-agent'));
1212
+ console.log(dim(' without --sandbox (it signs you up), then change the cap in your dashboard'));
1213
+ console.log(dim(' (${SOPS_PATH_ASCII}) and run again.'));
1214
+ console.log(dim(' The outcome changes. Your code does not. That is the point.'));` : `console.log(' Change the cap in the dashboard (${SOPS_PATH_ASCII}) and run again.');
1215
+ console.log(dim(' The outcome changes. This file does not. That is the point.'));`}
1181
1216
  console.log('');
1182
1217
  `;
1183
1218
  }
@@ -1222,7 +1257,8 @@ async function bookFlightViaGateway(args, decision) {
1222
1257
  amount: args.amount,
1223
1258
  currency: args.currency ?? '${currency}',
1224
1259
  merchant: args.merchant,
1225
- context: { tool: 'book-flight', riskLevel: args.riskLevel ?? 'low' },
1260
+ // Passed through as-is (never defaulted): a missing riskLevel must reach the gateway as missing.
1261
+ context: { tool: 'book-flight', riskLevel: args.riskLevel },
1226
1262
  payload,
1227
1263
  });
1228
1264
  signed.authorizationId = decision?.authorizationId;
@@ -1250,7 +1286,10 @@ const gatedBookFlight = guard.guardTool(
1250
1286
  amount: a.amount,
1251
1287
  currency: a.currency ?? '${currency}',
1252
1288
  merchant: a.merchant,
1253
- context: { tool: 'book-flight', riskLevel: a.riskLevel ?? 'low' },
1289
+ // riskLevel is the agent's OWN claim: signing it proves who said it, not that it is true, and nothing checks it unless
1290
+ // the owner configures provenance. Passed through as-is: when the agent does not say, it stays absent and the gate sends
1291
+ // the action for review — never 'low'.
1292
+ context: { tool: 'book-flight', riskLevel: a.riskLevel },
1254
1293
  // The authorization is bound to the SAME body bookFlightViaGateway() sends, so the gate records what this agent
1255
1294
  // signed and the gateway can prove it is running exactly that. Keep the two in step if you add a field.
1256
1295
  payload: { amount: a.amount, merchant: a.merchant, currency: a.currency ?? '${currency}' },
@@ -1373,7 +1412,7 @@ console.log('');
1373
1412
  console.log(bold(' With MetaMynd, you can\\'t be bypassed.') + ' ./gateway is why - it independently');
1374
1413
  console.log(dim(' re-verified step 1 before running it, and holds the tool this file never can.'));
1375
1414
  console.log('');
1376
- console.log(' Change the cap in the dashboard (Legal Entity -> SOPs) and run again.');
1415
+ console.log(' Change the cap in the dashboard (${SOPS_PATH_ASCII}) and run again.');
1377
1416
  console.log(dim(' The outcome changes. This file does not. That is the point.'));
1378
1417
  console.log('');
1379
1418
  `;
@@ -1406,7 +1445,7 @@ If a committed \`package-lock.json\` pins an older \`${GUARD_PKG}\` than this pr
1406
1445
  * with `gatewayPort` the tool lives in a separate process (./gateway, the real enforcement
1407
1446
  * boundary); without it (--no-gateway) the tool is a local function in this process.
1408
1447
  */
1409
- function exampleIndexNeutral({ scope, gatewayPort, demo, merchant }) {
1448
+ function exampleIndexNeutral({ scope, gatewayPort, demo, merchant, sandbox = false }) {
1410
1449
  const withGateway = gatewayPort != null;
1411
1450
  const steps = [
1412
1451
  ...demo.cases,
@@ -1553,8 +1592,12 @@ console.log(bold(' Without MetaMynd, you can be bypassed.') + ' performAction()
1553
1592
  console.log(dim(' call it directly instead of gatedAction and nothing above stops you.'));
1554
1593
  console.log(dim(' Re-scaffold without --no-gateway for the default shape, which closes that.'));`}
1555
1594
  console.log('');
1556
- console.log(' Change your rules in the dashboard (Legal Entity -> SOPs) and run again.');
1557
- console.log(dim(' The outcome changes. This file does not. That is the point.'));
1595
+ ${sandbox ? `console.log(' This is the SHARED sandbox agent: its rules are fixed and nobody can edit them.');
1596
+ console.log(dim(' To change them, provision your own agent: re-run create-metamynd-agent'));
1597
+ console.log(dim(' without --sandbox (it signs you up), then change its rules in your dashboard'));
1598
+ console.log(dim(' (${SOPS_PATH_ASCII}) and run again.'));
1599
+ console.log(dim(' The outcome changes. Your code does not. That is the point.'));` : `console.log(' Change your rules in the dashboard (${SOPS_PATH_ASCII}) and run again.');
1600
+ console.log(dim(' The outcome changes. This file does not. That is the point.'));`}
1558
1601
  console.log('');
1559
1602
  `;
1560
1603
  }
@@ -1733,7 +1776,15 @@ Replace \`performAction()\` in \`server.mjs\` with your implementation and put a
1733
1776
  }
1734
1777
 
1735
1778
  /** The README for a non-financial hosted scaffold. `withGateway` selects the two-process shape. */
1736
- function exampleReadmeNeutral(slug, scope, withGateway, gatewayPort, daemonKey, demo) {
1779
+ /** The generated README's "Change the rules" body: the dashboard path, or — for the shared sandbox agent — how to get an agent whose rules you can change. */
1780
+ function changeRulesSection(sandbox) {
1781
+ return sandbox
1782
+ ? `${SANDBOX_RULES_FIXED} An \`escalate\` verdict is held for an owner to approve; poll \`guard.escalationStatus(id)\`.`
1783
+ : `Edit the agent's SOPs in the dashboard (${SOPS_PATH}). The agent's behaviour changes live —
1784
+ no redeploy. An \`escalate\` verdict is held for an owner to approve; poll \`guard.escalationStatus(id)\`.`;
1785
+ }
1786
+
1787
+ function exampleReadmeNeutral(slug, scope, withGateway, gatewayPort, daemonKey, demo, sandbox = false) {
1737
1788
  const configLine = daemonKey
1738
1789
  ? `- \`agent.metamynd.json\` — your portable guard config (identity, mandate scope \`${scope}\`, issuer keys).
1739
1790
  **Holds no secret key.** Signing goes through your already-running agentsafe-signer daemon instead.`
@@ -1812,8 +1863,7 @@ ${clonedFreshSection(daemonKey)}
1812
1863
 
1813
1864
  ## Change the rules
1814
1865
 
1815
- Edit the agent's SOPs in the dashboard (Legal Entity → SOPs). The agent's behaviour changes live —
1816
- no redeploy. An \`escalate\` verdict is held for an owner to approve; poll \`guard.escalationStatus(id)\`.
1866
+ ${changeRulesSection(sandbox)}
1817
1867
 
1818
1868
  ## What this is not
1819
1869
 
@@ -1850,7 +1900,7 @@ function examplePackageJson(slug, neutral = false) {
1850
1900
  ) + '\n';
1851
1901
  }
1852
1902
 
1853
- function exampleReadme(slug, scope, withGateway, gatewayPort, daemonKey = false) {
1903
+ function exampleReadme(slug, scope, withGateway, gatewayPort, daemonKey = false, sandbox = false) {
1854
1904
  const configFileLine = daemonKey
1855
1905
  ? `- \`agent.metamynd.json\` — your portable guard config (identity, mandate scope \`${scope}\`, issuer keys).
1856
1906
  **Holds no secret key.** Signing goes through your already-running agentsafe-signer daemon
@@ -1877,6 +1927,8 @@ You should see an ALLOW (fulfilled by \`./gateway\`), a BLOCK (over the per-tran
1877
1927
  an ESCALATE (high risk). The BLOCK and ESCALATE never reach the gateway at all — this file's own
1878
1928
  \`guard.guardTool()\` refuses them first. Only the ALLOW crosses into the other process.
1879
1929
 
1930
+ ${RISK_LEVEL_NOTE}
1931
+
1880
1932
  ## Files
1881
1933
 
1882
1934
  ${configFileLine}
@@ -1898,6 +1950,8 @@ npm start
1898
1950
 
1899
1951
  You should see an ALLOW, a BLOCK (over the per-transaction cap), and an ESCALATE (high risk).
1900
1952
 
1953
+ ${RISK_LEVEL_NOTE}
1954
+
1901
1955
  ## Files
1902
1956
 
1903
1957
  ${configFileLine}
@@ -1940,8 +1994,7 @@ ${clonedFreshSection(daemonKey)}
1940
1994
 
1941
1995
  ## Change the rules
1942
1996
 
1943
- Edit the agent's SOPs in the dashboard (Legal Entity → SOPs). The agent's behaviour changes live —
1944
- no redeploy. An \`escalate\` verdict is held for an owner to approve; poll \`guard.escalationStatus(id)\`.
1997
+ ${changeRulesSection(sandbox)}
1945
1998
 
1946
1999
  Full integration guide: \`docs/integration/INTEGRATE-WITH-METAMYND.md\`.
1947
2000
  `;
@@ -2282,10 +2335,10 @@ function scaffoldProject({ outDir, config, slug, scope, perTxnMax, currency = 'U
2282
2335
  outDir,
2283
2336
  'index.mjs',
2284
2337
  neutral
2285
- ? exampleIndexNeutral({ scope, gatewayPort: withGateway ? gatewayPort : null, demo, merchant })
2338
+ ? exampleIndexNeutral({ scope, gatewayPort: withGateway ? gatewayPort : null, demo, merchant, sandbox: !!sandbox })
2286
2339
  : withGateway
2287
2340
  ? exampleIndex(scope, perTxnMax, gatewayPort, currency, paymentMerchant)
2288
- : exampleIndexNoGateway(scope, perTxnMax, currency, paymentMerchant),
2341
+ : exampleIndexNoGateway(scope, perTxnMax, currency, paymentMerchant, !!sandbox),
2289
2342
  force,
2290
2343
  );
2291
2344
  writeFileSafe(outDir, 'package.json', examplePackageJson(slug, neutral), force);
@@ -2294,8 +2347,8 @@ function scaffoldProject({ outDir, config, slug, scope, perTxnMax, currency = 'U
2294
2347
  outDir,
2295
2348
  'README.md',
2296
2349
  neutral
2297
- ? exampleReadmeNeutral(slug, scope, withGateway, gatewayPort, config.keyProvider === 'daemon', demo)
2298
- : exampleReadme(slug, scope, withGateway, gatewayPort, config.keyProvider === 'daemon'),
2350
+ ? exampleReadmeNeutral(slug, scope, withGateway, gatewayPort, config.keyProvider === 'daemon', demo, !!sandbox)
2351
+ : exampleReadme(slug, scope, withGateway, gatewayPort, config.keyProvider === 'daemon', !!sandbox),
2299
2352
  force,
2300
2353
  );
2301
2354
  // `npm test` (agentsafe-guard verify --context) needs the request inputs of a compliant request:
@@ -2366,7 +2419,9 @@ function scaffoldProject({ outDir, config, slug, scope, perTxnMax, currency = 'U
2366
2419
  console.log(c.dim(' · BLOCK (the agent asking to raise its OWN limit)\n'));
2367
2420
  }
2368
2421
  console.log(c.cyan(` npm test`) + c.dim(' → assert it CANNOT exceed its mandate. Put this in CI.\n'));
2369
- console.log(c.dim(` Change the rules any time in the dashboard (Legal Entity → SOPs) — no redeploy.\n`));
2422
+ console.log(c.dim(sandbox
2423
+ ? ` ${SANDBOX_RULES_FIXED}\n`
2424
+ : ` Change the rules any time in the dashboard (${SOPS_PATH}) — no redeploy.\n`));
2370
2425
  }
2371
2426
 
2372
2427
  /** --sandbox: no login, no KYB — fetch the shared sandbox agent config and scaffold. */
@@ -2381,7 +2436,7 @@ async function runSandbox(args) {
2381
2436
  const fileConfig = typeof args.config === 'string' ? loadConfigFile(args.config) : null;
2382
2437
  if (fileConfig) console.log(` ${c.green('✓')} loaded policy config ${c.dim(args.config)}`);
2383
2438
  const { financial } = announceFinancial(args, fileConfig);
2384
- warnRulesNotApplied(fileConfig, 'the shared sandbox agent');
2439
+ warnRulesNotApplied(fileConfig, 'the shared sandbox agent', { shared: true });
2385
2440
  if (!financial && typeof fileConfig?.scope === 'string' && fileConfig.scope !== 'perform-action') {
2386
2441
  console.log(` ${c.yellow('!')} the scope "${fileConfig.scope}" in the config file is not used: the shared sandbox agent's scope is "perform-action".`);
2387
2442
  }
@@ -3095,7 +3150,8 @@ async function callGateway(path, action, args) {
3095
3150
  // The COMPLETE body the tool receives, signed as a payload (MAGP 8.3.9): the eight signed fields cover amount and merchant
3096
3151
  // only, and this gateway refuses to run the tool on a body that is not exactly the one signed here.
3097
3152
  const payload = { amount: args.amount, merchant: args.merchant, currency: args.currency ?? '${currency}' };
3098
- const signed = await guard.buildSignedRequest({ action, amount: args.amount, currency: args.currency ?? '${currency}', merchant: args.merchant, context: { tool: '${scope}', riskLevel: args.riskLevel ?? 'low' }, payload });
3153
+ // riskLevel is passed through as-is (never defaulted): a missing one must reach the gateway as missing.
3154
+ const signed = await guard.buildSignedRequest({ action, amount: args.amount, currency: args.currency ?? '${currency}', merchant: args.merchant, context: { tool: '${scope}', riskLevel: args.riskLevel }, payload });
3099
3155
  const res = await fetch(GATEWAY + path, { method: 'POST', headers: { 'content-type': 'application/json', 'x-magp-request': JSON.stringify(signed) }, body: JSON.stringify(payload) });
3100
3156
  const body = await res.json().catch(() => null);
3101
3157
  if (!res.ok) {
@@ -3120,7 +3176,10 @@ const gatedBookFlight = guard.guardToolLocal(
3120
3176
  amount: a.amount,
3121
3177
  currency: a.currency ?? '${currency}',
3122
3178
  merchant: a.merchant,
3123
- context: { tool: 'book-flight', riskLevel: a.riskLevel ?? 'low' },
3179
+ // riskLevel is the agent's OWN claim: signing it proves who said it, not that it is true, and nothing checks it unless
3180
+ // the owner configures provenance. Passed through as-is: when the agent does not say, it stays absent and the gate sends
3181
+ // the action for review — never 'low'.
3182
+ context: { tool: 'book-flight', riskLevel: a.riskLevel },
3124
3183
  }),
3125
3184
  getBundle,
3126
3185
  );
@@ -3474,7 +3533,9 @@ action outside the mandate entirely. Every step says what it expects and flags a
3474
3533
  : `None of your rules could be staged in the demo (see below), so it shows only a BLOCK for an
3475
3534
  action outside the mandate. Your rules are still enforced; see \`metamynd-rules.json\`.`)
3476
3535
  : `You should see an ALLOW, a BLOCK (over the per-transaction cap), an ESCALATE (high risk —
3477
- open the dashboard to approve it), and a BLOCK (an action outside the mandate entirely).`}
3536
+ open the dashboard to approve it), and a BLOCK (an action outside the mandate entirely).
3537
+
3538
+ ${RISK_LEVEL_NOTE}`}
3478
3539
 
3479
3540
  ## Files
3480
3541
 
@@ -3704,9 +3765,15 @@ async function authFlow(args) {
3704
3765
  const login = await apiPost(base, '/auth/login', { username: email, password }, null);
3705
3766
  const token = login?.data?.accessToken;
3706
3767
  if (!token) fail('Login succeeded but no access token was returned.');
3768
+ console.log(c.dim(` ${SESSION_REPLACED_NOTE}`));
3707
3769
  return { base, token, email };
3708
3770
  }
3709
3771
 
3772
+ // One session per account: a CLI login replaces the account's dashboard session (the dashboard then answers
3773
+ // SESSION_REPLACED and explains). Said up front so it is not a surprise (item 14 of the 2026-10-02 open items).
3774
+ const SESSION_REPLACED_NOTE =
3775
+ 'Note: an account has one session at a time, so this login signs that account out of the MetaMynd dashboard in your browser. Sign in there again afterwards.';
3776
+
3710
3777
  const REQUEST_STATE_FILE = 'metamynd-request.json';
3711
3778
 
3712
3779
  // --request: a developer requests an agent for an owner's org (the owner approves in the dashboard).
@@ -3911,6 +3978,7 @@ async function main() {
3911
3978
  const token = login?.data?.accessToken;
3912
3979
  if (!token) { rl?.close(); fail('Login succeeded but no access token was returned.'); }
3913
3980
  console.log(` ${c.green('✓')} authenticated as ${email}`);
3981
+ console.log(c.dim(` ${SESSION_REPLACED_NOTE}`));
3914
3982
 
3915
3983
  // 2. Agent details — a --config file's fields are the default at every prompt/flag below.
3916
3984
  const name = await pick('name', null, 'Agent name', fileConfig?.name ?? 'Support Bot');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-metamynd-agent",
3
- "version": "0.14.4",
3
+ "version": "0.14.7",
4
4
  "description": "Scaffold a MetaMynd/AgentSafe-governed AI agent in one command — logs in, provisions the agent (identity + mandate + SOP + Standards) in a single call, writes agent.metamynd.json plus a runnable agent + separate tool-gateway process that closes direct-call, confused-deputy, replay, and cumulative-spend bypasses. --harness scaffolds a free, local, zero-network governance harness instead.",
5
5
  "type": "module",
6
6
  "bin": {