motebit 1.11.2 → 1.12.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.
Files changed (2) hide show
  1. package/dist/index.js +1171 -524
  2. package/package.json +14 -14
package/dist/index.js CHANGED
@@ -361,17 +361,17 @@ function optimalPathTrace(graph, source, target) {
361
361
  const value = dist.get(target) ?? sr.zero;
362
362
  if (value === sr.zero && source !== target)
363
363
  return null;
364
- const path19 = [];
364
+ const path20 = [];
365
365
  let current2 = target;
366
366
  const visited = /* @__PURE__ */ new Set();
367
367
  while (current2 != null && !visited.has(current2)) {
368
368
  visited.add(current2);
369
- path19.unshift(current2);
369
+ path20.unshift(current2);
370
370
  current2 = pred.get(current2) ?? null;
371
371
  }
372
- if (path19[0] !== source)
372
+ if (path20[0] !== source)
373
373
  return null;
374
- return { value, path: path19 };
374
+ return { value, path: path20 };
375
375
  }
376
376
  var init_traversal = __esm({
377
377
  "../../packages/protocol/dist/traversal.js"() {
@@ -1690,10 +1690,14 @@ function modelVendorHint(model) {
1690
1690
  return "groq";
1691
1691
  if (m4.startsWith("claude"))
1692
1692
  return "anthropic";
1693
+ if (m4.startsWith("gpt-oss"))
1694
+ return "local";
1693
1695
  if (m4.startsWith("gpt-") || /^o[0-9]/.test(m4))
1694
1696
  return "openai";
1695
1697
  if (m4.startsWith("gemini"))
1696
1698
  return "google";
1699
+ if (m4.startsWith("deepseek-r1"))
1700
+ return "local";
1697
1701
  if (m4.startsWith("deepseek"))
1698
1702
  return "deepseek";
1699
1703
  if (m4.includes(":") || /^(llama|mistral|qwen|phi|gemma|smollm)/.test(m4))
@@ -1712,7 +1716,27 @@ function providerAcceptsModel(provider, model) {
1712
1716
  return hint === "groq" || hint === "local";
1713
1717
  return hint === provider;
1714
1718
  }
1715
- var ANTHROPIC_MODELS, OPENAI_MODELS, GOOGLE_MODELS, DEEPSEEK_MODELS, GROQ_MODELS, LOCAL_SERVER_SUGGESTED_MODELS, OLLAMA_SUGGESTED_MODELS, PROXY_MODELS, DEFAULT_ANTHROPIC_MODEL, DEFAULT_OPENAI_MODEL, DEFAULT_GOOGLE_MODEL, DEFAULT_DEEPSEEK_MODEL, DEFAULT_GROQ_MODEL, DEFAULT_OLLAMA_MODEL, DEFAULT_LOCAL_SERVER_MODEL, DEFAULT_PROXY_MODEL;
1719
+ function modelCapabilityTier(model) {
1720
+ const m4 = model.trim().toLowerCase();
1721
+ if (m4 === "")
1722
+ return "capable";
1723
+ const sizeTag = /[:\-_](\d+(?:\.\d+)?)b(?:[-_.:]|$)/.exec(m4);
1724
+ if (sizeTag != null) {
1725
+ return parseFloat(sizeTag[1]) < 7 ? "minimal" : "capable";
1726
+ }
1727
+ const base = m4.split(":")[0];
1728
+ if (MINIMAL_FAMILIES.some((f7) => base.startsWith(f7))) {
1729
+ return "minimal";
1730
+ }
1731
+ if (base.endsWith("-mini") || base.endsWith("-nano") || base.includes("flash")) {
1732
+ return "capable";
1733
+ }
1734
+ if (FRONTIER_PREFIXES.some((p5) => base.startsWith(p5))) {
1735
+ return "frontier";
1736
+ }
1737
+ return "capable";
1738
+ }
1739
+ var ANTHROPIC_MODELS, OPENAI_MODELS, GOOGLE_MODELS, DEEPSEEK_MODELS, GROQ_MODELS, LOCAL_SERVER_SUGGESTED_MODELS, OLLAMA_SUGGESTED_MODELS, PROXY_MODELS, DEFAULT_ANTHROPIC_MODEL, DEFAULT_OPENAI_MODEL, DEFAULT_GOOGLE_MODEL, DEFAULT_DEEPSEEK_MODEL, DEFAULT_GROQ_MODEL, DEFAULT_OLLAMA_MODEL, DEFAULT_LOCAL_SERVER_MODEL, DEFAULT_PROXY_MODEL, MODEL_DEFAULT_REVIEW_BY, MINIMAL_FAMILIES, FRONTIER_PREFIXES;
1716
1740
  var init_models = __esm({
1717
1741
  "../../packages/sdk/dist/models.js"() {
1718
1742
  "use strict";
@@ -1739,14 +1763,20 @@ var init_models = __esm({
1739
1763
  DEEPSEEK_MODELS = ["deepseek-chat"];
1740
1764
  GROQ_MODELS = ["llama-3.3-70b-versatile", "openai/gpt-oss-120b"];
1741
1765
  LOCAL_SERVER_SUGGESTED_MODELS = [
1742
- "llama3.2",
1743
- "llama3.1",
1744
- "llama3",
1745
- "mistral",
1746
- "codellama",
1747
- "gemma2",
1748
- "phi3",
1749
- "qwen2"
1766
+ "qwen3",
1767
+ // balanced all-rounder, tool-capable — the first-run default
1768
+ "gpt-oss",
1769
+ // OpenAI open-weights — best small tool-use class (~16GB)
1770
+ "gemma3",
1771
+ // Google open family
1772
+ "llama4",
1773
+ // Meta current family
1774
+ "phi4-mini",
1775
+ // minimal-hardware tier (entry laptops, iGPU)
1776
+ "deepseek-r1",
1777
+ // reasoning-class open weights
1778
+ "mistral-small3.2"
1779
+ // Mistral current small
1750
1780
  ];
1751
1781
  OLLAMA_SUGGESTED_MODELS = LOCAL_SERVER_SUGGESTED_MODELS;
1752
1782
  PROXY_MODELS = [
@@ -1765,9 +1795,37 @@ var init_models = __esm({
1765
1795
  DEFAULT_GOOGLE_MODEL = "gemini-2.5-flash";
1766
1796
  DEFAULT_DEEPSEEK_MODEL = "deepseek-chat";
1767
1797
  DEFAULT_GROQ_MODEL = "llama-3.3-70b-versatile";
1768
- DEFAULT_OLLAMA_MODEL = "llama3.2";
1798
+ DEFAULT_OLLAMA_MODEL = "qwen3";
1769
1799
  DEFAULT_LOCAL_SERVER_MODEL = DEFAULT_OLLAMA_MODEL;
1770
1800
  DEFAULT_PROXY_MODEL = "claude-sonnet-4-6";
1801
+ MODEL_DEFAULT_REVIEW_BY = {
1802
+ anthropic: "2026-10-31",
1803
+ openai: "2026-10-31",
1804
+ google: "2026-10-31",
1805
+ deepseek: "2026-10-31",
1806
+ groq: "2026-10-31",
1807
+ "local-server": "2026-10-31",
1808
+ proxy: "2026-10-31"
1809
+ };
1810
+ MINIMAL_FAMILIES = [
1811
+ "llama3.2",
1812
+ // 1B/3B family — the witnessed weak-model floor
1813
+ "phi4-mini",
1814
+ "phi-3",
1815
+ "phi3",
1816
+ "smollm",
1817
+ "tinyllama",
1818
+ "gpt-5.4-nano"
1819
+ ];
1820
+ FRONTIER_PREFIXES = [
1821
+ "claude-fable",
1822
+ "claude-mythos",
1823
+ "claude-opus",
1824
+ "claude-sonnet",
1825
+ "gpt-5.4",
1826
+ // bare flagship; -mini/-nano handled before this check
1827
+ "gemini-2.5-pro"
1828
+ ];
1771
1829
  }
1772
1830
  });
1773
1831
 
@@ -4403,6 +4461,7 @@ __export(dist_exports2, {
4403
4461
  MEMORY_SOURCE_MARKER_UNKNOWN: () => MEMORY_SOURCE_MARKER_UNKNOWN,
4404
4462
  MERKLE_TREE_VERSION_REGISTRY: () => MERKLE_TREE_VERSION_REGISTRY,
4405
4463
  MICRO: () => MICRO,
4464
+ MODEL_DEFAULT_REVIEW_BY: () => MODEL_DEFAULT_REVIEW_BY,
4406
4465
  MaxProductLogSemiring: () => MaxProductLogSemiring,
4407
4466
  MemoryType: () => MemoryType,
4408
4467
  MotebitType: () => MotebitType,
@@ -4515,6 +4574,7 @@ __export(dist_exports2, {
4515
4574
  maxSensitivity: () => maxSensitivity,
4516
4575
  migrateAppearanceConfig: () => migrateAppearanceConfig,
4517
4576
  migrateVoiceConfig: () => migrateVoiceConfig,
4577
+ modelCapabilityTier: () => modelCapabilityTier,
4518
4578
  modelVendorHint: () => modelVendorHint,
4519
4579
  normalizeLocalServerEndpoint: () => normalizeLocalServerEndpoint,
4520
4580
  oklchToRgb: () => oklchToRgb,
@@ -22572,7 +22632,15 @@ var init_sanitizer = __esm({
22572
22632
  /\b(?:pretend|act\s+as\s+if|roleplay)\b/i,
22573
22633
  /\bdo\s+not\s+(?:follow|obey|listen)\b/i,
22574
22634
  /\b(?:override|bypass|ignore)\s+(?:safety|policy|rules|constraints)\b/i,
22575
- /<\s*(?:system|prompt|instruction)/i,
22635
+ // Exact tag shape only (`<system>`, `< prompt >`, `<instructions/>`).
22636
+ // The old open-prefix form (`<\s*(?:system|prompt|instruction)`) fired on
22637
+ // TypeScript generics (`Array<PromptTemplate>`), JSX components, and any
22638
+ // docs page whose prose puts these words after a `<` — witnessed live
22639
+ // 2026-07-31 flagging motebit's own CLI docs (#499). An attack needs the
22640
+ // tag to CLOSE to read as chat-template framing; attribute-carrying
22641
+ // variants fall through to the directive-density and boundary layers
22642
+ // (the [EXTERNAL_DATA] wrap is the defense — detection is signal).
22643
+ /<\s*(?:system|prompt|instruction)s?\s*\/?>/i,
22576
22644
  // --- Chat template injection ---
22577
22645
  /<\|im_start\|>\s*system/i,
22578
22646
  /<\|im_end\|>/i,
@@ -25587,7 +25655,7 @@ var init_config2 = __esm({
25587
25655
  "src/config.ts"() {
25588
25656
  "use strict";
25589
25657
  init_esm_shims();
25590
- VERSION = true ? "1.11.2" : "0.0.0-dev";
25658
+ VERSION = true ? "1.12.0" : "0.0.0-dev";
25591
25659
  CONFIG_DIR = process.env["MOTEBIT_CONFIG_DIR"] ?? path2.join(os.homedir(), ".motebit");
25592
25660
  CONFIG_PATH = path2.join(CONFIG_DIR, "config.json");
25593
25661
  RELAY_DIR = path2.join(CONFIG_DIR, "relay");
@@ -26457,13 +26525,13 @@ var init_intelligence = __esm({
26457
26525
  });
26458
26526
 
26459
26527
  // ../../packages/runtime/dist/commands/types.js
26460
- async function relayFetch(relay, path19, options) {
26528
+ async function relayFetch(relay, path20, options) {
26461
26529
  const headers = {
26462
26530
  "Content-Type": "application/json",
26463
26531
  Authorization: `Bearer ${relay.authToken}`,
26464
26532
  ...options?.headers
26465
26533
  };
26466
- const res = await fetch(`${relay.relayUrl}${path19}`, { ...options, headers });
26534
+ const res = await fetch(`${relay.relayUrl}${path20}`, { ...options, headers });
26467
26535
  if (!res.ok) {
26468
26536
  const text = await res.text().catch(() => "");
26469
26537
  throw new Error(`${res.status}: ${text}`);
@@ -29923,8 +29991,8 @@ function urlAuditDetail(url) {
29923
29991
  }
29924
29992
  try {
29925
29993
  const parsed = new URL(url);
29926
- const path19 = parsed.pathname;
29927
- const hasPath = path19.length > 0 && path19 !== "/";
29994
+ const path20 = parsed.pathname;
29995
+ const hasPath = path20.length > 0 && path20 !== "/";
29928
29996
  return {
29929
29997
  // Drop the trailing colon ("https:" → "https"). Lowercased
29930
29998
  // for canonical-form audit comparisons across replays.
@@ -30660,7 +30728,7 @@ var init_cloud_browser_dispatcher = __esm({
30660
30728
  };
30661
30729
  }
30662
30730
  // ── Internal: signed HTTP roundtrip ────────────────────────────────
30663
- async request(method, path19, body) {
30731
+ async request(method, path20, body) {
30664
30732
  let token;
30665
30733
  try {
30666
30734
  token = await this.getAuthToken();
@@ -30675,7 +30743,7 @@ var init_cloud_browser_dispatcher = __esm({
30675
30743
  headers["Content-Type"] = "application/json";
30676
30744
  let response;
30677
30745
  try {
30678
- response = await this.fetchImpl(`${this.baseUrl}${path19}`, {
30746
+ response = await this.fetchImpl(`${this.baseUrl}${path20}`, {
30679
30747
  method,
30680
30748
  headers,
30681
30749
  body: body === void 0 ? void 0 : JSON.stringify(body)
@@ -41660,8 +41728,8 @@ var init_three_core = __esm({
41660
41728
  * @param {string} path - The base path.
41661
41729
  * @return {Loader} A reference to this instance.
41662
41730
  */
41663
- setPath(path19) {
41664
- this.path = path19;
41731
+ setPath(path20) {
41732
+ this.path = path20;
41665
41733
  return this;
41666
41734
  }
41667
41735
  /**
@@ -41709,10 +41777,10 @@ var init_three_core = __esm({
41709
41777
  );
41710
41778
  _supportedObjectNames = ["material", "materials", "bones", "map"];
41711
41779
  Composite = class {
41712
- constructor(targetGroup, path19, optionalParsedPath) {
41713
- const parsedPath = optionalParsedPath || PropertyBinding.parseTrackName(path19);
41780
+ constructor(targetGroup, path20, optionalParsedPath) {
41781
+ const parsedPath = optionalParsedPath || PropertyBinding.parseTrackName(path20);
41714
41782
  this._targetGroup = targetGroup;
41715
- this._bindings = targetGroup.subscribe_(path19, parsedPath);
41783
+ this._bindings = targetGroup.subscribe_(path20, parsedPath);
41716
41784
  }
41717
41785
  getValue(array, offset) {
41718
41786
  this.bind();
@@ -41746,9 +41814,9 @@ var init_three_core = __esm({
41746
41814
  * @param {string} path - The path.
41747
41815
  * @param {?Object} [parsedPath] - The parsed path.
41748
41816
  */
41749
- constructor(rootNode, path19, parsedPath) {
41750
- this.path = path19;
41751
- this.parsedPath = parsedPath || _PropertyBinding.parseTrackName(path19);
41817
+ constructor(rootNode, path20, parsedPath) {
41818
+ this.path = path20;
41819
+ this.parsedPath = parsedPath || _PropertyBinding.parseTrackName(path20);
41752
41820
  this.node = _PropertyBinding.findNode(rootNode, this.parsedPath.nodeName);
41753
41821
  this.rootNode = rootNode;
41754
41822
  this.getValue = this._getValue_unbound;
@@ -41763,11 +41831,11 @@ var init_three_core = __esm({
41763
41831
  * @param {?Object} [parsedPath] - The parsed path.
41764
41832
  * @return {PropertyBinding|Composite} The created property binding or composite.
41765
41833
  */
41766
- static create(root, path19, parsedPath) {
41834
+ static create(root, path20, parsedPath) {
41767
41835
  if (!(root && root.isAnimationObjectGroup)) {
41768
- return new _PropertyBinding(root, path19, parsedPath);
41836
+ return new _PropertyBinding(root, path20, parsedPath);
41769
41837
  } else {
41770
- return new _PropertyBinding.Composite(root, path19, parsedPath);
41838
+ return new _PropertyBinding.Composite(root, path20, parsedPath);
41771
41839
  }
41772
41840
  }
41773
41841
  /**
@@ -59694,6 +59762,8 @@ var init_motebit_runtime = __esm({
59694
59762
  /** Allowed proactive capability names. Empty by default — fail-closed
59695
59763
  * sovereign default. User opts in explicitly via runtime config. */
59696
59764
  _proactiveCapabilities;
59765
+ /** #501 — config override: offer R4_MONEY tools to minimal-tier models. */
59766
+ _offerMoneyToolsToMinimalModels;
59697
59767
  /** Auto-anchor policy; null when disabled. Stored by reference so the
59698
59768
  * submitter can be rotated by the surface without re-constructing the
59699
59769
  * runtime. */
@@ -59875,8 +59945,11 @@ var init_motebit_runtime = __esm({
59875
59945
  });
59876
59946
  this._proactiveCapabilities = new Set(config.proactiveCapabilities ?? []);
59877
59947
  this._proactiveAnchor = config.proactiveAnchor ?? null;
59948
+ this._offerMoneyToolsToMinimalModels = config.offerMoneyToolsToMinimalModels ?? false;
59878
59949
  this.scopedToolRegistry = new ScopedToolRegistry(this.toolRegistry, {
59879
59950
  allows: (toolName) => {
59951
+ if (!this.tierAllowsTool(toolName))
59952
+ return false;
59880
59953
  const presence = this.presence.get();
59881
59954
  if (presence.mode === "responsive" || presence.mode === "idle")
59882
59955
  return true;
@@ -60285,6 +60358,39 @@ var init_motebit_runtime = __esm({
60285
60358
  get currentModel() {
60286
60359
  return this.provider?.model ?? null;
60287
60360
  }
60361
+ /**
60362
+ * Capability-tiered tool admission (#501): may the CURRENT model be
60363
+ * offered `toolName`? True unless the model is `minimal`-tier AND the
60364
+ * tool classifies at `R4_MONEY` AND the config override is off. Keys on
60365
+ * the SAME `classifyTool` vocabulary the approval gate uses, so any
60366
+ * future money tool inherits the policy at birth — and a rail-less
60367
+ * `delegate_to_agent` (R2 without a payment builder) stays offered:
60368
+ * the tool crosses the withholding line exactly when it can move money.
60369
+ */
60370
+ tierAllowsTool(toolName) {
60371
+ if (this._offerMoneyToolsToMinimalModels)
60372
+ return true;
60373
+ const model = this.provider?.model ?? null;
60374
+ if (model == null || modelCapabilityTier(model) !== "minimal")
60375
+ return true;
60376
+ const def = this.toolRegistry.list().find((t3) => t3.name === toolName);
60377
+ if (def == null)
60378
+ return true;
60379
+ return classifyTool(def).risk < RiskLevel.R4_MONEY;
60380
+ }
60381
+ /**
60382
+ * Surface-honesty readout (#501): true when the current model's tier is
60383
+ * withholding at least one registered money tool. Surfaces render ONE
60384
+ * calm line from this (launch / model switch) — never a toast.
60385
+ */
60386
+ get moneyToolsWithheld() {
60387
+ if (this._offerMoneyToolsToMinimalModels)
60388
+ return false;
60389
+ const model = this.provider?.model ?? null;
60390
+ if (model == null || modelCapabilityTier(model) !== "minimal")
60391
+ return false;
60392
+ return this.toolRegistry.list().some((t3) => classifyTool(t3).risk >= RiskLevel.R4_MONEY);
60393
+ }
60288
60394
  setModel(model) {
60289
60395
  if (!this.provider)
60290
60396
  throw new Error("No AI provider configured");
@@ -73914,14 +74020,14 @@ var init_dependency_container = __esm({
73914
74020
  provider = providerOrConstructor;
73915
74021
  }
73916
74022
  if (isTokenProvider(provider)) {
73917
- var path19 = [token];
74023
+ var path20 = [token];
73918
74024
  var tokenProvider = provider;
73919
74025
  while (tokenProvider != null) {
73920
74026
  var currentToken = tokenProvider.useToken;
73921
- if (path19.includes(currentToken)) {
73922
- throw new Error("Token registration cycle detected! " + __spread(path19, [currentToken]).join(" -> "));
74027
+ if (path20.includes(currentToken)) {
74028
+ throw new Error("Token registration cycle detected! " + __spread(path20, [currentToken]).join(" -> "));
73923
74029
  }
73924
- path19.push(currentToken);
74030
+ path20.push(currentToken);
73925
74031
  var registration = this._registry.get(currentToken);
73926
74032
  if (registration && isTokenProvider(registration.provider)) {
73927
74033
  tokenProvider = registration.provider;
@@ -83998,8 +84104,8 @@ ${FRONTMATTER_DELIM}`);
83998
84104
  const validation = SkillManifestSchema.safeParse(frontmatter);
83999
84105
  if (!validation.success) {
84000
84106
  const first = validation.error.issues[0];
84001
- const path19 = first?.path.join(".") ?? "(root)";
84002
- throw new SkillParseError(`Frontmatter failed schema validation at \`${path19}\`: ${first?.message ?? "unknown"}`);
84107
+ const path20 = first?.path.join(".") ?? "(root)";
84108
+ throw new SkillParseError(`Frontmatter failed schema validation at \`${path20}\`: ${first?.message ?? "unknown"}`);
84003
84109
  }
84004
84110
  return {
84005
84111
  manifest: validation.data,
@@ -84379,16 +84485,16 @@ var init_dist32 = __esm({
84379
84485
  // ../../packages/skills/dist/fs-adapter.js
84380
84486
  import { closeSync, fsyncSync, mkdirSync as mkdirSync2, openSync, readdirSync, readFileSync as readFileSync3, renameSync, rmSync, statSync, writeFileSync as writeFileSync3 } from "fs";
84381
84487
  import { dirname, join as join2, relative, sep } from "path";
84382
- function existsFile(path19) {
84488
+ function existsFile(path20) {
84383
84489
  try {
84384
- statSync(path19);
84490
+ statSync(path20);
84385
84491
  return true;
84386
84492
  } catch {
84387
84493
  return false;
84388
84494
  }
84389
84495
  }
84390
- function atomicWriteFile(path19, content) {
84391
- const tempPath = `${path19}.tmp.${process.pid}`;
84496
+ function atomicWriteFile(path20, content) {
84497
+ const tempPath = `${path20}.tmp.${process.pid}`;
84392
84498
  const fd = openSync(tempPath, "w");
84393
84499
  try {
84394
84500
  writeFileSync3(fd, content);
@@ -84396,7 +84502,7 @@ function atomicWriteFile(path19, content) {
84396
84502
  } finally {
84397
84503
  closeSync(fd);
84398
84504
  }
84399
- renameSync(tempPath, path19);
84505
+ renameSync(tempPath, path20);
84400
84506
  }
84401
84507
  function collectAuxFiles(dir) {
84402
84508
  const out = {};
@@ -84432,9 +84538,9 @@ function ensureSafeRelativePath(relPath) {
84432
84538
  }
84433
84539
  return segments.join("/");
84434
84540
  }
84435
- function resolveDirectorySkillSource(path19) {
84436
- const skillMdPath = join2(path19, SKILL_MD);
84437
- const envPath = join2(path19, SKILL_ENVELOPE_JSON);
84541
+ function resolveDirectorySkillSource(path20) {
84542
+ const skillMdPath = join2(path20, SKILL_MD);
84543
+ const envPath = join2(path20, SKILL_ENVELOPE_JSON);
84438
84544
  if (!existsFile(skillMdPath)) {
84439
84545
  throw new SkillParseError(`No SKILL.md at ${skillMdPath}`);
84440
84546
  }
@@ -84443,7 +84549,7 @@ function resolveDirectorySkillSource(path19) {
84443
84549
  }
84444
84550
  const parsed = parseSkillFile(readFileSync3(skillMdPath, "utf-8"));
84445
84551
  const envelope = JSON.parse(readFileSync3(envPath, "utf-8"));
84446
- const files = collectAuxFiles(path19);
84552
+ const files = collectAuxFiles(path20);
84447
84553
  return {
84448
84554
  kind: "in_memory",
84449
84555
  manifest: parsed.manifest,
@@ -84567,10 +84673,10 @@ var init_fs_adapter = __esm({
84567
84673
  return join2(this.root, name);
84568
84674
  }
84569
84675
  readIndex() {
84570
- const path19 = join2(this.root, INSTALLED_JSON);
84571
- if (!existsFile(path19))
84676
+ const path20 = join2(this.root, INSTALLED_JSON);
84677
+ if (!existsFile(path20))
84572
84678
  return [];
84573
- const raw = readFileSync3(path19, "utf-8");
84679
+ const raw = readFileSync3(path20, "utf-8");
84574
84680
  if (raw.trim() === "")
84575
84681
  return [];
84576
84682
  try {
@@ -84579,7 +84685,7 @@ var init_fs_adapter = __esm({
84579
84685
  return [];
84580
84686
  return parsed;
84581
84687
  } catch (err2) {
84582
- throw new Error(`Failed to parse skills index at ${path19}: ${err2 instanceof Error ? err2.message : String(err2)}`, { cause: err2 instanceof Error ? err2 : void 0 });
84688
+ throw new Error(`Failed to parse skills index at ${path20}: ${err2 instanceof Error ? err2.message : String(err2)}`, { cause: err2 instanceof Error ? err2 : void 0 });
84583
84689
  }
84584
84690
  }
84585
84691
  writeIndex(index) {
@@ -86332,7 +86438,6 @@ function createTerminalRenderer(io) {
86332
86438
  if (result === "submit") {
86333
86439
  submit();
86334
86440
  } else if (result === "exit") {
86335
- io.write("\n");
86336
86441
  destroyTerminal();
86337
86442
  process.exit(0);
86338
86443
  } else {
@@ -86368,6 +86473,22 @@ function createTerminalRenderer(io) {
86368
86473
  reject();
86369
86474
  }
86370
86475
  }
86476
+ function finalize2() {
86477
+ let scrollback = "";
86478
+ if (tail2 !== "") {
86479
+ scrollback += tail2 + "\n";
86480
+ tail2 = "";
86481
+ }
86482
+ if (inputActive) {
86483
+ scrollback += buildInputRow().row + "\n";
86484
+ inputResolver = null;
86485
+ inputRejecter = null;
86486
+ inputActive = false;
86487
+ }
86488
+ statusRow = null;
86489
+ modeRow = null;
86490
+ commit(scrollback);
86491
+ }
86371
86492
  return {
86372
86493
  writeOutput: writeOutput2,
86373
86494
  writeLine: writeLine2,
@@ -86377,7 +86498,8 @@ function createTerminalRenderer(io) {
86377
86498
  setModeRow: setModeRow2,
86378
86499
  handleEvent,
86379
86500
  repaint: () => commit(""),
86380
- detach
86501
+ detach,
86502
+ finalize: finalize2
86381
86503
  };
86382
86504
  }
86383
86505
  function applyEvent(state, event) {
@@ -86593,6 +86715,7 @@ function initTerminal() {
86593
86715
  function destroyTerminal() {
86594
86716
  if (!initialized) return;
86595
86717
  initialized = false;
86718
+ renderer.finalize();
86596
86719
  process.stdin.removeListener("data", onStdinData);
86597
86720
  process.stdout.removeListener("resize", onResize);
86598
86721
  if (process.stdin.isTTY) {
@@ -87160,6 +87283,10 @@ async function createRuntime(config, motebitId, toolRegistry, mcpServers, person
87160
87283
  // (enableInteractiveDelegation). Absent ⇒ delegation degrades to
87161
87284
  // relay-mode honestly.
87162
87285
  ...solanaWallet ? { solanaWallet } : {},
87286
+ // #501 — sovereign override for capability-tiered tool admission.
87287
+ // Default (absent/false): a minimal-tier model is never offered
87288
+ // R4_MONEY tools; the owner can restore full exposure in config.
87289
+ ...loadFullConfig().offer_money_tools_to_minimal_models === true ? { offerMoneyToolsToMinimalModels: true } : {},
87163
87290
  policy: {
87164
87291
  operatorMode: config.operator,
87165
87292
  pathAllowList: config.allowedPaths,
@@ -94028,8 +94155,8 @@ var init_x402_facilitator = __esm({
94028
94155
 
94029
94156
  // ../../services/relay/dist/tasks.js
94030
94157
  import { HTTPException as HTTPException7 } from "hono/http-exception";
94031
- function extractMotebitIdFromPath(path19) {
94032
- const match = path19.match(/\/agent\/([^/]+)\/task/);
94158
+ function extractMotebitIdFromPath(path20) {
94159
+ const match = path20.match(/\/agent\/([^/]+)\/task/);
94033
94160
  return match ? match[1] : null;
94034
94161
  }
94035
94162
  function getListingUnitCost(moteDb, agentId, capability) {
@@ -95916,9 +96043,9 @@ function enrichWithBondStatus(agents, db, nowMs = Date.now()) {
95916
96043
  function registerAgentAuthMiddleware(deps) {
95917
96044
  const { app, apiToken, identityManager, parseTokenPayloadUnsafe: parseTokenPayloadUnsafe2, verifySignedTokenForDevice: verifySignedTokenForDevice2, isTokenBlacklisted, isAgentRevoked } = deps;
95918
96045
  app.use("/api/v1/agents/*", async (c5, next) => {
95919
- const path19 = c5.req.path;
96046
+ const path20 = c5.req.path;
95920
96047
  const method = c5.req.method;
95921
- if (PUBLIC_AGENT_ROUTES.some((r2) => r2.match(path19, method))) {
96048
+ if (PUBLIC_AGENT_ROUTES.some((r2) => r2.match(path20, method))) {
95922
96049
  await next();
95923
96050
  return;
95924
96051
  }
@@ -95936,25 +96063,25 @@ function registerAgentAuthMiddleware(deps) {
95936
96063
  throw new HTTPException8(401, { message: "Invalid token" });
95937
96064
  }
95938
96065
  let agentAudience;
95939
- if (path19.includes("/p2p-eligibility")) {
96066
+ if (path20.includes("/p2p-eligibility")) {
95940
96067
  agentAudience = "market:listing";
95941
- } else if (path19.includes("/listing")) {
96068
+ } else if (path20.includes("/listing")) {
95942
96069
  agentAudience = "market:listing";
95943
- } else if (path19.includes("/credentials")) {
96070
+ } else if (path20.includes("/credentials")) {
95944
96071
  agentAudience = "credentials";
95945
- } else if (path19.includes("/presentation")) {
96072
+ } else if (path20.includes("/presentation")) {
95946
96073
  agentAudience = "credentials:present";
95947
- } else if (path19.includes("/proxy-token")) {
96074
+ } else if (path20.includes("/proxy-token")) {
95948
96075
  agentAudience = "proxy:token";
95949
- } else if (path19.includes("/receipts")) {
96076
+ } else if (path20.includes("/receipts")) {
95950
96077
  agentAudience = "receipts:read";
95951
- } else if (path19.endsWith("/balance") || path19.endsWith("/settlements")) {
96078
+ } else if (path20.endsWith("/balance") || path20.endsWith("/settlements")) {
95952
96079
  agentAudience = "account:balance";
95953
- } else if (path19.endsWith("/withdrawals")) {
96080
+ } else if (path20.endsWith("/withdrawals")) {
95954
96081
  agentAudience = "account:withdrawals";
95955
- } else if (path19.endsWith("/withdraw")) {
96082
+ } else if (path20.endsWith("/withdraw")) {
95956
96083
  agentAudience = "account:withdraw";
95957
- } else if (path19.endsWith("/checkout")) {
96084
+ } else if (path20.endsWith("/checkout")) {
95958
96085
  agentAudience = "account:checkout";
95959
96086
  } else {
95960
96087
  agentAudience = "admin:query";
@@ -95974,7 +96101,7 @@ function registerAgentAuthMiddleware(deps) {
95974
96101
  reason,
95975
96102
  expectedAudience: agentAudience,
95976
96103
  mid: claims.mid,
95977
- path: path19
96104
+ path: path20
95978
96105
  })
95979
96106
  );
95980
96107
  if (!valid) {
@@ -101753,7 +101880,7 @@ function admitModelForProvider(provider, model) {
101753
101880
  const flag = VENDOR_PROVIDER_FLAG[hint];
101754
101881
  return {
101755
101882
  admissible: false,
101756
- teach: `${model} is a hosted ${hint} model \u2014 a local server can't serve it. ` + (flag != null ? `Restart with --provider ${flag}, or pick a local model (e.g. /model llama3.2).` : `Pick a local model instead (e.g. /model llama3.2).`)
101883
+ teach: `${model} is a hosted ${hint} model \u2014 a local server can't serve it. ` + (flag != null ? `Restart with --provider ${flag}, or pick a local model (e.g. /model ${DEFAULT_LOCAL_SERVER_MODEL}).` : `Pick a local model instead (e.g. /model ${DEFAULT_LOCAL_SERVER_MODEL}).`)
101757
101884
  };
101758
101885
  }
101759
101886
  if (!providerAcceptsModel(provider, model)) {
@@ -101765,6 +101892,7 @@ function admitModelForProvider(provider, model) {
101765
101892
  }
101766
101893
  return { admissible: true };
101767
101894
  }
101895
+ var MONEY_TOOLS_WITHHELD_NOTICE = "money tools withheld from this model (minimal tier) \u2014 set offer_money_tools_to_minimal_models in ~/.motebit/config.json if you mean it";
101768
101896
 
101769
101897
  // src/index.ts
101770
101898
  init_dist8();
@@ -101804,10 +101932,10 @@ function generateUUIDv72() {
101804
101932
  return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
101805
101933
  }
101806
101934
  function loadStoredGrant(grantId) {
101807
- const path19 = join7(grantsDir(), `${grantId}.json`);
101808
- if (!existsSync(path19)) return null;
101935
+ const path20 = join7(grantsDir(), `${grantId}.json`);
101936
+ if (!existsSync(path20)) return null;
101809
101937
  try {
101810
- return JSON.parse(readFileSync4(path19, "utf8"));
101938
+ return JSON.parse(readFileSync4(path20, "utf8"));
101811
101939
  } catch {
101812
101940
  return null;
101813
101941
  }
@@ -102254,6 +102382,7 @@ function renderPreflight(pf, dim2) {
102254
102382
 
102255
102383
  // src/args.ts
102256
102384
  init_esm_shims();
102385
+ init_dist2();
102257
102386
  init_config2();
102258
102387
  init_colors();
102259
102388
  import { parseArgs } from "util";
@@ -102352,11 +102481,12 @@ function parseCliArgs(args = process.argv.slice(2)) {
102352
102481
  );
102353
102482
  }
102354
102483
  const cliProvider = rawProvider;
102355
- const defaultModel = cliProvider === "local-server" ? "llama3.2" : cliProvider === "openai" ? "gpt-5.4-mini" : cliProvider === "google" ? "gemini-2.5-flash" : cliProvider === "groq" ? "llama-3.3-70b-versatile" : cliProvider === "deepseek" ? "deepseek-chat" : "claude-sonnet-4-6";
102484
+ const defaultModel = defaultModelForProvider(cliProvider);
102356
102485
  const allowedPaths = values["allowed-paths"] != null && values["allowed-paths"] !== "" ? values["allowed-paths"].split(",").map((p5) => p5.trim()) : [process.cwd()];
102357
102486
  return {
102358
102487
  provider: cliProvider,
102359
102488
  model: values.model ?? defaultModel,
102489
+ modelExplicit: values.model != null,
102360
102490
  dbPath: values["db-path"],
102361
102491
  noStream: values["no-stream"],
102362
102492
  syncUrl: values["sync-url"],
@@ -102479,7 +102609,10 @@ var COMMANDS = [
102479
102609
  { usage: "/proposal <id> [accept|reject|counter]", desc: "Respond to a proposal" },
102480
102610
  { usage: "/operator", desc: "Show operator mode status" },
102481
102611
  { usage: "/invoke <cap> <prompt>", desc: "Invoke a capability deterministically (no AI loop)" },
102482
- { usage: "/receipt <task-id>", desc: "Re-render an archived receipt (offline-verified)" },
102612
+ {
102613
+ usage: "/receipt [task-id-prefix]",
102614
+ desc: "Re-render an archived receipt (offline-verified); no arg = latest"
102615
+ },
102483
102616
  { usage: "/voice [on|off]", desc: "Toggle TTS voice output (opt-in, off by default)" },
102484
102617
  { usage: "/say <text>", desc: "Speak text via TTS (requires voice provider)" },
102485
102618
  { usage: "/skills", desc: "List installed skills with provenance badges" },
@@ -102660,6 +102793,9 @@ Slash commands (in REPL):`
102660
102793
  function printVersion() {
102661
102794
  console.log(VERSION);
102662
102795
  }
102796
+ function defaultModelForProvider(provider) {
102797
+ return provider === "local-server" ? DEFAULT_LOCAL_SERVER_MODEL : provider === "openai" ? DEFAULT_OPENAI_MODEL : provider === "google" ? DEFAULT_GOOGLE_MODEL : provider === "groq" ? DEFAULT_GROQ_MODEL : provider === "deepseek" ? DEFAULT_DEEPSEEK_MODEL : DEFAULT_ANTHROPIC_MODEL;
102798
+ }
102663
102799
  function printBanner(opts) {
102664
102800
  const W2 = 56;
102665
102801
  const pad = (s3, visibleLen) => s3 + " ".repeat(Math.max(0, W2 - visibleLen));
@@ -102706,6 +102842,80 @@ function trimHistory(history) {
102706
102842
 
102707
102843
  // src/index.ts
102708
102844
  init_config2();
102845
+
102846
+ // src/update-nudge.ts
102847
+ init_esm_shims();
102848
+ init_config2();
102849
+ import * as fs7 from "fs";
102850
+ import * as path9 from "path";
102851
+ var UPDATE_CHECK_TTL_MS = 24 * 60 * 60 * 1e3;
102852
+ var FETCH_TIMEOUT_MS = 3e3;
102853
+ function updateCheckPath() {
102854
+ return path9.join(CONFIG_DIR, "update-check.json");
102855
+ }
102856
+ function isNewerVersion(latest, current2) {
102857
+ const parse3 = (v3) => {
102858
+ const parts = v3.trim().split(".");
102859
+ if (parts.length !== 3) return null;
102860
+ const nums = parts.map((p5) => /^\d+$/.test(p5) ? Number(p5) : NaN);
102861
+ return nums.some((n2) => Number.isNaN(n2)) ? null : nums;
102862
+ };
102863
+ const l6 = parse3(latest);
102864
+ const c5 = parse3(current2);
102865
+ if (l6 == null || c5 == null) return false;
102866
+ for (let i = 0; i < 3; i++) {
102867
+ if (l6[i] > c5[i]) return true;
102868
+ if (l6[i] < c5[i]) return false;
102869
+ }
102870
+ return false;
102871
+ }
102872
+ function readUpdateState(statePath = updateCheckPath()) {
102873
+ try {
102874
+ const raw = JSON.parse(fs7.readFileSync(statePath, "utf-8"));
102875
+ if (typeof raw.last_checked_at !== "number") return null;
102876
+ return {
102877
+ last_checked_at: raw.last_checked_at,
102878
+ ...typeof raw.latest === "string" ? { latest: raw.latest } : {}
102879
+ };
102880
+ } catch {
102881
+ return null;
102882
+ }
102883
+ }
102884
+ function renderUpdateNudge(params) {
102885
+ const latest = params.state?.latest;
102886
+ if (latest == null || !isNewerVersion(latest, params.currentVersion)) return null;
102887
+ return `motebit ${latest} available \u2014 npm i -g motebit`;
102888
+ }
102889
+ function refreshUpdateCheckInBackground(params) {
102890
+ const statePath = params?.statePath ?? updateCheckPath();
102891
+ const now = params?.nowMs ?? Date.now();
102892
+ const ttl = params?.ttlMs ?? UPDATE_CHECK_TTL_MS;
102893
+ const fetchFn = params?.fetchFn ?? fetch;
102894
+ const state = readUpdateState(statePath);
102895
+ if (state != null && now - state.last_checked_at < ttl) return;
102896
+ void (async () => {
102897
+ const controller = new AbortController();
102898
+ const timer = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
102899
+ try {
102900
+ const resp = await fetchFn("https://registry.npmjs.org/motebit/latest", {
102901
+ signal: controller.signal
102902
+ });
102903
+ if (!resp.ok) return;
102904
+ const body = await resp.json();
102905
+ if (typeof body.version !== "string") return;
102906
+ fs7.mkdirSync(path9.dirname(statePath), { recursive: true });
102907
+ fs7.writeFileSync(
102908
+ statePath,
102909
+ JSON.stringify({ last_checked_at: now, latest: body.version })
102910
+ );
102911
+ } catch {
102912
+ } finally {
102913
+ clearTimeout(timer);
102914
+ }
102915
+ })();
102916
+ }
102917
+
102918
+ // src/index.ts
102709
102919
  init_identity();
102710
102920
  init_runtime_factory();
102711
102921
 
@@ -102725,8 +102935,20 @@ function archiveReceipt(receipt) {
102725
102935
  if (!receipt.task_id) return;
102726
102936
  ARCHIVE.set(receipt.task_id, receipt);
102727
102937
  }
102728
- function getArchivedReceipt(taskId) {
102729
- return ARCHIVE.get(taskId);
102938
+ function findArchivedReceipt(idOrPrefix) {
102939
+ const prefix = idOrPrefix.replace(/…$/, "");
102940
+ if (prefix === "") return { kind: "miss" };
102941
+ const exact = ARCHIVE.get(prefix);
102942
+ if (exact) return { kind: "hit", receipt: exact };
102943
+ const matches = [...ARCHIVE.keys()].filter((id) => id.startsWith(prefix));
102944
+ if (matches.length === 1) return { kind: "hit", receipt: ARCHIVE.get(matches[0]) };
102945
+ if (matches.length > 1) return { kind: "ambiguous", taskIds: matches };
102946
+ return { kind: "miss" };
102947
+ }
102948
+ function latestArchivedReceipt() {
102949
+ let last;
102950
+ for (const r2 of ARCHIVE.values()) last = r2;
102951
+ return last;
102730
102952
  }
102731
102953
  var CAPABILITY_PRICES_USD = {
102732
102954
  review_pr: 0.01,
@@ -103176,14 +103398,14 @@ var JsonLineDecoder = class {
103176
103398
 
103177
103399
  // ../../packages/runtime-host/dist/paths-shared.js
103178
103400
  init_esm_shims();
103179
- function isWindowsPipePath(path19) {
103180
- return path19.startsWith("\\\\.\\pipe\\");
103401
+ function isWindowsPipePath(path20) {
103402
+ return path20.startsWith("\\\\.\\pipe\\");
103181
103403
  }
103182
103404
 
103183
103405
  // ../../packages/runtime-host/dist/lockfile.js
103184
103406
  init_esm_shims();
103185
- async function readLockfile(platform, path19) {
103186
- const raw = await platform.readFile(path19);
103407
+ async function readLockfile(platform, path20) {
103408
+ const raw = await platform.readFile(path20);
103187
103409
  if (raw === null)
103188
103410
  return null;
103189
103411
  try {
@@ -103203,16 +103425,16 @@ async function readLockfile(platform, path19) {
103203
103425
  return null;
103204
103426
  }
103205
103427
  }
103206
- async function writeLockfile(platform, path19, record) {
103207
- await platform.writeFile(path19, `${JSON.stringify(record)}
103428
+ async function writeLockfile(platform, path20, record) {
103429
+ await platform.writeFile(path20, `${JSON.stringify(record)}
103208
103430
  `);
103209
103431
  }
103210
- async function removeLockfile(platform, path19, pid) {
103211
- const current2 = await readLockfile(platform, path19);
103432
+ async function removeLockfile(platform, path20, pid) {
103433
+ const current2 = await readLockfile(platform, path20);
103212
103434
  if (current2 !== null && current2.pid !== pid)
103213
103435
  return;
103214
103436
  try {
103215
- await platform.removeFile(path19);
103437
+ await platform.removeFile(path20);
103216
103438
  } catch {
103217
103439
  }
103218
103440
  }
@@ -104203,11 +104425,11 @@ init_esm_shims();
104203
104425
 
104204
104426
  // ../../packages/runtime-host/dist/node-platform.js
104205
104427
  init_esm_shims();
104206
- import { chmodSync, mkdirSync as mkdirSync5, readFileSync as readFileSync5, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
104428
+ import { chmodSync, mkdirSync as mkdirSync6, readFileSync as readFileSync6, rmSync as rmSync2, writeFileSync as writeFileSync6 } from "fs";
104207
104429
  import { connect, createServer } from "net";
104208
- import { dirname as dirname4 } from "path";
104209
- function isWindowsPipe(path19) {
104210
- return path19.startsWith("\\\\.\\pipe\\");
104430
+ import { dirname as dirname5 } from "path";
104431
+ function isWindowsPipe(path20) {
104432
+ return path20.startsWith("\\\\.\\pipe\\");
104211
104433
  }
104212
104434
  function wrapSocket(socket) {
104213
104435
  return {
@@ -104301,36 +104523,36 @@ function nodePlatform(overrides = {}) {
104301
104523
  }
104302
104524
  },
104303
104525
  // eslint-disable-next-line @typescript-eslint/require-await
104304
- async readFile(path19) {
104526
+ async readFile(path20) {
104305
104527
  try {
104306
- return readFileSync5(path19, "utf8");
104528
+ return readFileSync6(path20, "utf8");
104307
104529
  } catch {
104308
104530
  return null;
104309
104531
  }
104310
104532
  },
104311
104533
  // eslint-disable-next-line @typescript-eslint/require-await
104312
- async writeFile(path19, content) {
104313
- mkdirSync5(dirname4(path19), { recursive: true, mode: 448 });
104314
- writeFileSync5(path19, content, { mode: 384 });
104534
+ async writeFile(path20, content) {
104535
+ mkdirSync6(dirname5(path20), { recursive: true, mode: 448 });
104536
+ writeFileSync6(path20, content, { mode: 384 });
104315
104537
  },
104316
104538
  // eslint-disable-next-line @typescript-eslint/require-await
104317
- async removeFile(path19) {
104318
- rmSync2(path19, { force: true });
104539
+ async removeFile(path20) {
104540
+ rmSync2(path20, { force: true });
104319
104541
  },
104320
104542
  // eslint-disable-next-line @typescript-eslint/require-await
104321
- async mkdirExclusive(path19) {
104322
- mkdirSync5(dirname4(path19), { recursive: true, mode: 448 });
104543
+ async mkdirExclusive(path20) {
104544
+ mkdirSync6(dirname5(path20), { recursive: true, mode: 448 });
104323
104545
  try {
104324
- mkdirSync5(path19);
104546
+ mkdirSync6(path20);
104325
104547
  return "created";
104326
104548
  } catch {
104327
104549
  return "exists";
104328
104550
  }
104329
104551
  },
104330
104552
  // eslint-disable-next-line @typescript-eslint/require-await
104331
- async removeDir(path19) {
104553
+ async removeDir(path20) {
104332
104554
  try {
104333
- rmSync2(path19, { recursive: true, force: true });
104555
+ rmSync2(path20, { recursive: true, force: true });
104334
104556
  } catch {
104335
104557
  }
104336
104558
  },
@@ -104352,19 +104574,19 @@ function nodePlatform(overrides = {}) {
104352
104574
  init_esm_shims();
104353
104575
  import { createHash } from "crypto";
104354
104576
  import { homedir as homedir3 } from "os";
104355
- import { join as join8 } from "path";
104577
+ import { join as join9 } from "path";
104356
104578
  function defaultRuntimeHostPaths(home = homedir3(), platform = process.platform) {
104357
- const dir = join8(home, ".motebit");
104579
+ const dir = join9(home, ".motebit");
104358
104580
  if (platform === "win32") {
104359
104581
  const tag2 = createHash("sha256").update(dir).digest("hex").slice(0, 16);
104360
104582
  return {
104361
104583
  socketPath: `\\\\.\\pipe\\motebit-runtime-${tag2}`,
104362
- lockfilePath: join8(dir, "runtime.lock")
104584
+ lockfilePath: join9(dir, "runtime.lock")
104363
104585
  };
104364
104586
  }
104365
104587
  return {
104366
- socketPath: join8(dir, "runtime.sock"),
104367
- lockfilePath: join8(dir, "runtime.lock")
104588
+ socketPath: join9(dir, "runtime.sock"),
104589
+ lockfilePath: join9(dir, "runtime.lock")
104368
104590
  };
104369
104591
  }
104370
104592
 
@@ -104486,202 +104708,6 @@ async function electAttachOrCoordinate(fullConfig, motebitId, runtimeRef) {
104486
104708
  init_esm_shims();
104487
104709
  init_colors();
104488
104710
  init_terminal();
104489
- init_statusline();
104490
- init_status_render();
104491
- async function renderStream(stream) {
104492
- let pendingApproval = null;
104493
- let status = null;
104494
- let thinking = null;
104495
- const stopThinking = () => {
104496
- thinking?.stop();
104497
- thinking = null;
104498
- };
104499
- const stopStatus = () => {
104500
- stopThinking();
104501
- const elapsed = status?.stop() ?? 0;
104502
- status = null;
104503
- return elapsed;
104504
- };
104505
- thinking = startStatus("thinking");
104506
- try {
104507
- for await (const raw of stream) {
104508
- const chunk = raw;
104509
- switch (chunk.type) {
104510
- case "text":
104511
- stopThinking();
104512
- if (typeof chunk.text === "string") writeOutput(chunk.text);
104513
- break;
104514
- case "tool_status": {
104515
- const name = chunk.name ?? "tool";
104516
- if (chunk.status === "calling") {
104517
- if (name === "delegate_to_agent" && status) break;
104518
- stopThinking();
104519
- status = name === "delegate_to_agent" ? startStatus("delegating") : startStatus("running", name);
104520
- } else if (status) {
104521
- writeLine(
104522
- ` ${action("\u25CF")} ${action(name)} ${meta(`\xB7 done \xB7 ${formatElapsed(0, stopStatus())}`)}`
104523
- );
104524
- thinking = startStatus("thinking");
104525
- }
104526
- break;
104527
- }
104528
- case "approval_request":
104529
- pendingApproval = {
104530
- name: chunk.name ?? "tool",
104531
- args: chunk.args ?? {},
104532
- ...chunk.risk_level != null ? { riskLevel: chunk.risk_level } : {}
104533
- };
104534
- break;
104535
- case "delegation_start":
104536
- if (status) break;
104537
- stopThinking();
104538
- status = startStatus("delegating", chunk.tool ?? "task");
104539
- break;
104540
- case "delegation_complete":
104541
- stopStatus();
104542
- if (chunk.receipt?.task_id != null) {
104543
- writeLine(
104544
- dim(`[receipt ${chunk.receipt.task_id.slice(0, 8)} \xB7 ${chunk.receipt.status ?? ""}]`)
104545
- );
104546
- }
104547
- thinking = startStatus("thinking");
104548
- break;
104549
- case "injection_warning":
104550
- writeLine(`${warn2("\u26A0")} suspicious content in ${chunk.tool_name ?? "tool"} output`);
104551
- break;
104552
- case "approval_expired":
104553
- stopStatus();
104554
- writeLine(
104555
- `${warn2("[this approval expired before your answer arrived \u2014 nothing was executed]")}
104556
- ${dim(`(${chunk.tool_name ?? "the tool"} was never run; no money moved. Ask again when ready.)`)}`
104557
- );
104558
- break;
104559
- case "approval_voided":
104560
- stopStatus();
104561
- writeLine(
104562
- `${warn2("[your new message set aside the pending approval \u2014 nothing was executed]")}
104563
- ${dim(`(${chunk.tool_name ?? "the tool"} was never run; no money moved. It can be proposed again.)`)}`
104564
- );
104565
- break;
104566
- case "invoke_error":
104567
- stopStatus();
104568
- writeLine(
104569
- `${warn2(`[invoke failed${chunk.code != null ? ` \xB7 ${chunk.code}` : ""}]`)} ${chunk.message ?? ""}`
104570
- );
104571
- break;
104572
- case "task_step_narration":
104573
- if (typeof chunk.text === "string") {
104574
- status?.step(chunk.text.trim());
104575
- writeLine(` ${meta("\xB7 " + chunk.text.trim())}`);
104576
- }
104577
- break;
104578
- default:
104579
- break;
104580
- }
104581
- }
104582
- } catch (err2) {
104583
- writeLine(`${warn2("[coordinator error]")} ${err2 instanceof Error ? err2.message : String(err2)}`);
104584
- } finally {
104585
- stopStatus();
104586
- }
104587
- return { pendingApproval };
104588
- }
104589
- async function renderTurn(client, motebitId, stream) {
104590
- let current2 = stream;
104591
- for (; ; ) {
104592
- const { pendingApproval } = await renderStream(current2);
104593
- if (pendingApproval === null) return;
104594
- for (const line of renderApprovalRequest({
104595
- name: pendingApproval.name,
104596
- args: pendingApproval.args,
104597
- ...pendingApproval.riskLevel != null ? { riskLevel: pendingApproval.riskLevel } : {}
104598
- })) {
104599
- writeLine(line);
104600
- }
104601
- const answer = await askQuestion(` ${warn2("Allow?")} ${dim("(y/n)")} `);
104602
- const approved = answer.trim().toLowerCase() === "y";
104603
- current2 = client.resolveApproval(approved, motebitId);
104604
- }
104605
- }
104606
- var ATTACHED_HELP = `
104607
- Attached mode \u2014 the coordinator process owns the runtime; this terminal renders.
104608
- <text> chat with your motebit (proxied to the coordinator)
104609
- /invoke <cap> <text> invoke a capability deterministically
104610
- /help this help
104611
- /exit leave (the coordinator keeps running)
104612
- Other slash commands need the runtime in-process: exit, stop the coordinator, and re-run \`motebit\`.
104613
- `;
104614
- async function runAttachedRepl(client, motebitId) {
104615
- writeOutput(
104616
- `
104617
- ${dim("Attached to the machine's coordinator runtime")} ${dim(`(pid ${client.coordinatorPid})`)}
104618
- ${dim("This terminal renders; the coordinator acts. /help for what's available.")}
104619
-
104620
- `
104621
- );
104622
- setModeRow(renderModeRow({ attachedPid: client.coordinatorPid }));
104623
- let closed = false;
104624
- client.onClose(() => {
104625
- closed = true;
104626
- writeOutput(
104627
- `
104628
- ${warn2("Coordinator exited.")} Run \`motebit\` again to take over as coordinator.
104629
- `
104630
- );
104631
- destroyTerminal();
104632
- process.exit(0);
104633
- });
104634
- for (; ; ) {
104635
- if (closed) return;
104636
- let line;
104637
- try {
104638
- line = await readInput(prompt("you>") + " ");
104639
- } catch {
104640
- break;
104641
- }
104642
- const trimmed = line.trim();
104643
- if (trimmed === "") continue;
104644
- if (trimmed === "/exit" || trimmed === "/quit" || trimmed === "exit" || trimmed === "quit") {
104645
- writeOutput("Goodbye! (coordinator keeps running)\n");
104646
- break;
104647
- }
104648
- if (trimmed === "/help") {
104649
- writeOutput(ATTACHED_HELP);
104650
- continue;
104651
- }
104652
- if (trimmed.startsWith("/invoke ")) {
104653
- const rest = trimmed.slice("/invoke ".length).trim();
104654
- const space = rest.indexOf(" ");
104655
- const capability = space === -1 ? rest : rest.slice(0, space);
104656
- const prompt2 = space === -1 ? "" : rest.slice(space + 1);
104657
- if (capability === "") {
104658
- writeOutput(`${warn2("usage:")} /invoke <capability> <prompt>
104659
- `);
104660
- continue;
104661
- }
104662
- writeOutput(prompt("mote>") + " ");
104663
- await renderTurn(client, motebitId, client.invoke(capability, prompt2));
104664
- writeOutput("\n");
104665
- continue;
104666
- }
104667
- if (trimmed.startsWith("/")) {
104668
- writeOutput(
104669
- `${dim(`${trimmed.split(" ")[0]} needs the runtime in-process \u2014 not available in attached mode.`)}
104670
- ${dim("Stop the coordinator and re-run `motebit` to use it.")}
104671
- `
104672
- );
104673
- continue;
104674
- }
104675
- writeOutput(prompt("mote>") + " ");
104676
- await renderTurn(client, motebitId, client.chat(trimmed));
104677
- writeOutput("\n");
104678
- }
104679
- client.close();
104680
- destroyTerminal();
104681
- }
104682
-
104683
- // src/index.ts
104684
- init_colors();
104685
104711
 
104686
104712
  // src/slash-commands.ts
104687
104713
  init_esm_shims();
@@ -105007,21 +105033,21 @@ var RelayClientError = class extends Error {
105007
105033
  path;
105008
105034
  /** Relay-provided error body text when available (non-2xx responses). */
105009
105035
  body;
105010
- constructor(kind, path19, message2, options) {
105036
+ constructor(kind, path20, message2, options) {
105011
105037
  super(message2, options?.cause !== void 0 ? { cause: options.cause } : void 0);
105012
105038
  this.name = "RelayClientError";
105013
105039
  this.kind = kind;
105014
- this.path = path19;
105040
+ this.path = path20;
105015
105041
  this.status = options?.status;
105016
105042
  this.body = options?.body;
105017
105043
  }
105018
105044
  };
105019
105045
 
105020
105046
  // ../../packages/relay-client/dist/client.js
105021
- function validate(schema, body, path19, label) {
105047
+ function validate(schema, body, path20, label) {
105022
105048
  const parsed = schema.safeParse(body);
105023
105049
  if (!parsed.success) {
105024
- throw new RelayClientError("schema", path19, `${label} response failed wire-schema validation: ${parsed.error.message}`);
105050
+ throw new RelayClientError("schema", path20, `${label} response failed wire-schema validation: ${parsed.error.message}`);
105025
105051
  }
105026
105052
  return parsed.data;
105027
105053
  }
@@ -105060,11 +105086,11 @@ var RelayClient = class {
105060
105086
  * never sends credentials, regardless of configured auth.
105061
105087
  */
105062
105088
  async discover(motebitId) {
105063
- const path19 = `/api/v1/discover/${encodeURIComponent(motebitId)}`;
105064
- const body = await this.requestJson("GET", path19, {
105089
+ const path20 = `/api/v1/discover/${encodeURIComponent(motebitId)}`;
105090
+ const body = await this.requestJson("GET", path20, {
105065
105091
  retry: true
105066
105092
  });
105067
- return validate(AgentResolutionResultSchema, body, path19, "discover");
105093
+ return validate(AgentResolutionResultSchema, body, path20, "discover");
105068
105094
  }
105069
105095
  /**
105070
105096
  * `GET /api/v1/agents/:motebitId/balance`. Contract tier: VALIDATED
@@ -105073,12 +105099,12 @@ var RelayClient = class {
105073
105099
  * converts from micro-units at its boundary; never convert again.
105074
105100
  */
105075
105101
  async getBalance(motebitId) {
105076
- const path19 = `/api/v1/agents/${encodeURIComponent(motebitId)}/balance`;
105077
- const body = await this.requestJson("GET", path19, {
105102
+ const path20 = `/api/v1/agents/${encodeURIComponent(motebitId)}/balance`;
105103
+ const body = await this.requestJson("GET", path20, {
105078
105104
  audience: ACCOUNT_BALANCE_AUDIENCE,
105079
105105
  retry: true
105080
105106
  });
105081
- return validate(AccountBalanceResultSchema, body, path19, "balance");
105107
+ return validate(AccountBalanceResultSchema, body, path20, "balance");
105082
105108
  }
105083
105109
  /**
105084
105110
  * `POST /agent/:targetMotebitId/task` — submit a delegation task.
@@ -105087,8 +105113,8 @@ var RelayClient = class {
105087
105113
  * caller supplies it so a retry by the CALLER replays, never double-spends.
105088
105114
  */
105089
105115
  async submitTask(targetMotebitId, request, options) {
105090
- const path19 = `/agent/${encodeURIComponent(targetMotebitId)}/task`;
105091
- const body = await this.requestJson("POST", path19, {
105116
+ const path20 = `/agent/${encodeURIComponent(targetMotebitId)}/task`;
105117
+ const body = await this.requestJson("POST", path20, {
105092
105118
  audience: TASK_SUBMIT_AUDIENCE,
105093
105119
  retry: false,
105094
105120
  jsonBody: request,
@@ -105102,8 +105128,8 @@ var RelayClient = class {
105102
105128
  * token; the relay authorizes submitter-or-target).
105103
105129
  */
105104
105130
  async getTask(targetMotebitId, taskId) {
105105
- const path19 = `/agent/${encodeURIComponent(targetMotebitId)}/task/${encodeURIComponent(taskId)}`;
105106
- const body = await this.requestJson("GET", path19, {
105131
+ const path20 = `/agent/${encodeURIComponent(targetMotebitId)}/task/${encodeURIComponent(taskId)}`;
105132
+ const body = await this.requestJson("GET", path20, {
105107
105133
  audience: TASK_QUERY_AUDIENCE,
105108
105134
  retry: true
105109
105135
  });
@@ -105121,24 +105147,24 @@ var RelayClient = class {
105121
105147
  * `kind: "http"`, `status: 402`.
105122
105148
  */
105123
105149
  async withdraw(motebitId, request, options) {
105124
- const path19 = `/api/v1/agents/${encodeURIComponent(motebitId)}/withdraw`;
105125
- const body = await this.requestJson("POST", path19, {
105150
+ const path20 = `/api/v1/agents/${encodeURIComponent(motebitId)}/withdraw`;
105151
+ const body = await this.requestJson("POST", path20, {
105126
105152
  audience: ACCOUNT_WITHDRAW_AUDIENCE,
105127
105153
  retry: false,
105128
105154
  jsonBody: request,
105129
105155
  headers: { "Idempotency-Key": options.idempotencyKey }
105130
105156
  });
105131
- return validate(AccountWithdrawResultSchema, body, path19, "withdraw");
105157
+ return validate(AccountWithdrawResultSchema, body, path20, "withdraw");
105132
105158
  }
105133
105159
  // ── Transport kernel ─────────────────────────────────────────────────
105134
- async requestJson(method, path19, opts) {
105160
+ async requestJson(method, path20, opts) {
105135
105161
  const headers = { ...opts.headers };
105136
105162
  if (opts.jsonBody !== void 0)
105137
105163
  headers["Content-Type"] = "application/json";
105138
105164
  if (opts.audience !== void 0) {
105139
105165
  const token = await this.resolveToken(opts.audience);
105140
105166
  if (token == null) {
105141
- throw new RelayClientError("auth", path19, `no credential available for ${path19} (audience ${opts.audience}) \u2014 provide credentialSource, deviceKey, or staticToken`);
105167
+ throw new RelayClientError("auth", path20, `no credential available for ${path20} (audience ${opts.audience}) \u2014 provide credentialSource, deviceKey, or staticToken`);
105142
105168
  }
105143
105169
  headers["Authorization"] = `Bearer ${token}`;
105144
105170
  }
@@ -105147,7 +105173,7 @@ var RelayClient = class {
105147
105173
  headers,
105148
105174
  ...opts.jsonBody !== void 0 ? { body: JSON.stringify(opts.jsonBody) } : {}
105149
105175
  };
105150
- const res = await this.fetchWithRetry(path19, init, opts.retry);
105176
+ const res = await this.fetchWithRetry(path20, init, opts.retry);
105151
105177
  if (!res.ok) {
105152
105178
  let bodyText;
105153
105179
  try {
@@ -105155,7 +105181,7 @@ var RelayClient = class {
105155
105181
  } catch {
105156
105182
  bodyText = void 0;
105157
105183
  }
105158
- throw new RelayClientError("http", path19, `${method} ${path19} \u2192 ${res.status}`, {
105184
+ throw new RelayClientError("http", path20, `${method} ${path20} \u2192 ${res.status}`, {
105159
105185
  status: res.status,
105160
105186
  body: bodyText
105161
105187
  });
@@ -105163,13 +105189,13 @@ var RelayClient = class {
105163
105189
  try {
105164
105190
  return await res.json();
105165
105191
  } catch (err2) {
105166
- throw new RelayClientError("parse", path19, `${method} ${path19} returned non-JSON body`, {
105192
+ throw new RelayClientError("parse", path20, `${method} ${path20} returned non-JSON body`, {
105167
105193
  cause: err2
105168
105194
  });
105169
105195
  }
105170
105196
  }
105171
- async fetchWithRetry(path19, init, retry) {
105172
- const url = `${this.baseUrl}${path19}`;
105197
+ async fetchWithRetry(path20, init, retry) {
105198
+ const url = `${this.baseUrl}${path20}`;
105173
105199
  const attempts = retry ? this.maxRetries + 1 : 1;
105174
105200
  let lastNetworkError;
105175
105201
  for (let attempt = 0; attempt < attempts; attempt++) {
@@ -105186,7 +105212,7 @@ var RelayClient = class {
105186
105212
  }
105187
105213
  await this.backoff(attempt);
105188
105214
  }
105189
- throw new RelayClientError("network", path19, `request to ${path19} failed after ${attempts} attempt(s)`, {
105215
+ throw new RelayClientError("network", path20, `request to ${path20} failed after ${attempts} attempt(s)`, {
105190
105216
  cause: lastNetworkError
105191
105217
  });
105192
105218
  }
@@ -105471,7 +105497,7 @@ init_dist6();
105471
105497
 
105472
105498
  // ../../packages/mcp-server/dist/bootstrap-service.js
105473
105499
  init_esm_shims();
105474
- import { writeFileSync as writeFileSync7 } from "fs";
105500
+ import { writeFileSync as writeFileSync8 } from "fs";
105475
105501
  import { resolve as resolve6 } from "path";
105476
105502
 
105477
105503
  // ../../packages/core-identity/dist/node.js
@@ -105479,12 +105505,12 @@ init_esm_shims();
105479
105505
 
105480
105506
  // ../../packages/core-identity/dist/file-stores.js
105481
105507
  init_esm_shims();
105482
- import { existsSync as existsSync2, readFileSync as readFileSync6, writeFileSync as writeFileSync6, renameSync as renameSync2, chmodSync as chmodSync2 } from "fs";
105508
+ import { existsSync as existsSync2, readFileSync as readFileSync7, writeFileSync as writeFileSync7, renameSync as renameSync2, chmodSync as chmodSync2 } from "fs";
105483
105509
 
105484
105510
  // ../../packages/core-identity/dist/bootstrap-service.js
105485
105511
  init_esm_shims();
105486
- import { mkdirSync as mkdirSync6, existsSync as existsSync3 } from "fs";
105487
- import { join as join9 } from "path";
105512
+ import { mkdirSync as mkdirSync7, existsSync as existsSync3 } from "fs";
105513
+ import { join as join10 } from "path";
105488
105514
  init_dist17();
105489
105515
  init_dist16();
105490
105516
 
@@ -106274,7 +106300,7 @@ var McpServerAdapter = class _McpServerAdapter {
106274
106300
  init_config2();
106275
106301
  init_dist32();
106276
106302
  init_node_fs();
106277
- import { join as join10 } from "path";
106303
+ import { join as join11 } from "path";
106278
106304
 
106279
106305
  // src/utils.ts
106280
106306
  init_esm_shims();
@@ -106343,14 +106369,25 @@ async function handleInvokeCommand(args, deps) {
106343
106369
  async function handleReceiptCommand(args, deps) {
106344
106370
  const out = deps.out ?? ((s3) => console.log(s3));
106345
106371
  const taskId = args.trim();
106372
+ let receipt;
106346
106373
  if (!taskId) {
106347
- out(error2("Usage: /receipt <task-id>"));
106348
- return;
106349
- }
106350
- const receipt = getArchivedReceipt(taskId);
106351
- if (!receipt) {
106352
- out(warn2(`No archived receipt for task_id=${taskId}`));
106353
- return;
106374
+ receipt = latestArchivedReceipt();
106375
+ if (!receipt) {
106376
+ out(warn2("No receipts archived this session. Usage: /receipt [task-id-prefix]"));
106377
+ return;
106378
+ }
106379
+ } else {
106380
+ const found = findArchivedReceipt(taskId);
106381
+ if (found.kind === "ambiguous") {
106382
+ out(warn2(`Prefix "${taskId}" matches ${found.taskIds.length} receipts:`));
106383
+ for (const id of found.taskIds) out(dim(` ${id}`));
106384
+ return;
106385
+ }
106386
+ if (found.kind === "miss") {
106387
+ out(warn2(`No archived receipt matches "${taskId}" this session.`));
106388
+ return;
106389
+ }
106390
+ receipt = found.receipt;
106354
106391
  }
106355
106392
  out("");
106356
106393
  await renderReceipt(receipt, out);
@@ -106391,6 +106428,369 @@ async function drainInvokeStream(stream, out, voice) {
106391
106428
  }
106392
106429
  }
106393
106430
 
106431
+ // etc/cli-surface.json
106432
+ var cli_surface_default = {
106433
+ subcommands: {
106434
+ approvals: [
106435
+ "approve",
106436
+ "deny",
106437
+ "list",
106438
+ "show"
106439
+ ],
106440
+ attest: [],
106441
+ balance: [],
106442
+ credentials: [],
106443
+ delegate: [],
106444
+ discover: [],
106445
+ doctor: [],
106446
+ export: [],
106447
+ federation: [
106448
+ "mesh",
106449
+ "peer",
106450
+ "peer-remove",
106451
+ "peers",
106452
+ "status"
106453
+ ],
106454
+ fund: [],
106455
+ goal: [
106456
+ "add",
106457
+ "list",
106458
+ "outcomes",
106459
+ "pause",
106460
+ "remove",
106461
+ "resume"
106462
+ ],
106463
+ grant: [],
106464
+ id: [],
106465
+ init: [],
106466
+ keychain: [],
106467
+ ledger: [],
106468
+ logs: [],
106469
+ lsp: [],
106470
+ migrate: [],
106471
+ "migrate-keyring": [],
106472
+ ps: [],
106473
+ register: [],
106474
+ relay: [
106475
+ "up"
106476
+ ],
106477
+ restore: [],
106478
+ rotate: [],
106479
+ run: [],
106480
+ schema: [],
106481
+ seed: [],
106482
+ serve: [],
106483
+ skills: [],
106484
+ smoke: [],
106485
+ up: [],
106486
+ verify: [
106487
+ "identity"
106488
+ ],
106489
+ "verify-release": [],
106490
+ wallet: [],
106491
+ withdraw: []
106492
+ },
106493
+ flags: [
106494
+ {
106495
+ name: "address-only",
106496
+ type: "boolean",
106497
+ default: false
106498
+ },
106499
+ {
106500
+ name: "all",
106501
+ type: "boolean",
106502
+ default: false
106503
+ },
106504
+ {
106505
+ name: "allow-commands",
106506
+ type: "string"
106507
+ },
106508
+ {
106509
+ name: "allowed-paths",
106510
+ type: "string"
106511
+ },
106512
+ {
106513
+ name: "auto-approve",
106514
+ type: "boolean",
106515
+ default: false
106516
+ },
106517
+ {
106518
+ name: "block-commands",
106519
+ type: "string"
106520
+ },
106521
+ {
106522
+ name: "budget",
106523
+ type: "string"
106524
+ },
106525
+ {
106526
+ name: "cadence-hours",
106527
+ type: "string"
106528
+ },
106529
+ {
106530
+ name: "capability",
106531
+ type: "string"
106532
+ },
106533
+ {
106534
+ name: "days",
106535
+ type: "string"
106536
+ },
106537
+ {
106538
+ name: "db-path",
106539
+ type: "string"
106540
+ },
106541
+ {
106542
+ name: "destination",
106543
+ type: "string"
106544
+ },
106545
+ {
106546
+ name: "direct",
106547
+ type: "boolean",
106548
+ default: false
106549
+ },
106550
+ {
106551
+ name: "dry-run",
106552
+ type: "boolean",
106553
+ default: false
106554
+ },
106555
+ {
106556
+ name: "event-type",
106557
+ type: "string"
106558
+ },
106559
+ {
106560
+ name: "every",
106561
+ type: "string"
106562
+ },
106563
+ {
106564
+ name: "facilitator-url",
106565
+ type: "string"
106566
+ },
106567
+ {
106568
+ name: "federation-url",
106569
+ type: "string"
106570
+ },
106571
+ {
106572
+ name: "file",
106573
+ type: "string",
106574
+ short: "f"
106575
+ },
106576
+ {
106577
+ name: "force",
106578
+ type: "boolean",
106579
+ default: false
106580
+ },
106581
+ {
106582
+ name: "grant",
106583
+ type: "string"
106584
+ },
106585
+ {
106586
+ name: "help",
106587
+ type: "boolean",
106588
+ default: false,
106589
+ short: "h"
106590
+ },
106591
+ {
106592
+ name: "identity",
106593
+ type: "string"
106594
+ },
106595
+ {
106596
+ name: "json",
106597
+ type: "boolean",
106598
+ default: false
106599
+ },
106600
+ {
106601
+ name: "lifetime-usd",
106602
+ type: "string"
106603
+ },
106604
+ {
106605
+ name: "limit",
106606
+ type: "string"
106607
+ },
106608
+ {
106609
+ name: "max-tokens",
106610
+ type: "string"
106611
+ },
106612
+ {
106613
+ name: "model",
106614
+ type: "string"
106615
+ },
106616
+ {
106617
+ name: "network",
106618
+ type: "string"
106619
+ },
106620
+ {
106621
+ name: "no-stream",
106622
+ type: "boolean",
106623
+ default: false
106624
+ },
106625
+ {
106626
+ name: "once",
106627
+ type: "boolean",
106628
+ default: false
106629
+ },
106630
+ {
106631
+ name: "operator",
106632
+ type: "boolean",
106633
+ default: false
106634
+ },
106635
+ {
106636
+ name: "output",
106637
+ type: "string",
106638
+ short: "o"
106639
+ },
106640
+ {
106641
+ name: "passphrase",
106642
+ type: "boolean",
106643
+ default: false
106644
+ },
106645
+ {
106646
+ name: "pay-new-agents",
106647
+ type: "boolean",
106648
+ default: false
106649
+ },
106650
+ {
106651
+ name: "pay-to-address",
106652
+ type: "string"
106653
+ },
106654
+ {
106655
+ name: "plan",
106656
+ type: "boolean",
106657
+ default: false
106658
+ },
106659
+ {
106660
+ name: "port",
106661
+ type: "string"
106662
+ },
106663
+ {
106664
+ name: "presentation",
106665
+ type: "boolean",
106666
+ default: false
106667
+ },
106668
+ {
106669
+ name: "price",
106670
+ type: "string"
106671
+ },
106672
+ {
106673
+ name: "project",
106674
+ type: "string"
106675
+ },
106676
+ {
106677
+ name: "provider",
106678
+ type: "string",
106679
+ default: "anthropic"
106680
+ },
106681
+ {
106682
+ name: "prune",
106683
+ type: "boolean",
106684
+ default: false
106685
+ },
106686
+ {
106687
+ name: "reason",
106688
+ type: "string"
106689
+ },
106690
+ {
106691
+ name: "routing-strategy",
106692
+ type: "string"
106693
+ },
106694
+ {
106695
+ name: "scope",
106696
+ type: "string"
106697
+ },
106698
+ {
106699
+ name: "self-test",
106700
+ type: "boolean",
106701
+ default: false
106702
+ },
106703
+ {
106704
+ name: "serve-port",
106705
+ type: "string"
106706
+ },
106707
+ {
106708
+ name: "serve-transport",
106709
+ type: "string"
106710
+ },
106711
+ {
106712
+ name: "solana-rpc-url",
106713
+ type: "string"
106714
+ },
106715
+ {
106716
+ name: "sovereign",
106717
+ type: "boolean",
106718
+ default: false
106719
+ },
106720
+ {
106721
+ name: "subject",
106722
+ type: "string"
106723
+ },
106724
+ {
106725
+ name: "sync-token",
106726
+ type: "string"
106727
+ },
106728
+ {
106729
+ name: "sync-url",
106730
+ type: "string"
106731
+ },
106732
+ {
106733
+ name: "tail",
106734
+ type: "boolean",
106735
+ default: false
106736
+ },
106737
+ {
106738
+ name: "target",
106739
+ type: "string"
106740
+ },
106741
+ {
106742
+ name: "tools",
106743
+ type: "string"
106744
+ },
106745
+ {
106746
+ name: "version",
106747
+ type: "boolean",
106748
+ default: false,
106749
+ short: "v"
106750
+ },
106751
+ {
106752
+ name: "voice",
106753
+ type: "boolean",
106754
+ default: false
106755
+ },
106756
+ {
106757
+ name: "waive",
106758
+ type: "boolean",
106759
+ default: false
106760
+ },
106761
+ {
106762
+ name: "wall-clock",
106763
+ type: "string"
106764
+ },
106765
+ {
106766
+ name: "window-hours",
106767
+ type: "string"
106768
+ },
106769
+ {
106770
+ name: "window-usd",
106771
+ type: "string"
106772
+ }
106773
+ ],
106774
+ exitCodes: [
106775
+ 0,
106776
+ 1,
106777
+ 2,
106778
+ 130
106779
+ ],
106780
+ onDiskLayout: [
106781
+ "config.json",
106782
+ "dev-keyring.json",
106783
+ "identity.md",
106784
+ "motebit.db",
106785
+ "motebit.md",
106786
+ "relay",
106787
+ "relay/relay.db",
106788
+ "smoke-x402-buyer-eoa.txt",
106789
+ "smoke-x402-worker-eoa.txt",
106790
+ "update-check.json"
106791
+ ]
106792
+ };
106793
+
106394
106794
  // src/slash-commands.ts
106395
106795
  function isSlashCommand(input) {
106396
106796
  return input.startsWith("/");
@@ -106413,6 +106813,17 @@ function resolveBareCommand(input) {
106413
106813
  if (name === "ledger" && words.length === 2) return `/ledger ${words[1]}`;
106414
106814
  return null;
106415
106815
  }
106816
+ function detectShellInvocation(input) {
106817
+ if (input.includes("?")) return null;
106818
+ const words = input.trim().split(/\s+/);
106819
+ if (words.length < 2 || words[0] !== "motebit") return null;
106820
+ const second = words[1];
106821
+ const known = second.startsWith("--") ? CLI_FLAG_NAMES.has(second.slice(2).split("=")[0].toLowerCase()) : CLI_SUBCOMMAND_NAMES.has(second.toLowerCase());
106822
+ if (!known) return null;
106823
+ return " that's a shell command \u2014 type `quit`, then run it in your terminal";
106824
+ }
106825
+ var CLI_SUBCOMMAND_NAMES = new Set(Object.keys(cli_surface_default.subcommands));
106826
+ var CLI_FLAG_NAMES = new Set(cli_surface_default.flags.map((f7) => f7.name.toLowerCase()));
106416
106827
  function renderProvenanceBadge(record) {
106417
106828
  const status = record.provenance_status;
106418
106829
  if (status === "verified") return success("[verified]");
@@ -106475,8 +106886,8 @@ function parseSub(args) {
106475
106886
  const m4 = args.match(/^(\S+)\s*([\s\S]*)$/);
106476
106887
  return m4 ? { sub: m4[1], rest: (m4[2] ?? "").trim() } : { sub: "", rest: "" };
106477
106888
  }
106478
- async function relayFetch2(baseUrl, path19, opts) {
106479
- const url = `${baseUrl.replace(/\/+$/, "")}${path19}`;
106889
+ async function relayFetch2(baseUrl, path20, opts) {
106890
+ const url = `${baseUrl.replace(/\/+$/, "")}${path20}`;
106480
106891
  const init = { headers: opts?.headers };
106481
106892
  if (opts?.method) init.method = opts.method;
106482
106893
  if (opts?.body != null) init.body = JSON.stringify(opts.body);
@@ -106748,7 +107159,10 @@ ${summary}`);
106748
107159
  "gpt-5.4-mini": "gpt-5.4-mini",
106749
107160
  "gpt-5.4-nano": "gpt-5.4-nano",
106750
107161
  o3: "o3",
107162
+ qwen3: "qwen3",
107163
+ "gpt-oss": "gpt-oss",
106751
107164
  "llama3.2": "llama3.2",
107165
+ // legacy alias — still resolvable, no longer suggested
106752
107166
  mistral: "mistral"
106753
107167
  };
106754
107168
  const envKey = config.provider === "openai" ? process.env["OPENAI_API_KEY"] : process.env["ANTHROPIC_API_KEY"];
@@ -106839,6 +107253,10 @@ Unknown model: ${cyan(args)}
106839
107253
  break;
106840
107254
  }
106841
107255
  runtime.setModel(modelId);
107256
+ if (runtime.moneyToolsWithheld) {
107257
+ console.log(`
107258
+ ${dim(MONEY_TOOLS_WITHHELD_NOTICE)}`);
107259
+ }
106842
107260
  if (fullConfig) {
106843
107261
  fullConfig.default_model = modelId;
106844
107262
  const persistable = ["anthropic", "openai", "google", "local-server", "proxy"];
@@ -107057,9 +107475,9 @@ Unknown model: ${cyan(args)}
107057
107475
  let guardianAttest;
107058
107476
  try {
107059
107477
  const { parse: parse3 } = await Promise.resolve().then(() => (init_dist34(), dist_exports10));
107060
- const fs19 = await import("fs");
107478
+ const fs20 = await import("fs");
107061
107479
  const idPath = config.identity ?? "motebit.md";
107062
- const content = fs19.readFileSync(idPath, "utf-8");
107480
+ const content = fs20.readFileSync(idPath, "utf-8");
107063
107481
  const guardian = parse3(content).frontmatter.guardian;
107064
107482
  guardianPubKey = guardian?.public_key;
107065
107483
  guardianAttest = guardian?.attestation;
@@ -108406,7 +108824,7 @@ Curiosity targets (${targets.length}):
108406
108824
  }
108407
108825
  case "skills": {
108408
108826
  const registry = new SkillRegistry(
108409
- new NodeFsSkillStorageAdapter({ root: join10(CONFIG_DIR, "skills") })
108827
+ new NodeFsSkillStorageAdapter({ root: join11(CONFIG_DIR, "skills") })
108410
108828
  );
108411
108829
  const records = await registry.list();
108412
108830
  if (records.length === 0) {
@@ -108437,7 +108855,7 @@ Curiosity targets (${targets.length}):
108437
108855
  break;
108438
108856
  }
108439
108857
  const registry = new SkillRegistry(
108440
- new NodeFsSkillStorageAdapter({ root: join10(CONFIG_DIR, "skills") })
108858
+ new NodeFsSkillStorageAdapter({ root: join11(CONFIG_DIR, "skills") })
108441
108859
  );
108442
108860
  const record = await registry.get(name);
108443
108861
  if (!record) {
@@ -108515,6 +108933,209 @@ Curiosity targets (${targets.length}):
108515
108933
  }
108516
108934
  }
108517
108935
 
108936
+ // src/attached-repl.ts
108937
+ init_statusline();
108938
+ init_status_render();
108939
+ async function renderStream(stream) {
108940
+ let pendingApproval = null;
108941
+ let status = null;
108942
+ let thinking = null;
108943
+ const stopThinking = () => {
108944
+ thinking?.stop();
108945
+ thinking = null;
108946
+ };
108947
+ const stopStatus = () => {
108948
+ stopThinking();
108949
+ const elapsed = status?.stop() ?? 0;
108950
+ status = null;
108951
+ return elapsed;
108952
+ };
108953
+ thinking = startStatus("thinking");
108954
+ try {
108955
+ for await (const raw of stream) {
108956
+ const chunk = raw;
108957
+ switch (chunk.type) {
108958
+ case "text":
108959
+ stopThinking();
108960
+ if (typeof chunk.text === "string") writeOutput(chunk.text);
108961
+ break;
108962
+ case "tool_status": {
108963
+ const name = chunk.name ?? "tool";
108964
+ if (chunk.status === "calling") {
108965
+ if (name === "delegate_to_agent" && status) break;
108966
+ stopThinking();
108967
+ status = name === "delegate_to_agent" ? startStatus("delegating") : startStatus("running", name);
108968
+ } else if (status) {
108969
+ writeLine(
108970
+ ` ${action("\u25CF")} ${action(name)} ${meta(`\xB7 done \xB7 ${formatElapsed(0, stopStatus())}`)}`
108971
+ );
108972
+ thinking = startStatus("thinking");
108973
+ }
108974
+ break;
108975
+ }
108976
+ case "approval_request":
108977
+ pendingApproval = {
108978
+ name: chunk.name ?? "tool",
108979
+ args: chunk.args ?? {},
108980
+ ...chunk.risk_level != null ? { riskLevel: chunk.risk_level } : {}
108981
+ };
108982
+ break;
108983
+ case "delegation_start":
108984
+ if (status) break;
108985
+ stopThinking();
108986
+ status = startStatus("delegating", chunk.tool ?? "task");
108987
+ break;
108988
+ case "delegation_complete":
108989
+ stopStatus();
108990
+ if (chunk.receipt?.task_id != null) {
108991
+ writeLine(
108992
+ dim(`[receipt ${chunk.receipt.task_id.slice(0, 8)} \xB7 ${chunk.receipt.status ?? ""}]`)
108993
+ );
108994
+ }
108995
+ thinking = startStatus("thinking");
108996
+ break;
108997
+ case "injection_warning":
108998
+ writeLine(`${warn2("\u26A0")} suspicious content in ${chunk.tool_name ?? "tool"} output`);
108999
+ break;
109000
+ case "approval_expired":
109001
+ stopStatus();
109002
+ writeLine(
109003
+ `${warn2("[this approval expired before your answer arrived \u2014 nothing was executed]")}
109004
+ ${dim(`(${chunk.tool_name ?? "the tool"} was never run; no money moved. Ask again when ready.)`)}`
109005
+ );
109006
+ break;
109007
+ case "approval_voided":
109008
+ stopStatus();
109009
+ writeLine(
109010
+ `${warn2("[your new message set aside the pending approval \u2014 nothing was executed]")}
109011
+ ${dim(`(${chunk.tool_name ?? "the tool"} was never run; no money moved. It can be proposed again.)`)}`
109012
+ );
109013
+ break;
109014
+ case "invoke_error":
109015
+ stopStatus();
109016
+ writeLine(
109017
+ `${warn2(`[invoke failed${chunk.code != null ? ` \xB7 ${chunk.code}` : ""}]`)} ${chunk.message ?? ""}`
109018
+ );
109019
+ break;
109020
+ case "task_step_narration":
109021
+ if (typeof chunk.text === "string") {
109022
+ status?.step(chunk.text.trim());
109023
+ writeLine(` ${meta("\xB7 " + chunk.text.trim())}`);
109024
+ }
109025
+ break;
109026
+ default:
109027
+ break;
109028
+ }
109029
+ }
109030
+ } catch (err2) {
109031
+ writeLine(`${warn2("[coordinator error]")} ${err2 instanceof Error ? err2.message : String(err2)}`);
109032
+ } finally {
109033
+ stopStatus();
109034
+ }
109035
+ return { pendingApproval };
109036
+ }
109037
+ async function renderTurn(client, motebitId, stream) {
109038
+ let current2 = stream;
109039
+ for (; ; ) {
109040
+ const { pendingApproval } = await renderStream(current2);
109041
+ if (pendingApproval === null) return;
109042
+ for (const line of renderApprovalRequest({
109043
+ name: pendingApproval.name,
109044
+ args: pendingApproval.args,
109045
+ ...pendingApproval.riskLevel != null ? { riskLevel: pendingApproval.riskLevel } : {}
109046
+ })) {
109047
+ writeLine(line);
109048
+ }
109049
+ const answer = await askQuestion(` ${warn2("Allow?")} ${dim("(y/n)")} `);
109050
+ const approved = answer.trim().toLowerCase() === "y";
109051
+ current2 = client.resolveApproval(approved, motebitId);
109052
+ }
109053
+ }
109054
+ var ATTACHED_HELP = `
109055
+ Attached mode \u2014 the coordinator process owns the runtime; this terminal renders.
109056
+ <text> chat with your motebit (proxied to the coordinator)
109057
+ /invoke <cap> <text> invoke a capability deterministically
109058
+ /help this help
109059
+ /exit leave (the coordinator keeps running)
109060
+ Other slash commands need the runtime in-process: exit, stop the coordinator, and re-run \`motebit\`.
109061
+ `;
109062
+ async function runAttachedRepl(client, motebitId) {
109063
+ writeOutput(
109064
+ `
109065
+ ${dim("Attached to the machine's coordinator runtime")} ${dim(`(pid ${client.coordinatorPid})`)}
109066
+ ${dim("This terminal renders; the coordinator acts. /help for what's available.")}
109067
+
109068
+ `
109069
+ );
109070
+ setModeRow(renderModeRow({ attachedPid: client.coordinatorPid }));
109071
+ let closed = false;
109072
+ client.onClose(() => {
109073
+ closed = true;
109074
+ writeOutput(
109075
+ `
109076
+ ${warn2("Coordinator exited.")} Run \`motebit\` again to take over as coordinator.
109077
+ `
109078
+ );
109079
+ destroyTerminal();
109080
+ process.exit(0);
109081
+ });
109082
+ for (; ; ) {
109083
+ if (closed) return;
109084
+ let line;
109085
+ try {
109086
+ line = await readInput(prompt("you>") + " ");
109087
+ } catch {
109088
+ break;
109089
+ }
109090
+ const trimmed = line.trim();
109091
+ if (trimmed === "") continue;
109092
+ if (trimmed === "/exit" || trimmed === "/quit" || trimmed === "exit" || trimmed === "quit") {
109093
+ writeOutput("Goodbye! (coordinator keeps running)\n");
109094
+ break;
109095
+ }
109096
+ if (trimmed === "/help") {
109097
+ writeOutput(ATTACHED_HELP);
109098
+ continue;
109099
+ }
109100
+ if (trimmed.startsWith("/invoke ")) {
109101
+ const rest = trimmed.slice("/invoke ".length).trim();
109102
+ const space = rest.indexOf(" ");
109103
+ const capability = space === -1 ? rest : rest.slice(0, space);
109104
+ const prompt2 = space === -1 ? "" : rest.slice(space + 1);
109105
+ if (capability === "") {
109106
+ writeOutput(`${warn2("usage:")} /invoke <capability> <prompt>
109107
+ `);
109108
+ continue;
109109
+ }
109110
+ writeOutput(prompt("mote>") + " ");
109111
+ await renderTurn(client, motebitId, client.invoke(capability, prompt2));
109112
+ writeOutput("\n");
109113
+ continue;
109114
+ }
109115
+ if (trimmed.startsWith("/")) {
109116
+ writeOutput(
109117
+ `${dim(`${trimmed.split(" ")[0]} needs the runtime in-process \u2014 not available in attached mode.`)}
109118
+ ${dim("Stop the coordinator and re-run `motebit` to use it.")}
109119
+ `
109120
+ );
109121
+ continue;
109122
+ }
109123
+ const shellTeach = detectShellInvocation(trimmed);
109124
+ if (shellTeach != null) {
109125
+ writeOutput(dim(shellTeach) + "\n\n");
109126
+ continue;
109127
+ }
109128
+ writeOutput(prompt("mote>") + " ");
109129
+ await renderTurn(client, motebitId, client.chat(trimmed));
109130
+ writeOutput("\n");
109131
+ }
109132
+ client.close();
109133
+ destroyTerminal();
109134
+ }
109135
+
109136
+ // src/index.ts
109137
+ init_colors();
109138
+
108518
109139
  // src/subcommands/index.ts
108519
109140
  init_esm_shims();
108520
109141
 
@@ -108647,8 +109268,8 @@ init_dist11();
108647
109268
  init_config2();
108648
109269
  init_identity();
108649
109270
  init_runtime_factory();
108650
- import * as fs7 from "fs";
108651
- import * as path9 from "path";
109271
+ import * as fs8 from "fs";
109272
+ import * as path10 from "path";
108652
109273
  import * as readline2 from "readline";
108653
109274
  async function buildAttestationCredential(input) {
108654
109275
  return composeHardwareAttestationCredential({
@@ -108731,8 +109352,8 @@ async function handleAttest(config) {
108731
109352
  rl.close();
108732
109353
  const json = JSON.stringify(signed, null, 2);
108733
109354
  if (config.output != null && config.output !== "") {
108734
- const outPath = path9.resolve(config.output);
108735
- fs7.writeFileSync(outPath, `${json}
109355
+ const outPath = path10.resolve(config.output);
109356
+ fs8.writeFileSync(outPath, `${json}
108736
109357
  `, "utf-8");
108737
109358
  process.stderr.write(
108738
109359
  `Wrote attestation credential for ${motebitId.slice(0, 8)}\u2026 to ${outPath}
@@ -109386,8 +110007,8 @@ Agent ${data.motebit_id}: found`);
109386
110007
  init_esm_shims();
109387
110008
  init_dist11();
109388
110009
  init_config2();
109389
- import * as fs8 from "fs";
109390
- import * as path10 from "path";
110010
+ import * as fs9 from "fs";
110011
+ import * as path11 from "path";
109391
110012
 
109392
110013
  // src/subcommands/seed.ts
109393
110014
  init_esm_shims();
@@ -109492,26 +110113,26 @@ async function handleDoctor() {
109492
110113
  detail: major >= 20 ? `v${nodeVer}` : `v${nodeVer} (requires >=20)`
109493
110114
  });
109494
110115
  try {
109495
- fs8.mkdirSync(CONFIG_DIR, { recursive: true });
109496
- const testFile = path10.join(CONFIG_DIR, ".doctor-test");
109497
- fs8.writeFileSync(testFile, "ok", "utf-8");
109498
- fs8.unlinkSync(testFile);
110116
+ fs9.mkdirSync(CONFIG_DIR, { recursive: true });
110117
+ const testFile = path11.join(CONFIG_DIR, ".doctor-test");
110118
+ fs9.writeFileSync(testFile, "ok", "utf-8");
110119
+ fs9.unlinkSync(testFile);
109499
110120
  checks.push({ name: "Config dir", ok: true, detail: CONFIG_DIR });
109500
110121
  } catch {
109501
110122
  checks.push({ name: "Config dir", ok: false, detail: `Cannot write to ${CONFIG_DIR}` });
109502
110123
  }
109503
110124
  try {
109504
- const tmpDbPath = path10.join(CONFIG_DIR, ".doctor-test.db");
110125
+ const tmpDbPath = path11.join(CONFIG_DIR, ".doctor-test.db");
109505
110126
  const db = await openMotebitDatabase(tmpDbPath);
109506
110127
  const driverName = db.db.driverName;
109507
110128
  db.close();
109508
- fs8.unlinkSync(tmpDbPath);
110129
+ fs9.unlinkSync(tmpDbPath);
109509
110130
  try {
109510
- fs8.unlinkSync(tmpDbPath + "-wal");
110131
+ fs9.unlinkSync(tmpDbPath + "-wal");
109511
110132
  } catch {
109512
110133
  }
109513
110134
  try {
109514
- fs8.unlinkSync(tmpDbPath + "-shm");
110135
+ fs9.unlinkSync(tmpDbPath + "-shm");
109515
110136
  } catch {
109516
110137
  }
109517
110138
  checks.push({ name: "SQLite", ok: true, detail: `${driverName} loaded and functional` });
@@ -109540,10 +110161,10 @@ async function handleDoctor() {
109540
110161
  checks.push({ name: "Identity", ok: true, detail: "not created yet (run motebit to create)" });
109541
110162
  }
109542
110163
  {
109543
- const mdPath = path10.join(CONFIG_DIR, "motebit.md");
109544
- if (fs8.existsSync(mdPath) && fullCfg.device_public_key) {
110164
+ const mdPath = path11.join(CONFIG_DIR, "motebit.md");
110165
+ if (fs9.existsSync(mdPath) && fullCfg.device_public_key) {
109545
110166
  try {
109546
- const md = fs8.readFileSync(mdPath, "utf-8");
110167
+ const md = fs9.readFileSync(mdPath, "utf-8");
109547
110168
  const keyMatch = /public_key:\s*"?([0-9a-fA-F]{64})"?/.exec(md);
109548
110169
  const fileKey = keyMatch?.[1]?.toLowerCase();
109549
110170
  const stale = fileKey != null && fileKey !== fullCfg.device_public_key.toLowerCase();
@@ -109589,7 +110210,7 @@ async function handleDoctor() {
109589
110210
  detail: "cli_private_key (plaintext, deprecated \u2014 re-encrypt at next run)"
109590
110211
  });
109591
110212
  } else {
109592
- const clobberedBackups = fs8.readdirSync(CONFIG_DIR).filter((f7) => f7.startsWith("config.json.clobbered-"));
110213
+ const clobberedBackups = fs9.readdirSync(CONFIG_DIR).filter((f7) => f7.startsWith("config.json.clobbered-"));
109593
110214
  const restoreHint = clobberedBackups.length > 0 ? `restore from ~/.motebit/${clobberedBackups[0]} (a clobbered backup is present)` : "run `motebit init` to create or import an identity key";
109594
110215
  checks.push({
109595
110216
  name: "Identity key",
@@ -109873,8 +110494,8 @@ init_config2();
109873
110494
  init_identity();
109874
110495
  init_runtime_factory();
109875
110496
  import * as readline4 from "readline";
109876
- import * as fs9 from "fs";
109877
- import * as path11 from "path";
110497
+ import * as fs10 from "fs";
110498
+ import * as path12 from "path";
109878
110499
  async function handleExport(config) {
109879
110500
  const fullConfig = loadFullConfig();
109880
110501
  const rl = readline4.createInterface({
@@ -109948,22 +110569,22 @@ async function handleExport(config) {
109948
110569
  },
109949
110570
  privateKey
109950
110571
  );
109951
- const outputDir = config.output != null && config.output !== "" ? path11.resolve(config.output) : path11.resolve("motebit-export");
109952
- fs9.mkdirSync(outputDir, { recursive: true });
110572
+ const outputDir = config.output != null && config.output !== "" ? path12.resolve(config.output) : path12.resolve("motebit-export");
110573
+ fs10.mkdirSync(outputDir, { recursive: true });
109953
110574
  const exported = [];
109954
110575
  const skipped = [];
109955
- const identityPath = path11.join(outputDir, "motebit.md");
109956
- fs9.writeFileSync(identityPath, identityContent, "utf-8");
110576
+ const identityPath = path12.join(outputDir, "motebit.md");
110577
+ fs10.writeFileSync(identityPath, identityContent, "utf-8");
109957
110578
  exported.push("identity");
109958
110579
  try {
109959
- fs9.writeFileSync(path11.join(CONFIG_DIR, "motebit.md"), identityContent, "utf-8");
110580
+ fs10.writeFileSync(path12.join(CONFIG_DIR, "motebit.md"), identityContent, "utf-8");
109960
110581
  } catch {
109961
110582
  }
109962
110583
  try {
109963
110584
  const latestGradient = moteDb.gradientStore.latest(motebitId);
109964
110585
  if (latestGradient) {
109965
- const gradientPath = path11.join(outputDir, "gradient.json");
109966
- fs9.writeFileSync(gradientPath, JSON.stringify(latestGradient, null, 2), "utf-8");
110586
+ const gradientPath = path12.join(outputDir, "gradient.json");
110587
+ fs10.writeFileSync(gradientPath, JSON.stringify(latestGradient, null, 2), "utf-8");
109967
110588
  exported.push("gradient snapshot");
109968
110589
  } else {
109969
110590
  skipped.push("gradient (no snapshots recorded)");
@@ -109990,8 +110611,8 @@ async function handleExport(config) {
109990
110611
  if (credResult.ok) {
109991
110612
  const credBody = credResult.data;
109992
110613
  const creds = credBody.credentials ?? [];
109993
- const credPath = path11.join(outputDir, "credentials.json");
109994
- fs9.writeFileSync(credPath, JSON.stringify(creds, null, 2), "utf-8");
110614
+ const credPath = path12.join(outputDir, "credentials.json");
110615
+ fs10.writeFileSync(credPath, JSON.stringify(creds, null, 2), "utf-8");
109995
110616
  exported.push(`${creds.length} credential${creds.length !== 1 ? "s" : ""}`);
109996
110617
  } else {
109997
110618
  skipped.push(`credentials (${credResult.error})`);
@@ -110003,8 +110624,8 @@ async function handleExport(config) {
110003
110624
  );
110004
110625
  if (vpResult.ok) {
110005
110626
  const vpBody = vpResult.data;
110006
- const vpPath = path11.join(outputDir, "presentation.json");
110007
- fs9.writeFileSync(vpPath, JSON.stringify(vpBody.presentation ?? vpBody, null, 2), "utf-8");
110627
+ const vpPath = path12.join(outputDir, "presentation.json");
110628
+ fs10.writeFileSync(vpPath, JSON.stringify(vpBody.presentation ?? vpBody, null, 2), "utf-8");
110008
110629
  const credCount = vpBody.credential_count ?? 0;
110009
110630
  exported.push(`presentation (${credCount} credential${credCount !== 1 ? "s" : ""})`);
110010
110631
  } else {
@@ -110012,16 +110633,16 @@ async function handleExport(config) {
110012
110633
  }
110013
110634
  try {
110014
110635
  const ossaManifest = generateOssaManifest(motebitId, publicKeyHex);
110015
- const ossaPath = path11.join(outputDir, "ossa-manifest.yaml");
110016
- fs9.writeFileSync(ossaPath, ossaManifest, "utf-8");
110636
+ const ossaPath = path12.join(outputDir, "ossa-manifest.yaml");
110637
+ fs10.writeFileSync(ossaPath, ossaManifest, "utf-8");
110017
110638
  exported.push("OSSA manifest");
110018
110639
  } catch {
110019
110640
  skipped.push("OSSA manifest (generation failed)");
110020
110641
  }
110021
110642
  const budgetResult = await fetchRelayJson(`${baseUrl}/agent/${motebitId}/budget`, headers);
110022
110643
  if (budgetResult.ok) {
110023
- const budgetPath = path11.join(outputDir, "budget.json");
110024
- fs9.writeFileSync(budgetPath, JSON.stringify(budgetResult.data, null, 2), "utf-8");
110644
+ const budgetPath = path12.join(outputDir, "budget.json");
110645
+ fs10.writeFileSync(budgetPath, JSON.stringify(budgetResult.data, null, 2), "utf-8");
110025
110646
  const budgetData = budgetResult.data;
110026
110647
  const allocCount = budgetData.allocations?.length ?? 0;
110027
110648
  exported.push(`budget (${allocCount} allocation${allocCount !== 1 ? "s" : ""})`);
@@ -110485,8 +111106,8 @@ async function handleGoalSetEnabled(config, enabled2) {
110485
111106
 
110486
111107
  // src/subcommands/init.ts
110487
111108
  init_esm_shims();
110488
- import * as fs10 from "fs";
110489
- import * as path12 from "path";
111109
+ import * as fs11 from "fs";
111110
+ import * as path13 from "path";
110490
111111
  var DEFAULT_PATH = "motebit.yaml";
110491
111112
  var SCAFFOLD = `# motebit.yaml \u2014 declarative config for a motebit.
110492
111113
  #
@@ -110538,14 +111159,14 @@ routines: []
110538
111159
  `;
110539
111160
  function handleInit(config) {
110540
111161
  const targetRelative = config.file ?? DEFAULT_PATH;
110541
- const target = path12.isAbsolute(targetRelative) ? targetRelative : path12.join(process.cwd(), targetRelative);
110542
- if (fs10.existsSync(target) && !config.force) {
111162
+ const target = path13.isAbsolute(targetRelative) ? targetRelative : path13.join(process.cwd(), targetRelative);
111163
+ if (fs11.existsSync(target) && !config.force) {
110543
111164
  console.error(
110544
111165
  `Error: ${target} already exists. Edit it directly, or pass --force to overwrite.`
110545
111166
  );
110546
111167
  process.exit(1);
110547
111168
  }
110548
- fs10.writeFileSync(target, SCAFFOLD, "utf-8");
111169
+ fs11.writeFileSync(target, SCAFFOLD, "utf-8");
110549
111170
  console.log(`Wrote ${target}`);
110550
111171
  console.log("Next: edit the file to declare routines, then run `motebit up`.");
110551
111172
  }
@@ -110767,9 +111388,9 @@ function formatDiagnostic(d6) {
110767
111388
  const pathStr = d6.path.length === 0 ? "" : `${formatPath(d6.path)}: `;
110768
111389
  return `${loc}: ${pathStr}${d6.message}`;
110769
111390
  }
110770
- function formatPath(path19) {
111391
+ function formatPath(path20) {
110771
111392
  const parts = [];
110772
- for (const seg of path19) {
111393
+ for (const seg of path20) {
110773
111394
  if (typeof seg === "number") {
110774
111395
  parts.push(`[${seg}]`);
110775
111396
  } else if (parts.length === 0) {
@@ -110885,7 +111506,7 @@ import { isMap, isSeq, isScalar } from "yaml";
110885
111506
  function findPathAtOffset(doc, offset) {
110886
111507
  return walk(doc.contents, offset, []);
110887
111508
  }
110888
- function walk(node, offset, path19) {
111509
+ function walk(node, offset, path20) {
110889
111510
  if (node == null) return null;
110890
111511
  if (isMap(node)) {
110891
111512
  for (const pair of node.items) {
@@ -110894,30 +111515,30 @@ function walk(node, offset, path19) {
110894
111515
  const keyName = key != null && isScalar(key) ? String(key.value) : null;
110895
111516
  const keyRange = key?.range;
110896
111517
  if (keyRange && offset >= keyRange[0] && offset <= keyRange[1]) {
110897
- return { path: keyName != null ? [...path19, keyName] : path19, onKey: true };
111518
+ return { path: keyName != null ? [...path20, keyName] : path20, onKey: true };
110898
111519
  }
110899
111520
  const valueRange = value?.range;
110900
111521
  if (value && keyName != null && valueRange) {
110901
111522
  if (offset >= valueRange[0] && offset <= valueRange[2]) {
110902
- const inner = walk(value, offset, [...path19, keyName]);
111523
+ const inner = walk(value, offset, [...path20, keyName]);
110903
111524
  if (inner) return inner;
110904
- return { path: [...path19, keyName], onKey: false };
111525
+ return { path: [...path20, keyName], onKey: false };
110905
111526
  }
110906
111527
  }
110907
111528
  }
110908
- return path19.length > 0 ? { path: path19, onKey: false } : null;
111529
+ return path20.length > 0 ? { path: path20, onKey: false } : null;
110909
111530
  }
110910
111531
  if (isSeq(node)) {
110911
111532
  for (let i = 0; i < node.items.length; i++) {
110912
111533
  const item = node.items[i];
110913
111534
  const range = item?.range;
110914
111535
  if (range && offset >= range[0] && offset <= range[2]) {
110915
- const inner = walk(item, offset, [...path19, i]);
111536
+ const inner = walk(item, offset, [...path20, i]);
110916
111537
  if (inner) return inner;
110917
- return { path: [...path19, i], onKey: false };
111538
+ return { path: [...path20, i], onKey: false };
110918
111539
  }
110919
111540
  }
110920
- return path19.length > 0 ? { path: path19, onKey: false } : null;
111541
+ return path20.length > 0 ? { path: path20, onKey: false } : null;
110921
111542
  }
110922
111543
  return null;
110923
111544
  }
@@ -110950,9 +111571,9 @@ function findDescription(schema) {
110950
111571
  cur = next;
110951
111572
  }
110952
111573
  }
110953
- function resolvePath(schema, path19) {
111574
+ function resolvePath(schema, path20) {
110954
111575
  let cur = schema;
110955
- for (const seg of path19) {
111576
+ for (const seg of path20) {
110956
111577
  const inner = unwrapAll(cur);
110957
111578
  if (inner instanceof z44.ZodObject) {
110958
111579
  const shape = inner.shape;
@@ -110969,8 +111590,8 @@ function resolvePath(schema, path19) {
110969
111590
  }
110970
111591
  return cur;
110971
111592
  }
110972
- function objectKeys(schema, path19) {
110973
- const target = resolvePath(schema, path19);
111593
+ function objectKeys(schema, path20) {
111594
+ const target = resolvePath(schema, path20);
110974
111595
  if (target == null) return [];
110975
111596
  const inner = unwrapAll(target);
110976
111597
  if (inner instanceof z44.ZodObject) {
@@ -110984,8 +111605,8 @@ function objectKeys(schema, path19) {
110984
111605
  }
110985
111606
  return [];
110986
111607
  }
110987
- function enumValues(schema, path19) {
110988
- const target = resolvePath(schema, path19);
111608
+ function enumValues(schema, path20) {
111609
+ const target = resolvePath(schema, path20);
110989
111610
  if (target == null) return null;
110990
111611
  const inner = unwrapAll(target);
110991
111612
  if (inner instanceof z44.ZodEnum) {
@@ -111050,9 +111671,9 @@ async function computeDiagnostics(doc) {
111050
111671
  }
111051
111672
  return diagnostics;
111052
111673
  }
111053
- function formatPath2(path19) {
111674
+ function formatPath2(path20) {
111054
111675
  const parts = [];
111055
- for (const seg of path19) {
111676
+ for (const seg of path20) {
111056
111677
  if (typeof seg === "number") {
111057
111678
  parts.push(`[${seg}]`);
111058
111679
  } else if (parts.length === 0) {
@@ -111145,14 +111766,14 @@ function inferParentPath(lines, currentLine, currentIndent) {
111145
111766
  stack.unshift({ indent: effectiveIndent, key, isArray: arrayBullet });
111146
111767
  if (effectiveIndent === 0) break;
111147
111768
  }
111148
- const path19 = [];
111769
+ const path20 = [];
111149
111770
  for (let i = 0; i < stack.length; i++) {
111150
111771
  const cur = stack[i];
111151
- path19.push(cur.key);
111772
+ path20.push(cur.key);
111152
111773
  const next = stack[i + 1];
111153
- if (next && next.isArray) path19.push(0);
111774
+ if (next && next.isArray) path20.push(0);
111154
111775
  }
111155
- return path19;
111776
+ return path20;
111156
111777
  }
111157
111778
 
111158
111779
  // src/subcommands/lsp.ts
@@ -111210,8 +111831,8 @@ init_dist25();
111210
111831
  init_dist11();
111211
111832
  init_config2();
111212
111833
  init_runtime_factory();
111213
- import * as fs11 from "fs";
111214
- import * as path13 from "path";
111834
+ import * as fs12 from "fs";
111835
+ import * as path14 from "path";
111215
111836
  async function handleUp(config) {
111216
111837
  const yamlPath = resolveYamlPath(config.file);
111217
111838
  if (yamlPath == null) {
@@ -111246,7 +111867,7 @@ async function handleUp(config) {
111246
111867
  console.log("\nApplied.");
111247
111868
  }
111248
111869
  async function applyMotebitYaml(opts) {
111249
- const raw = fs11.readFileSync(opts.yamlPath, "utf-8");
111870
+ const raw = fs12.readFileSync(opts.yamlPath, "utf-8");
111250
111871
  const parsed = await parseMotebitYaml(raw, opts.yamlPath);
111251
111872
  if (!parsed.ok) {
111252
111873
  return { kind: "parse_error", diagnostics: parsed.diagnostics };
@@ -111407,14 +112028,14 @@ function printPlan(plan, opts) {
111407
112028
  }
111408
112029
  function resolveYamlPath(explicit) {
111409
112030
  if (explicit != null && explicit !== "") {
111410
- const abs = path13.isAbsolute(explicit) ? explicit : path13.resolve(explicit);
111411
- return fs11.existsSync(abs) ? abs : null;
112031
+ const abs = path14.isAbsolute(explicit) ? explicit : path14.resolve(explicit);
112032
+ return fs12.existsSync(abs) ? abs : null;
111412
112033
  }
111413
112034
  let dir = process.cwd();
111414
112035
  for (; ; ) {
111415
- const candidate = path13.join(dir, "motebit.yaml");
111416
- if (fs11.existsSync(candidate)) return candidate;
111417
- const parent = path13.dirname(dir);
112036
+ const candidate = path14.join(dir, "motebit.yaml");
112037
+ if (fs12.existsSync(candidate)) return candidate;
112038
+ const parent = path14.dirname(dir);
111418
112039
  if (parent === dir) return null;
111419
112040
  dir = parent;
111420
112041
  }
@@ -111675,8 +112296,8 @@ init_esm_shims();
111675
112296
  init_dist6();
111676
112297
  init_config2();
111677
112298
  init_identity();
111678
- import * as fs12 from "fs";
111679
- import * as path14 from "path";
112299
+ import * as fs13 from "fs";
112300
+ import * as path15 from "path";
111680
112301
  async function handleMigrateKeyring(config) {
111681
112302
  const force = config.force === true;
111682
112303
  const fullConfig = loadFullConfig();
@@ -111692,8 +112313,8 @@ async function handleMigrateKeyring(config) {
111692
112313
  );
111693
112314
  process.exit(1);
111694
112315
  }
111695
- const devKeyringPath = path14.join(CONFIG_DIR, "dev-keyring.json");
111696
- if (!fs12.existsSync(devKeyringPath)) {
112316
+ const devKeyringPath = path15.join(CONFIG_DIR, "dev-keyring.json");
112317
+ if (!fs13.existsSync(devKeyringPath)) {
111697
112318
  console.error(`Error: no plaintext keyring at ${devKeyringPath}.`);
111698
112319
  console.error(
111699
112320
  " This subcommand recovers from configs where cli_encrypted_key was lost\n but a plaintext key remains on disk. If you have neither, run\n `motebit` (no args) to create a fresh identity."
@@ -111702,7 +112323,7 @@ async function handleMigrateKeyring(config) {
111702
112323
  }
111703
112324
  let devKeyring;
111704
112325
  try {
111705
- const raw = fs12.readFileSync(devKeyringPath, "utf-8");
112326
+ const raw = fs13.readFileSync(devKeyringPath, "utf-8");
111706
112327
  devKeyring = JSON.parse(raw);
111707
112328
  } catch (err2) {
111708
112329
  console.error(
@@ -111768,9 +112389,9 @@ async function handleMigrateKeyring(config) {
111768
112389
  saveFullConfig(fullConfig);
111769
112390
  secureErase(privateKeyBytes);
111770
112391
  try {
111771
- const stat = fs12.statSync(devKeyringPath);
111772
- fs12.writeFileSync(devKeyringPath, "0".repeat(Math.min(stat.size, 4096)));
111773
- fs12.unlinkSync(devKeyringPath);
112392
+ const stat = fs13.statSync(devKeyringPath);
112393
+ fs13.writeFileSync(devKeyringPath, "0".repeat(Math.min(stat.size, 4096)));
112394
+ fs13.unlinkSync(devKeyringPath);
111774
112395
  } catch (err2) {
111775
112396
  console.warn(
111776
112397
  `Warning: could not remove ${devKeyringPath} (${err2 instanceof Error ? err2.message : String(err2)}).`
@@ -112153,7 +112774,7 @@ init_dist6();
112153
112774
  init_config2();
112154
112775
  init_identity();
112155
112776
  init_colors();
112156
- import * as fs13 from "fs";
112777
+ import * as fs14 from "fs";
112157
112778
  import * as readline5 from "readline";
112158
112779
  var IDENTITY_SUITE = "motebit-jcs-ed25519-hex-v1";
112159
112780
  function askVisible(prompt2) {
@@ -112179,7 +112800,7 @@ async function handleRestore(config) {
112179
112800
  let mdContent = null;
112180
112801
  if (mdPath != null) {
112181
112802
  try {
112182
- mdContent = fs13.readFileSync(mdPath, "utf-8");
112803
+ mdContent = fs14.readFileSync(mdPath, "utf-8");
112183
112804
  } catch (err2) {
112184
112805
  console.error(`Cannot read ${mdPath}: ${err2 instanceof Error ? err2.message : String(err2)}`);
112185
112806
  process.exit(1);
@@ -112371,7 +112992,7 @@ async function handleKeychain(config) {
112371
112992
 
112372
112993
  // src/subcommands/relay.ts
112373
112994
  init_esm_shims();
112374
- import * as fs14 from "fs";
112995
+ import * as fs15 from "fs";
112375
112996
  import { serve } from "@hono/node-server";
112376
112997
 
112377
112998
  // ../../services/relay/dist/index.js
@@ -120974,7 +121595,7 @@ function resolveRelayDbPath(override) {
120974
121595
  if (override != null && override !== "") return override;
120975
121596
  const envPath = process.env["MOTEBIT_RELAY_DB_PATH"];
120976
121597
  if (envPath != null && envPath !== "") return envPath;
120977
- fs14.mkdirSync(RELAY_DIR, { recursive: true });
121598
+ fs15.mkdirSync(RELAY_DIR, { recursive: true });
120978
121599
  return RELAY_DB_PATH;
120979
121600
  }
120980
121601
  async function resolveOptions2(config) {
@@ -121108,22 +121729,22 @@ init_dist6();
121108
121729
  init_config2();
121109
121730
  init_identity();
121110
121731
  import * as readline6 from "readline";
121111
- import * as fs15 from "fs";
121112
- import * as path15 from "path";
121732
+ import * as fs16 from "fs";
121733
+ import * as path16 from "path";
121113
121734
  function discoverIdentityFile() {
121114
121735
  let dir = process.cwd();
121115
- const root = path15.parse(dir).root;
121116
- let parent = path15.dirname(dir);
121736
+ const root = path16.parse(dir).root;
121737
+ let parent = path16.dirname(dir);
121117
121738
  while (dir !== parent && dir !== root) {
121118
- const candidate = path15.join(dir, "motebit.md");
121119
- if (fs15.existsSync(candidate)) return candidate;
121739
+ const candidate = path16.join(dir, "motebit.md");
121740
+ if (fs16.existsSync(candidate)) return candidate;
121120
121741
  dir = parent;
121121
- parent = path15.dirname(dir);
121742
+ parent = path16.dirname(dir);
121122
121743
  }
121123
- const rootCandidate = path15.join(root, "motebit.md");
121124
- if (fs15.existsSync(rootCandidate)) return rootCandidate;
121125
- const homeCandidate = path15.join(CONFIG_DIR, "identity.md");
121126
- if (fs15.existsSync(homeCandidate)) return homeCandidate;
121744
+ const rootCandidate = path16.join(root, "motebit.md");
121745
+ if (fs16.existsSync(rootCandidate)) return rootCandidate;
121746
+ const homeCandidate = path16.join(CONFIG_DIR, "identity.md");
121747
+ if (fs16.existsSync(homeCandidate)) return homeCandidate;
121127
121748
  return null;
121128
121749
  }
121129
121750
  async function handleRotate(config) {
@@ -121138,7 +121759,7 @@ async function handleRotate(config) {
121138
121759
  Identity file: ${identityPath}`);
121139
121760
  let existingContent;
121140
121761
  try {
121141
- existingContent = fs15.readFileSync(identityPath, "utf-8");
121762
+ existingContent = fs16.readFileSync(identityPath, "utf-8");
121142
121763
  } catch (err2) {
121143
121764
  const msg = err2 instanceof Error ? err2.message : String(err2);
121144
121765
  console.error(`Error: cannot read identity file: ${msg}`);
@@ -121209,7 +121830,7 @@ Identity file: ${identityPath}`);
121209
121830
  rl.close();
121210
121831
  process.exit(1);
121211
121832
  }
121212
- fs15.writeFileSync(identityPath, rotatedContent, "utf-8");
121833
+ fs16.writeFileSync(identityPath, rotatedContent, "utf-8");
121213
121834
  console.log(" Identity file: updated and re-signed");
121214
121835
  fullConfig.cli_encrypted_key = await encryptPrivateKey(
121215
121836
  bytesToHex4(rotateResult.newPrivateKey),
@@ -121401,12 +122022,12 @@ init_esm_shims();
121401
122022
  init_dist6();
121402
122023
  init_config2();
121403
122024
  import * as crypto3 from "crypto";
121404
- import * as fs16 from "fs";
121405
- import * as path16 from "path";
122025
+ import * as fs17 from "fs";
122026
+ import * as path17 from "path";
121406
122027
  var SMOKE_UNIT_COST_USD = 0.01;
121407
122028
  var SMOKE_CAPABILITY = "echo";
121408
- var BUYER_EOA_FILE = path16.join(CONFIG_DIR, "smoke-x402-buyer-eoa.txt");
121409
- var WORKER_EOA_FILE = path16.join(CONFIG_DIR, "smoke-x402-worker-eoa.txt");
122029
+ var BUYER_EOA_FILE = path17.join(CONFIG_DIR, "smoke-x402-buyer-eoa.txt");
122030
+ var WORKER_EOA_FILE = path17.join(CONFIG_DIR, "smoke-x402-worker-eoa.txt");
121410
122031
  var USDC_CONTRACTS2 = {
121411
122032
  mainnet: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
121412
122033
  testnet: "0x036CbD53842c5426634e7929541eC2318f3dCF7e"
@@ -121484,8 +122105,8 @@ async function handleSmokeX402(config) {
121484
122105
  }
121485
122106
  async function loadOrGenerateEoa(filePath, label) {
121486
122107
  const { generatePrivateKey, privateKeyToAccount } = await import("viem/accounts");
121487
- if (fs16.existsSync(filePath)) {
121488
- const privateKey2 = fs16.readFileSync(filePath, "utf-8").trim();
122108
+ if (fs17.existsSync(filePath)) {
122109
+ const privateKey2 = fs17.readFileSync(filePath, "utf-8").trim();
121489
122110
  if (!/^0x[0-9a-f]{64}$/i.test(privateKey2)) {
121490
122111
  throw new Error(
121491
122112
  `${filePath} is not a valid EOA private key (expected 0x + 64 hex). Delete the file to regenerate.`
@@ -121494,9 +122115,9 @@ async function loadOrGenerateEoa(filePath, label) {
121494
122115
  const account2 = privateKeyToAccount(privateKey2);
121495
122116
  return { address: account2.address, privateKey: privateKey2, justGenerated: false };
121496
122117
  }
121497
- fs16.mkdirSync(path16.dirname(filePath), { recursive: true });
122118
+ fs17.mkdirSync(path17.dirname(filePath), { recursive: true });
121498
122119
  const privateKey = generatePrivateKey();
121499
- fs16.writeFileSync(filePath, privateKey, { mode: 384 });
122120
+ fs17.writeFileSync(filePath, privateKey, { mode: 384 });
121500
122121
  const account = privateKeyToAccount(privateKey);
121501
122122
  console.log(`Generated ${label} EOA at ${filePath} (mode 0600)`);
121502
122123
  return { address: account.address, privateKey, justGenerated: true };
@@ -121721,13 +122342,13 @@ init_colors();
121721
122342
  import {
121722
122343
  appendFileSync,
121723
122344
  existsSync as existsSync10,
121724
- mkdirSync as mkdirSync11,
121725
- readFileSync as readFileSync13,
122345
+ mkdirSync as mkdirSync12,
122346
+ readFileSync as readFileSync14,
121726
122347
  readdirSync as readdirSync4,
121727
122348
  statSync as statSync4,
121728
- writeFileSync as writeFileSync15
122349
+ writeFileSync as writeFileSync16
121729
122350
  } from "fs";
121730
- import { isAbsolute as isAbsolute3, join as join18, resolve as resolve10 } from "path";
122351
+ import { isAbsolute as isAbsolute3, join as join19, resolve as resolve10 } from "path";
121731
122352
  import * as readline7 from "readline";
121732
122353
  var DEFAULT_RELAY_URL = "https://relay.motebit.com";
121733
122354
  var REGISTRY_ADDRESS_RE = /^did:key:z[1-9A-HJ-NP-Za-km-z]+\/[a-z0-9-]+@[^/]+$/;
@@ -121747,15 +122368,15 @@ function resolveRelayUrl() {
121747
122368
  var SKILLS_DIR_NAME = "skills";
121748
122369
  var AUDIT_LOG_NAME = "audit.log";
121749
122370
  function getSkillsRoot() {
121750
- return join18(CONFIG_DIR, SKILLS_DIR_NAME);
122371
+ return join19(CONFIG_DIR, SKILLS_DIR_NAME);
121751
122372
  }
121752
122373
  function getAuditLogPath() {
121753
- return join18(getSkillsRoot(), AUDIT_LOG_NAME);
122374
+ return join19(getSkillsRoot(), AUDIT_LOG_NAME);
121754
122375
  }
121755
122376
  function makeAuditSink() {
121756
122377
  return (event) => {
121757
122378
  const root = getSkillsRoot();
121758
- if (!existsSync10(root)) mkdirSync11(root, { recursive: true });
122379
+ if (!existsSync10(root)) mkdirSync12(root, { recursive: true });
121759
122380
  appendFileSync(getAuditLogPath(), JSON.stringify(event) + "\n", "utf-8");
121760
122381
  };
121761
122382
  }
@@ -121793,18 +122414,18 @@ async function handleSkillsInstall(config) {
121793
122414
  await installFromDirectory(config, sourceArg);
121794
122415
  }
121795
122416
  async function installFromDirectory(config, sourceArg) {
121796
- const path19 = isAbsolute3(sourceArg) ? sourceArg : resolve10(process.cwd(), sourceArg);
122417
+ const path20 = isAbsolute3(sourceArg) ? sourceArg : resolve10(process.cwd(), sourceArg);
121797
122418
  let stat;
121798
122419
  try {
121799
- stat = statSync4(path19);
122420
+ stat = statSync4(path20);
121800
122421
  } catch {
121801
- console.error(error2(`No such path: ${path19}`));
122422
+ console.error(error2(`No such path: ${path20}`));
121802
122423
  process.exit(1);
121803
122424
  }
121804
122425
  if (!stat.isDirectory()) {
121805
122426
  console.error(
121806
122427
  error2(
121807
- `Source must be a directory containing SKILL.md and skill-envelope.json. Got: ${path19}`
122428
+ `Source must be a directory containing SKILL.md and skill-envelope.json. Got: ${path20}`
121808
122429
  )
121809
122430
  );
121810
122431
  console.error(dim("(git+ssh install sources land in phase 2.)"));
@@ -121812,13 +122433,13 @@ async function installFromDirectory(config, sourceArg) {
121812
122433
  }
121813
122434
  let installSource;
121814
122435
  try {
121815
- installSource = resolveDirectorySkillSource(path19);
122436
+ installSource = resolveDirectorySkillSource(path20);
121816
122437
  } catch (err2) {
121817
- console.error(error2(`Failed to read skill at ${path19}:`));
122438
+ console.error(error2(`Failed to read skill at ${path20}:`));
121818
122439
  console.error(` ${err2 instanceof Error ? err2.message : String(err2)}`);
121819
122440
  process.exit(1);
121820
122441
  }
121821
- await runInstall(config, installSource, `directory:${path19}`, path19);
122442
+ await runInstall(config, installSource, `directory:${path20}`, path20);
121822
122443
  }
121823
122444
  async function installFromRelay(config, rawAddress, parsed) {
121824
122445
  const relayUrl = resolveRelayUrl().replace(/\/$/, "");
@@ -121894,8 +122515,8 @@ async function installFromRelay(config, rawAddress, parsed) {
121894
122515
  const bodyBytes = base64Decode2(bundle.body);
121895
122516
  const fileBytes = {};
121896
122517
  if (bundle.files) {
121897
- for (const [path19, b64] of Object.entries(bundle.files)) {
121898
- fileBytes[path19] = base64Decode2(b64);
122518
+ for (const [path20, b64] of Object.entries(bundle.files)) {
122519
+ fileBytes[path20] = base64Decode2(b64);
121899
122520
  }
121900
122521
  }
121901
122522
  const installSource = {
@@ -122091,9 +122712,9 @@ function parseAuditFilters(config) {
122091
122712
  return { skillName, type, limit, json: config.json };
122092
122713
  }
122093
122714
  function readAuditEvents() {
122094
- const path19 = getAuditLogPath();
122095
- if (!existsSync10(path19)) return [];
122096
- const text = readFileSync13(path19, "utf-8");
122715
+ const path20 = getAuditLogPath();
122716
+ if (!existsSync10(path20)) return [];
122717
+ const text = readFileSync14(path20, "utf-8");
122097
122718
  const events = [];
122098
122719
  for (const line of text.split("\n")) {
122099
122720
  const trimmed = line.trim();
@@ -122255,8 +122876,8 @@ async function handleSkillsRunScript(config) {
122255
122876
  const { mkdtempSync, writeFileSync: writeBytes, chmodSync: chmodSync3, rmSync: rmSync3 } = await import("fs");
122256
122877
  const { tmpdir: tmpdir2 } = await import("os");
122257
122878
  const { spawnSync: spawnSync2 } = await import("child_process");
122258
- const tempDir = mkdtempSync(join18(tmpdir2(), "motebit-skill-script-"));
122259
- const tempPath = join18(tempDir, scriptName);
122879
+ const tempDir = mkdtempSync(join19(tmpdir2(), "motebit-skill-script-"));
122880
+ const tempPath = join19(tempDir, scriptName);
122260
122881
  try {
122261
122882
  writeBytes(tempPath, Buffer.from(scriptBytes));
122262
122883
  chmodSync3(tempPath, 448);
@@ -122326,17 +122947,17 @@ function collectAuxFiles2(skillDir) {
122326
122947
  function walk2(current2, base) {
122327
122948
  const entries = readdirSync4(current2, { withFileTypes: true });
122328
122949
  for (const entry of entries) {
122329
- const full = join18(current2, entry.name);
122950
+ const full = join19(current2, entry.name);
122330
122951
  if (entry.isDirectory()) {
122331
122952
  walk2(full, base);
122332
122953
  } else if (entry.isFile()) {
122333
122954
  const rel = full.slice(base.length + 1).split(/[\\/]+/).join("/");
122334
- out[rel] = readFileSync13(full);
122955
+ out[rel] = readFileSync14(full);
122335
122956
  }
122336
122957
  }
122337
122958
  }
122338
122959
  for (const subdir of AUX_DIRS2) {
122339
- const subdirPath = join18(skillDir, subdir);
122960
+ const subdirPath = join19(skillDir, subdir);
122340
122961
  if (existsSync10(subdirPath)) walk2(subdirPath, skillDir);
122341
122962
  }
122342
122963
  return out;
@@ -122387,12 +123008,12 @@ async function loadIdentityKey() {
122387
123008
  };
122388
123009
  }
122389
123010
  async function signSkillDirectory(skillDir, privateKey, publicKey) {
122390
- const skillMdPath = join18(skillDir, SKILL_MD_NAME);
123011
+ const skillMdPath = join19(skillDir, SKILL_MD_NAME);
122391
123012
  if (!existsSync10(skillMdPath)) {
122392
123013
  console.error(error2(` No SKILL.md at ${skillMdPath}`));
122393
123014
  process.exit(1);
122394
123015
  }
122395
- const text = readFileSync13(skillMdPath, "utf-8");
123016
+ const text = readFileSync14(skillMdPath, "utf-8");
122396
123017
  const parsed = parseSkillFile(text);
122397
123018
  const body = parsed.body;
122398
123019
  const motebitNoSig = { ...parsed.manifest.motebit };
@@ -122411,7 +123032,7 @@ async function signSkillDirectory(skillDir, privateKey, publicKey) {
122411
123032
  const bodyHash = await hash(body);
122412
123033
  const auxFiles = collectAuxFiles2(skillDir);
122413
123034
  const filesEntries = await Promise.all(
122414
- Object.entries(auxFiles).sort(([a4], [b5]) => a4.localeCompare(b5)).map(async ([path19, bytes]) => ({ path: path19, hash: await hash(bytes) }))
123035
+ Object.entries(auxFiles).sort(([a4], [b5]) => a4.localeCompare(b5)).map(async ([path20, bytes]) => ({ path: path20, hash: await hash(bytes) }))
122415
123036
  );
122416
123037
  const signedEnvelope = await signSkillEnvelope(
122417
123038
  {
@@ -122429,9 +123050,9 @@ async function signSkillDirectory(skillDir, privateKey, publicKey) {
122429
123050
  publicKey
122430
123051
  );
122431
123052
  const skillMdContent = serializeSkillFile(signedManifest, body);
122432
- writeFileSync15(skillMdPath, skillMdContent);
122433
- writeFileSync15(
122434
- join18(skillDir, SKILL_ENVELOPE_JSON_NAME),
123053
+ writeFileSync16(skillMdPath, skillMdContent);
123054
+ writeFileSync16(
123055
+ join19(skillDir, SKILL_ENVELOPE_JSON_NAME),
122435
123056
  JSON.stringify(signedEnvelope, null, 2) + "\n"
122436
123057
  );
122437
123058
  return { envelope: signedEnvelope, manifest: signedManifest, body };
@@ -122461,8 +123082,8 @@ async function handleSkillsPublish(config) {
122461
123082
  }
122462
123083
  const auxFiles = collectAuxFiles2(skillDir);
122463
123084
  const filesPayload = {};
122464
- for (const [path19, bytes] of Object.entries(auxFiles)) {
122465
- filesPayload[path19] = bytesToBase64(bytes);
123085
+ for (const [path20, bytes] of Object.entries(auxFiles)) {
123086
+ filesPayload[path20] = bytesToBase64(bytes);
122466
123087
  }
122467
123088
  const submission = {
122468
123089
  envelope,
@@ -122508,8 +123129,8 @@ async function handleSkillsPublish(config) {
122508
123129
  init_esm_shims();
122509
123130
  init_dist34();
122510
123131
  init_dist6();
122511
- import * as fs17 from "fs";
122512
- import * as path17 from "path";
123132
+ import * as fs18 from "fs";
123133
+ import * as path18 from "path";
122513
123134
  function tryParseJson(text) {
122514
123135
  try {
122515
123136
  return JSON.parse(text);
@@ -122520,7 +123141,7 @@ function tryParseJson(text) {
122520
123141
  function readJsonFile(filePath) {
122521
123142
  let raw;
122522
123143
  try {
122523
- raw = fs17.readFileSync(filePath, "utf-8");
123144
+ raw = fs18.readFileSync(filePath, "utf-8");
122524
123145
  } catch {
122525
123146
  return { ok: false, error: "file not found" };
122526
123147
  }
@@ -122553,10 +123174,10 @@ function extractSubjectMotebitId(vc) {
122553
123174
  return typeof subject.id === "string" ? subject.id : null;
122554
123175
  }
122555
123176
  async function handleVerify(filePath) {
122556
- const resolved = path17.resolve(filePath);
123177
+ const resolved = path18.resolve(filePath);
122557
123178
  let stat;
122558
123179
  try {
122559
- stat = fs17.statSync(resolved);
123180
+ stat = fs18.statSync(resolved);
122560
123181
  } catch {
122561
123182
  console.error(`Error: path does not exist: ${resolved}`);
122562
123183
  process.exit(1);
@@ -122581,7 +123202,7 @@ async function handleVerify(filePath) {
122581
123202
  async function verifySingleIdentityFile(filePath) {
122582
123203
  let content;
122583
123204
  try {
122584
- content = fs17.readFileSync(filePath, "utf-8");
123205
+ content = fs18.readFileSync(filePath, "utf-8");
122585
123206
  } catch {
122586
123207
  console.error(`Error: cannot read file: ${filePath}`);
122587
123208
  process.exit(1);
@@ -122674,16 +123295,16 @@ Verifying ${data.length} credential${data.length !== 1 ? "s" : ""}...
122674
123295
  }
122675
123296
  async function verifyBundle(dirPath) {
122676
123297
  console.log(`
122677
- Verifying ${path17.basename(dirPath)}/...
123298
+ Verifying ${path18.basename(dirPath)}/...
122678
123299
  `);
122679
123300
  let passed = true;
122680
123301
  let motebitId = null;
122681
123302
  let identityDid = null;
122682
- const identityPath = path17.join(dirPath, "motebit.md");
122683
- if (fs17.existsSync(identityPath)) {
123303
+ const identityPath = path18.join(dirPath, "motebit.md");
123304
+ if (fs18.existsSync(identityPath)) {
122684
123305
  let content;
122685
123306
  try {
122686
- content = fs17.readFileSync(identityPath, "utf-8");
123307
+ content = fs18.readFileSync(identityPath, "utf-8");
122687
123308
  } catch {
122688
123309
  console.log(` Identity (motebit.md): FAILED \u2014 cannot read file`);
122689
123310
  passed = false;
@@ -122705,9 +123326,9 @@ Verifying ${path17.basename(dirPath)}/...
122705
123326
  } else {
122706
123327
  console.log(` Identity (motebit.md): not found, skipping`);
122707
123328
  }
122708
- const credsPath = path17.join(dirPath, "credentials.json");
123329
+ const credsPath = path18.join(dirPath, "credentials.json");
122709
123330
  const credentials = [];
122710
- if (fs17.existsSync(credsPath)) {
123331
+ if (fs18.existsSync(credsPath)) {
122711
123332
  const credResult = readJsonFile(credsPath);
122712
123333
  if (!credResult.ok) {
122713
123334
  console.log(` Credentials: FAILED \u2014 ${credResult.error}`);
@@ -122750,8 +123371,8 @@ Verifying ${path17.basename(dirPath)}/...
122750
123371
  } else {
122751
123372
  console.log(` Credentials: not found, skipping`);
122752
123373
  }
122753
- const vpPath = path17.join(dirPath, "presentation.json");
122754
- if (fs17.existsSync(vpPath)) {
123374
+ const vpPath = path18.join(dirPath, "presentation.json");
123375
+ if (fs18.existsSync(vpPath)) {
122755
123376
  const vpResult = readJsonFile(vpPath);
122756
123377
  if (!vpResult.ok) {
122757
123378
  console.log(` Presentation: FAILED \u2014 ${vpResult.error}`);
@@ -122800,8 +123421,8 @@ Verifying ${path17.basename(dirPath)}/...
122800
123421
  passed = false;
122801
123422
  }
122802
123423
  }
122803
- const budgetPath = path17.join(dirPath, "budget.json");
122804
- if (fs17.existsSync(budgetPath)) {
123424
+ const budgetPath = path18.join(dirPath, "budget.json");
123425
+ if (fs18.existsSync(budgetPath)) {
122805
123426
  const budgetResult = readJsonFile(budgetPath);
122806
123427
  if (!budgetResult.ok) {
122807
123428
  console.log(` Budget: FAILED \u2014 ${budgetResult.error}`);
@@ -122823,8 +123444,8 @@ Verifying ${path17.basename(dirPath)}/...
122823
123444
  } else {
122824
123445
  console.log(` Budget: not found, skipping`);
122825
123446
  }
122826
- const gradientPath = path17.join(dirPath, "gradient.json");
122827
- if (fs17.existsSync(gradientPath)) {
123447
+ const gradientPath = path18.join(dirPath, "gradient.json");
123448
+ if (fs18.existsSync(gradientPath)) {
122828
123449
  const gradientResult = readJsonFile(gradientPath);
122829
123450
  if (!gradientResult.ok) {
122830
123451
  console.log(` Gradient: FAILED \u2014 ${gradientResult.error}`);
@@ -122851,7 +123472,7 @@ init_esm_shims();
122851
123472
  init_dist6();
122852
123473
  init_dist31();
122853
123474
  init_colors();
122854
- import { readFileSync as readFileSync15 } from "fs";
123475
+ import { readFileSync as readFileSync16 } from "fs";
122855
123476
  import { resolve as resolve12 } from "path";
122856
123477
  var KIND_KEYWORDS = /* @__PURE__ */ new Set(["receipt", "token", "listing"]);
122857
123478
  function isVerifyKind(s3) {
@@ -122862,7 +123483,7 @@ async function verifyWire(kind, filePath, now = Date.now()) {
122862
123483
  const absPath = resolve12(filePath);
122863
123484
  let raw;
122864
123485
  try {
122865
- const text = readFileSync15(absPath, "utf-8");
123486
+ const text = readFileSync16(absPath, "utf-8");
122866
123487
  raw = JSON.parse(text);
122867
123488
  checks.push({ name: "json", ok: true, detail: `parsed ${text.length} bytes` });
122868
123489
  } catch (err2) {
@@ -122986,7 +123607,7 @@ async function handleVerifyWire(kindArg, pathArg, opts) {
122986
123607
  // src/subcommands/verify-release.ts
122987
123608
  init_esm_shims();
122988
123609
  import { createHash as createHash3 } from "crypto";
122989
- import { readFileSync as readFileSync16 } from "fs";
123610
+ import { readFileSync as readFileSync17 } from "fs";
122990
123611
  init_config2();
122991
123612
  init_config2();
122992
123613
  async function handleVerifyRelease(options = {}) {
@@ -123000,7 +123621,7 @@ async function handleVerifyRelease(options = {}) {
123000
123621
  }
123001
123622
  let selfHash;
123002
123623
  try {
123003
- selfHash = createHash3("sha256").update(readFileSync16(bundlePath)).digest("hex");
123624
+ selfHash = createHash3("sha256").update(readFileSync17(bundlePath)).digest("hex");
123004
123625
  } catch (err2) {
123005
123626
  console.error(
123006
123627
  `verify-release: cannot read own bytes at ${bundlePath}: ${err2 instanceof Error ? err2.message : String(err2)}`
@@ -123065,8 +123686,8 @@ init_dist22();
123065
123686
  init_dist2();
123066
123687
  init_dist6();
123067
123688
  init_dist34();
123068
- import * as fs18 from "fs";
123069
- import * as path18 from "path";
123689
+ import * as fs19 from "fs";
123690
+ import * as path19 from "path";
123070
123691
  init_dist10();
123071
123692
  init_dist13();
123072
123693
 
@@ -123958,10 +124579,10 @@ async function publishServiceListing(syncUrl, motebitId, headers, toolNames, pri
123958
124579
  }
123959
124580
  async function handleRun(config) {
123960
124581
  const explicitIdentity = config.identity != null && config.identity !== "";
123961
- const identityPath = explicitIdentity ? path18.resolve(config.identity) : path18.resolve("motebit.md");
124582
+ const identityPath = explicitIdentity ? path19.resolve(config.identity) : path19.resolve("motebit.md");
123962
124583
  let identityContent;
123963
124584
  try {
123964
- identityContent = fs18.readFileSync(identityPath, "utf-8");
124585
+ identityContent = fs19.readFileSync(identityPath, "utf-8");
123965
124586
  } catch {
123966
124587
  if (explicitIdentity) {
123967
124588
  console.error(`Error: cannot read identity file: ${identityPath}`);
@@ -124075,7 +124696,7 @@ async function handleRun(config) {
124075
124696
  if (watchedYaml != null) {
124076
124697
  console.log(`Watching ${watchedYaml} \u2014 changes will re-apply automatically.`);
124077
124698
  try {
124078
- fs18.watch(watchedYaml, () => {
124699
+ fs19.watch(watchedYaml, () => {
124079
124700
  if (yamlDebounce) clearTimeout(yamlDebounce);
124080
124701
  yamlDebounce = setTimeout(() => {
124081
124702
  void (async () => {
@@ -124555,10 +125176,10 @@ async function handleServe(config) {
124555
125176
  let guardianAttestation;
124556
125177
  let policyOverrides = {};
124557
125178
  if (config.identity != null && config.identity !== "") {
124558
- const identityPath = path18.resolve(config.identity);
125179
+ const identityPath = path19.resolve(config.identity);
124559
125180
  let identityContent;
124560
125181
  try {
124561
- identityContent = fs18.readFileSync(identityPath, "utf-8");
125182
+ identityContent = fs19.readFileSync(identityPath, "utf-8");
124562
125183
  } catch {
124563
125184
  console.error(`Error: cannot read identity file: ${identityPath}`);
124564
125185
  process.exit(1);
@@ -124623,7 +125244,7 @@ async function handleServe(config) {
124623
125244
  const runtimeHostServer = election.server;
124624
125245
  if (config.tools) {
124625
125246
  const { pathToFileURL } = await import("url");
124626
- const resolved = path18.resolve(config.tools);
125247
+ const resolved = path19.resolve(config.tools);
124627
125248
  const mod2 = await import(pathToFileURL(resolved).href);
124628
125249
  const entries = mod2.default ?? mod2.tools;
124629
125250
  if (!Array.isArray(entries)) {
@@ -124863,7 +125484,7 @@ async function handleServe(config) {
124863
125484
  }
124864
125485
  if (config.identity != null && config.identity !== "") {
124865
125486
  try {
124866
- deps.identityFileContent = fs18.readFileSync(path18.resolve(config.identity), "utf-8");
125487
+ deps.identityFileContent = fs19.readFileSync(path19.resolve(config.identity), "utf-8");
124867
125488
  } catch {
124868
125489
  }
124869
125490
  }
@@ -125140,7 +125761,7 @@ init_esm_shims();
125140
125761
  import { spawn } from "child_process";
125141
125762
  import { mkdtemp, writeFile as writeFile3, unlink } from "fs/promises";
125142
125763
  import { tmpdir } from "os";
125143
- import { join as join20 } from "path";
125764
+ import { join as join21 } from "path";
125144
125765
 
125145
125766
  // ../../packages/voice/dist/index.js
125146
125767
  init_esm_shims();
@@ -125416,22 +126037,22 @@ var SystemTTSProvider = class {
125416
126037
  }
125417
126038
  };
125418
126039
  async function writeTempMp3(buf) {
125419
- const dir = await mkdtemp(join20(tmpdir(), "motebit-tts-"));
125420
- const path19 = join20(dir, "out.mp3");
125421
- await writeFile3(path19, buf);
125422
- return path19;
126040
+ const dir = await mkdtemp(join21(tmpdir(), "motebit-tts-"));
126041
+ const path20 = join21(dir, "out.mp3");
126042
+ await writeFile3(path20, buf);
126043
+ return path20;
125423
126044
  }
125424
- function mp3PlayerCommand(path19) {
125425
- if (process.platform === "darwin") return { bin: "afplay", args: [path19] };
125426
- return { bin: "mpg123", args: ["-q", path19] };
126045
+ function mp3PlayerCommand(path20) {
126046
+ if (process.platform === "darwin") return { bin: "afplay", args: [path20] };
126047
+ return { bin: "mpg123", args: ["-q", path20] };
125427
126048
  }
125428
126049
  function systemSpeakCommand() {
125429
126050
  if (process.platform === "darwin") return { bin: "say", args: [] };
125430
126051
  if (process.platform === "linux") return { bin: "espeak", args: [] };
125431
126052
  return null;
125432
126053
  }
125433
- function playMp3(path19, onSpawn) {
125434
- const cmd = mp3PlayerCommand(path19);
126054
+ function playMp3(path20, onSpawn) {
126055
+ const cmd = mp3PlayerCommand(path20);
125435
126056
  if (!cmd) {
125436
126057
  return Promise.reject(new Error(`No MP3 player available on ${process.platform}`));
125437
126058
  }
@@ -125812,12 +126433,16 @@ async function main() {
125812
126433
  const validProviders = ["anthropic", "openai", "google", "local-server", "proxy"];
125813
126434
  if (validProviders.includes(personalityConfig.default_provider)) {
125814
126435
  config.provider = personalityConfig.default_provider;
126436
+ if (!config.modelExplicit) {
126437
+ config.model = defaultModelForProvider(config.provider);
126438
+ }
125815
126439
  }
125816
126440
  }
125817
126441
  if (personalityConfig.default_model != null && personalityConfig.default_model !== "" && !process.argv.includes("--model")) {
125818
126442
  if (admitModelForProvider(config.provider, personalityConfig.default_model).admissible) {
125819
126443
  config.model = personalityConfig.default_model;
125820
126444
  } else {
126445
+ config.model = defaultModelForProvider(config.provider);
125821
126446
  console.log(
125822
126447
  dim(
125823
126448
  ` [config default_model "${personalityConfig.default_model}" belongs to another provider; using ${config.model} for ${config.provider}]`
@@ -125983,13 +126608,13 @@ async function main() {
125983
126608
  runtimeRef
125984
126609
  });
125985
126610
  } catch (err2) {
126611
+ destroyTerminal();
125986
126612
  console.error(
125987
126613
  `Runtime-host election failed: ${err2 instanceof Error ? err2.message : String(err2)}`
125988
126614
  );
125989
126615
  console.error(
125990
126616
  "Another motebit process may be coordinating with an incompatible build. Stop it and retry."
125991
126617
  );
125992
- destroyTerminal();
125993
126618
  process.exit(1);
125994
126619
  }
125995
126620
  if (election.role === "frontend") {
@@ -126165,7 +126790,8 @@ async function main() {
126165
126790
  moteDb.close();
126166
126791
  };
126167
126792
  process.on("SIGINT", () => {
126168
- console.log("\nGoodbye!");
126793
+ destroyTerminal();
126794
+ console.log("Goodbye!");
126169
126795
  void shutdown().then(() => process.exit(0));
126170
126796
  });
126171
126797
  const toolCount = toolRegistry.size;
@@ -126184,6 +126810,18 @@ async function main() {
126184
126810
  console.log(dim(" recovery seed not backed up \u2014 `motebit seed reveal` (once, on paper)"));
126185
126811
  console.log();
126186
126812
  }
126813
+ if (process.env["MOTEBIT_NO_UPDATE_CHECK"] !== "1") {
126814
+ const updateNudge = renderUpdateNudge({ currentVersion: VERSION, state: readUpdateState() });
126815
+ if (updateNudge != null) {
126816
+ console.log(dim(` ${updateNudge}`));
126817
+ console.log();
126818
+ }
126819
+ refreshUpdateCheckInBackground();
126820
+ }
126821
+ if (runtime.moneyToolsWithheld) {
126822
+ console.log(dim(` ${MONEY_TOOLS_WITHHELD_NOTICE}`));
126823
+ console.log();
126824
+ }
126187
126825
  if (isFirstLaunch) {
126188
126826
  try {
126189
126827
  const activationRunId = crypto.randomUUID();
@@ -126249,6 +126887,15 @@ async function main() {
126249
126887
  const bareSlash = resolveBareCommand(trimmed);
126250
126888
  const effective = bareSlash ?? trimmed;
126251
126889
  if (bareSlash != null) console.log(dim(` \u2192 ${bareSlash}`));
126890
+ if (bareSlash == null) {
126891
+ const shellTeach = detectShellInvocation(trimmed);
126892
+ if (shellTeach != null) {
126893
+ console.log(dim(shellTeach));
126894
+ console.log();
126895
+ prompt2();
126896
+ return;
126897
+ }
126898
+ }
126252
126899
  if (isSlashCommand(effective)) {
126253
126900
  const { command: command2, args } = parseSlashCommand(effective);
126254
126901
  await handleSlashCommand(command2, args, runtime, config, fullConfig, {