@ametyst/cli 0.3.6 → 0.3.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +542 -279
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -23203,13 +23203,13 @@ var init_getCallError = __esm({
23203
23203
 
23204
23204
  // node_modules/.pnpm/viem@2.38.6_typescript@5.2.2_zod@4.3.6/node_modules/viem/_esm/utils/promise/withResolvers.js
23205
23205
  function withResolvers() {
23206
- let resolve = () => void 0;
23206
+ let resolve3 = () => void 0;
23207
23207
  let reject = () => void 0;
23208
23208
  const promise = new Promise((resolve_, reject_) => {
23209
- resolve = resolve_;
23209
+ resolve3 = resolve_;
23210
23210
  reject = reject_;
23211
23211
  });
23212
- return { promise, resolve, reject };
23212
+ return { promise, resolve: resolve3, reject };
23213
23213
  }
23214
23214
  var init_withResolvers = __esm({
23215
23215
  "node_modules/.pnpm/viem@2.38.6_typescript@5.2.2_zod@4.3.6/node_modules/viem/_esm/utils/promise/withResolvers.js"() {
@@ -23230,8 +23230,8 @@ function createBatchScheduler({ fn, id, shouldSplitBatch, wait: wait2 = 0, sort
23230
23230
  if (sort && Array.isArray(data))
23231
23231
  data.sort(sort);
23232
23232
  for (let i = 0; i < scheduler.length; i++) {
23233
- const { resolve } = scheduler[i];
23234
- resolve?.([data[i], data]);
23233
+ const { resolve: resolve3 } = scheduler[i];
23234
+ resolve3?.([data[i], data]);
23235
23235
  }
23236
23236
  }).catch((err) => {
23237
23237
  for (let i = 0; i < scheduler.length; i++) {
@@ -23247,16 +23247,16 @@ function createBatchScheduler({ fn, id, shouldSplitBatch, wait: wait2 = 0, sort
23247
23247
  return {
23248
23248
  flush,
23249
23249
  async schedule(args) {
23250
- const { promise, resolve, reject } = withResolvers();
23250
+ const { promise, resolve: resolve3, reject } = withResolvers();
23251
23251
  const split2 = shouldSplitBatch?.([...getBatchedArgs(), args]);
23252
23252
  if (split2)
23253
23253
  exec();
23254
23254
  const hasActiveScheduler = getScheduler().length > 0;
23255
23255
  if (hasActiveScheduler) {
23256
- setScheduler({ args, resolve, reject });
23256
+ setScheduler({ args, resolve: resolve3, reject });
23257
23257
  return promise;
23258
23258
  }
23259
- setScheduler({ args, resolve, reject });
23259
+ setScheduler({ args, resolve: resolve3, reject });
23260
23260
  setTimeout(exec, wait2);
23261
23261
  return promise;
23262
23262
  }
@@ -24831,7 +24831,7 @@ var init_calls = __esm({
24831
24831
 
24832
24832
  // node_modules/.pnpm/viem@2.38.6_typescript@5.2.2_zod@4.3.6/node_modules/viem/_esm/utils/promise/withRetry.js
24833
24833
  function withRetry(fn, { delay: delay_ = 100, retryCount = 2, shouldRetry: shouldRetry2 = () => true } = {}) {
24834
- return new Promise((resolve, reject) => {
24834
+ return new Promise((resolve3, reject) => {
24835
24835
  const attemptRetry = async ({ count = 0 } = {}) => {
24836
24836
  const retry = async ({ error }) => {
24837
24837
  const delay = typeof delay_ === "function" ? delay_({ count, error }) : delay_;
@@ -24841,7 +24841,7 @@ function withRetry(fn, { delay: delay_ = 100, retryCount = 2, shouldRetry: shoul
24841
24841
  };
24842
24842
  try {
24843
24843
  const data = await fn();
24844
- resolve(data);
24844
+ resolve3(data);
24845
24845
  } catch (err) {
24846
24846
  if (count < retryCount && await shouldRetry2({ count, error: err }))
24847
24847
  return retry({ error: err });
@@ -24963,7 +24963,7 @@ async function sendCalls(client, parameters) {
24963
24963
  });
24964
24964
  promises.push(promise);
24965
24965
  if (experimental_fallbackDelay > 0)
24966
- await new Promise((resolve) => setTimeout(resolve, experimental_fallbackDelay));
24966
+ await new Promise((resolve3) => setTimeout(resolve3, experimental_fallbackDelay));
24967
24967
  }
24968
24968
  const results = await Promise.allSettled(promises);
24969
24969
  if (results.every((r) => r.status === "rejected"))
@@ -25098,9 +25098,9 @@ async function waitForCallsStatus(client, parameters) {
25098
25098
  throwOnFailure = false
25099
25099
  } = parameters;
25100
25100
  const observerId = stringify(["waitForCallsStatus", client.uid, id]);
25101
- const { promise, resolve, reject } = withResolvers();
25101
+ const { promise, resolve: resolve3, reject } = withResolvers();
25102
25102
  let timer;
25103
- const unobserve = observe(observerId, { resolve, reject }, (emit2) => {
25103
+ const unobserve = observe(observerId, { resolve: resolve3, reject }, (emit2) => {
25104
25104
  const unpoll = poll(async () => {
25105
25105
  const done = (fn) => {
25106
25106
  clearTimeout(timer);
@@ -25511,13 +25511,13 @@ async function isImageUri(uri) {
25511
25511
  }
25512
25512
  if (!Object.hasOwn(globalThis, "Image"))
25513
25513
  return false;
25514
- return new Promise((resolve) => {
25514
+ return new Promise((resolve3) => {
25515
25515
  const img = new Image();
25516
25516
  img.onload = () => {
25517
- resolve(true);
25517
+ resolve3(true);
25518
25518
  };
25519
25519
  img.onerror = () => {
25520
- resolve(false);
25520
+ resolve3(false);
25521
25521
  };
25522
25522
  img.src = uri;
25523
25523
  });
@@ -27351,7 +27351,7 @@ var init_nonceManager = __esm({
27351
27351
 
27352
27352
  // node_modules/.pnpm/viem@2.38.6_typescript@5.2.2_zod@4.3.6/node_modules/viem/_esm/utils/promise/withTimeout.js
27353
27353
  function withTimeout(fn, { errorInstance = new Error("timed out"), timeout, signal }) {
27354
- return new Promise((resolve, reject) => {
27354
+ return new Promise((resolve3, reject) => {
27355
27355
  ;
27356
27356
  (async () => {
27357
27357
  let timeoutId;
@@ -27366,7 +27366,7 @@ function withTimeout(fn, { errorInstance = new Error("timed out"), timeout, sign
27366
27366
  }
27367
27367
  }, timeout);
27368
27368
  }
27369
- resolve(await fn({ signal: controller?.signal || null }));
27369
+ resolve3(await fn({ signal: controller?.signal || null }));
27370
27370
  } catch (err) {
27371
27371
  if (err?.name === "AbortError")
27372
27372
  reject(errorInstance);
@@ -29757,7 +29757,7 @@ var require_extension = __commonJS({
29757
29757
  if (dest[name] === void 0) dest[name] = [elem];
29758
29758
  else dest[name].push(elem);
29759
29759
  }
29760
- function parse3(header) {
29760
+ function parse5(header) {
29761
29761
  const offers = /* @__PURE__ */ Object.create(null);
29762
29762
  let params = /* @__PURE__ */ Object.create(null);
29763
29763
  let mustUnescape = false;
@@ -29897,7 +29897,7 @@ var require_extension = __commonJS({
29897
29897
  }).join(", ");
29898
29898
  }).join(", ");
29899
29899
  }
29900
- module.exports = { format, parse: parse3 };
29900
+ module.exports = { format, parse: parse5 };
29901
29901
  }
29902
29902
  });
29903
29903
 
@@ -29932,7 +29932,7 @@ var require_websocket = __commonJS({
29932
29932
  var {
29933
29933
  EventTarget: { addEventListener: addEventListener2, removeEventListener: removeEventListener2 }
29934
29934
  } = require_event_target();
29935
- var { format, parse: parse3 } = require_extension();
29935
+ var { format, parse: parse5 } = require_extension();
29936
29936
  var { toBuffer: toBuffer2 } = require_buffer_util();
29937
29937
  var kAborted = /* @__PURE__ */ Symbol("kAborted");
29938
29938
  var protocolVersions = [8, 13];
@@ -30609,7 +30609,7 @@ var require_websocket = __commonJS({
30609
30609
  }
30610
30610
  let extensions;
30611
30611
  try {
30612
- extensions = parse3(secWebSocketExtensions);
30612
+ extensions = parse5(secWebSocketExtensions);
30613
30613
  } catch (err) {
30614
30614
  const message = "Invalid Sec-WebSocket-Extensions header";
30615
30615
  abortHandshake(websocket, socket, message);
@@ -30903,7 +30903,7 @@ var require_subprotocol = __commonJS({
30903
30903
  "use strict";
30904
30904
  init_esm_shims();
30905
30905
  var { tokenChars } = require_validation();
30906
- function parse3(header) {
30906
+ function parse5(header) {
30907
30907
  const protocols = /* @__PURE__ */ new Set();
30908
30908
  let start = -1;
30909
30909
  let end = -1;
@@ -30939,7 +30939,7 @@ var require_subprotocol = __commonJS({
30939
30939
  protocols.add(protocol4);
30940
30940
  return protocols;
30941
30941
  }
30942
- module.exports = { parse: parse3 };
30942
+ module.exports = { parse: parse5 };
30943
30943
  }
30944
30944
  });
30945
30945
 
@@ -31447,10 +31447,10 @@ async function getWebSocketRpcClient(url2, options = {}) {
31447
31447
  socket.addEventListener("error", onError);
31448
31448
  socket.addEventListener("open", onOpen);
31449
31449
  if (socket.readyState === WebSocket4.CONNECTING) {
31450
- await new Promise((resolve, reject) => {
31450
+ await new Promise((resolve3, reject) => {
31451
31451
  if (!socket)
31452
31452
  return;
31453
- socket.onopen = resolve;
31453
+ socket.onopen = resolve3;
31454
31454
  socket.onerror = reject;
31455
31455
  });
31456
31456
  }
@@ -35738,13 +35738,13 @@ async function waitForTransactionReceipt(client, parameters) {
35738
35738
  let retrying = false;
35739
35739
  let _unobserve;
35740
35740
  let _unwatch;
35741
- const { promise, resolve, reject } = withResolvers();
35741
+ const { promise, resolve: resolve3, reject } = withResolvers();
35742
35742
  const timer = timeout ? setTimeout(() => {
35743
35743
  _unwatch?.();
35744
35744
  _unobserve?.();
35745
35745
  reject(new WaitForTransactionReceiptTimeoutError({ hash: hash3 }));
35746
35746
  }, timeout) : void 0;
35747
- _unobserve = observe(observerId, { onReplaced, resolve, reject }, async (emit2) => {
35747
+ _unobserve = observe(observerId, { onReplaced, resolve: resolve3, reject }, async (emit2) => {
35748
35748
  receipt = await getAction(client, getTransactionReceipt, "getTransactionReceipt")({ hash: hash3 }).catch(() => void 0);
35749
35749
  if (receipt && confirmations <= 1) {
35750
35750
  clearTimeout(timer);
@@ -38095,7 +38095,7 @@ function webSocket(url2, config = {}) {
38095
38095
  },
38096
38096
  async subscribe({ params, onData, onError }) {
38097
38097
  const rpcClient = await getWebSocketRpcClient(url_, wsRpcClientOpts);
38098
- const { result: subscriptionId } = await new Promise((resolve, reject) => rpcClient.request({
38098
+ const { result: subscriptionId } = await new Promise((resolve3, reject) => rpcClient.request({
38099
38099
  body: {
38100
38100
  method: "eth_subscribe",
38101
38101
  params
@@ -38112,7 +38112,7 @@ function webSocket(url2, config = {}) {
38112
38112
  return;
38113
38113
  }
38114
38114
  if (typeof response.id === "number") {
38115
- resolve(response);
38115
+ resolve3(response);
38116
38116
  return;
38117
38117
  }
38118
38118
  if (response.method !== "eth_subscription")
@@ -38123,12 +38123,12 @@ function webSocket(url2, config = {}) {
38123
38123
  return {
38124
38124
  subscriptionId,
38125
38125
  async unsubscribe() {
38126
- return new Promise((resolve) => rpcClient.request({
38126
+ return new Promise((resolve3) => rpcClient.request({
38127
38127
  body: {
38128
38128
  method: "eth_unsubscribe",
38129
38129
  params: [subscriptionId]
38130
38130
  },
38131
- onResponse: resolve
38131
+ onResponse: resolve3
38132
38132
  }));
38133
38133
  }
38134
38134
  };
@@ -66783,8 +66783,8 @@ function waitForUserOperationReceipt(client, parameters) {
66783
66783
  client.uid,
66784
66784
  hash3
66785
66785
  ]);
66786
- return new Promise((resolve, reject) => {
66787
- const unobserve = observe(observerId, { resolve, reject }, (emit2) => {
66786
+ return new Promise((resolve3, reject) => {
66787
+ const unobserve = observe(observerId, { resolve: resolve3, reject }, (emit2) => {
66788
66788
  const done = (fn) => {
66789
66789
  unpoll();
66790
66790
  fn();
@@ -67779,7 +67779,7 @@ var require_parse = __commonJS({
67779
67779
  "use strict";
67780
67780
  init_esm_shims();
67781
67781
  var SemVer = require_semver();
67782
- var parse3 = (version5, options, throwErrors = false) => {
67782
+ var parse5 = (version5, options, throwErrors = false) => {
67783
67783
  if (version5 instanceof SemVer) {
67784
67784
  return version5;
67785
67785
  }
@@ -67792,7 +67792,7 @@ var require_parse = __commonJS({
67792
67792
  throw er;
67793
67793
  }
67794
67794
  };
67795
- module.exports = parse3;
67795
+ module.exports = parse5;
67796
67796
  }
67797
67797
  });
67798
67798
 
@@ -67801,9 +67801,9 @@ var require_valid = __commonJS({
67801
67801
  "node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/valid.js"(exports, module) {
67802
67802
  "use strict";
67803
67803
  init_esm_shims();
67804
- var parse3 = require_parse();
67804
+ var parse5 = require_parse();
67805
67805
  var valid = (version5, options) => {
67806
- const v = parse3(version5, options);
67806
+ const v = parse5(version5, options);
67807
67807
  return v ? v.version : null;
67808
67808
  };
67809
67809
  module.exports = valid;
@@ -67815,9 +67815,9 @@ var require_clean = __commonJS({
67815
67815
  "node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/clean.js"(exports, module) {
67816
67816
  "use strict";
67817
67817
  init_esm_shims();
67818
- var parse3 = require_parse();
67818
+ var parse5 = require_parse();
67819
67819
  var clean2 = (version5, options) => {
67820
- const s = parse3(version5.trim().replace(/^[=v]+/, ""), options);
67820
+ const s = parse5(version5.trim().replace(/^[=v]+/, ""), options);
67821
67821
  return s ? s.version : null;
67822
67822
  };
67823
67823
  module.exports = clean2;
@@ -67854,10 +67854,10 @@ var require_diff = __commonJS({
67854
67854
  "node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/diff.js"(exports, module) {
67855
67855
  "use strict";
67856
67856
  init_esm_shims();
67857
- var parse3 = require_parse();
67857
+ var parse5 = require_parse();
67858
67858
  var diff = (version1, version22) => {
67859
- const v1 = parse3(version1, null, true);
67860
- const v2 = parse3(version22, null, true);
67859
+ const v1 = parse5(version1, null, true);
67860
+ const v2 = parse5(version22, null, true);
67861
67861
  const comparison = v1.compare(v2);
67862
67862
  if (comparison === 0) {
67863
67863
  return null;
@@ -67932,9 +67932,9 @@ var require_prerelease = __commonJS({
67932
67932
  "node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/prerelease.js"(exports, module) {
67933
67933
  "use strict";
67934
67934
  init_esm_shims();
67935
- var parse3 = require_parse();
67935
+ var parse5 = require_parse();
67936
67936
  var prerelease = (version5, options) => {
67937
- const parsed = parse3(version5, options);
67937
+ const parsed = parse5(version5, options);
67938
67938
  return parsed && parsed.prerelease.length ? parsed.prerelease : null;
67939
67939
  };
67940
67940
  module.exports = prerelease;
@@ -68134,7 +68134,7 @@ var require_coerce = __commonJS({
68134
68134
  "use strict";
68135
68135
  init_esm_shims();
68136
68136
  var SemVer = require_semver();
68137
- var parse3 = require_parse();
68137
+ var parse5 = require_parse();
68138
68138
  var { safeRe: re2, t } = require_re();
68139
68139
  var coerce = (version5, options) => {
68140
68140
  if (version5 instanceof SemVer) {
@@ -68169,7 +68169,7 @@ var require_coerce = __commonJS({
68169
68169
  const patch = match[4] || "0";
68170
68170
  const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : "";
68171
68171
  const build = options.includePrerelease && match[6] ? `+${match[6]}` : "";
68172
- return parse3(`${major}.${minor}.${patch}${prerelease}${build}`, options);
68172
+ return parse5(`${major}.${minor}.${patch}${prerelease}${build}`, options);
68173
68173
  };
68174
68174
  module.exports = coerce;
68175
68175
  }
@@ -68180,11 +68180,11 @@ var require_truncate = __commonJS({
68180
68180
  "node_modules/.pnpm/semver@7.8.1/node_modules/semver/functions/truncate.js"(exports, module) {
68181
68181
  "use strict";
68182
68182
  init_esm_shims();
68183
- var parse3 = require_parse();
68184
- var constants3 = require_constants2();
68183
+ var parse5 = require_parse();
68184
+ var constants5 = require_constants2();
68185
68185
  var SemVer = require_semver();
68186
68186
  var truncate = (version5, truncation, options) => {
68187
- if (!constants3.RELEASE_TYPES.includes(truncation)) {
68187
+ if (!constants5.RELEASE_TYPES.includes(truncation)) {
68188
68188
  return null;
68189
68189
  }
68190
68190
  const clonedVersion = cloneInputVersion(version5, options);
@@ -68192,7 +68192,7 @@ var require_truncate = __commonJS({
68192
68192
  };
68193
68193
  var cloneInputVersion = (version5, options) => {
68194
68194
  const versionStringToParse = version5 instanceof SemVer ? version5.version : version5;
68195
- return parse3(versionStringToParse, options);
68195
+ return parse5(versionStringToParse, options);
68196
68196
  };
68197
68197
  var doTruncation = (version5, truncation) => {
68198
68198
  if (isPrerelease(truncation)) {
@@ -69244,10 +69244,10 @@ var require_semver2 = __commonJS({
69244
69244
  "use strict";
69245
69245
  init_esm_shims();
69246
69246
  var internalRe = require_re();
69247
- var constants3 = require_constants2();
69247
+ var constants5 = require_constants2();
69248
69248
  var SemVer = require_semver();
69249
69249
  var identifiers = require_identifiers();
69250
- var parse3 = require_parse();
69250
+ var parse5 = require_parse();
69251
69251
  var valid = require_valid();
69252
69252
  var clean2 = require_clean();
69253
69253
  var inc = require_inc();
@@ -69286,7 +69286,7 @@ var require_semver2 = __commonJS({
69286
69286
  var simplifyRange = require_simplify();
69287
69287
  var subset = require_subset();
69288
69288
  module.exports = {
69289
- parse: parse3,
69289
+ parse: parse5,
69290
69290
  valid,
69291
69291
  clean: clean2,
69292
69292
  inc,
@@ -69328,8 +69328,8 @@ var require_semver2 = __commonJS({
69328
69328
  re: internalRe.re,
69329
69329
  src: internalRe.src,
69330
69330
  tokens: internalRe.t,
69331
- SEMVER_SPEC_VERSION: constants3.SEMVER_SPEC_VERSION,
69332
- RELEASE_TYPES: constants3.RELEASE_TYPES,
69331
+ SEMVER_SPEC_VERSION: constants5.SEMVER_SPEC_VERSION,
69332
+ RELEASE_TYPES: constants5.RELEASE_TYPES,
69333
69333
  compareIdentifiers: identifiers.compareIdentifiers,
69334
69334
  rcompareIdentifiers: identifiers.rcompareIdentifiers
69335
69335
  };
@@ -77915,7 +77915,7 @@ function bufferToUTF8String(value2) {
77915
77915
  function browserSupportsWebAuthnAutofill() {
77916
77916
  const globalPublicKeyCredential = window.PublicKeyCredential;
77917
77917
  if (globalPublicKeyCredential.isConditionalMediationAvailable === void 0) {
77918
- return new Promise((resolve) => resolve(false));
77918
+ return new Promise((resolve3) => resolve3(false));
77919
77919
  }
77920
77920
  return globalPublicKeyCredential.isConditionalMediationAvailable();
77921
77921
  }
@@ -78019,7 +78019,7 @@ async function startAuthentication(requestOptionsJSON, useBrowserAutofill = fals
78019
78019
  }
78020
78020
  function platformAuthenticatorIsAvailable() {
78021
78021
  if (!browserSupportsWebAuthn()) {
78022
- return new Promise((resolve) => resolve(false));
78022
+ return new Promise((resolve3) => resolve3(false));
78023
78023
  }
78024
78024
  return PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();
78025
78025
  }
@@ -78405,7 +78405,7 @@ function bufferToUTF8String2(value2) {
78405
78405
  function browserSupportsWebAuthnAutofill2() {
78406
78406
  const globalPublicKeyCredential = window.PublicKeyCredential;
78407
78407
  if (globalPublicKeyCredential.isConditionalMediationAvailable === void 0) {
78408
- return new Promise((resolve) => resolve(false));
78408
+ return new Promise((resolve3) => resolve3(false));
78409
78409
  }
78410
78410
  return globalPublicKeyCredential.isConditionalMediationAvailable();
78411
78411
  }
@@ -78509,7 +78509,7 @@ async function startAuthentication2(requestOptionsJSON, useBrowserAutofill = fal
78509
78509
  }
78510
78510
  function platformAuthenticatorIsAvailable2() {
78511
78511
  if (!browserSupportsWebAuthn2()) {
78512
- return new Promise((resolve) => resolve(false));
78512
+ return new Promise((resolve3) => resolve3(false));
78513
78513
  }
78514
78514
  return PublicKeyCredential.isUserVerifyingPlatformAuthenticatorAvailable();
78515
78515
  }
@@ -78896,18 +78896,18 @@ var init_initialization = __esm({
78896
78896
  async createBaseContracts() {
78897
78897
  const eoaAccount = await this.actions.createEoaAccount();
78898
78898
  const kernelClient = await this.actions.createKernelClientWithEoa(eoaAccount);
78899
- await new Promise((resolve) => setTimeout(resolve, 3e3));
78899
+ await new Promise((resolve3) => setTimeout(resolve3, 3e3));
78900
78900
  const recoveryEscrowFactoryAddress = await this.actions.deployContractAndGetAddress(kernelClient, RecoveryEscrowFactoryAbi, RecoveryEscrowFactoryBytecode, []);
78901
- await new Promise((resolve) => setTimeout(resolve, 3e3));
78901
+ await new Promise((resolve3) => setTimeout(resolve3, 3e3));
78902
78902
  const mockTokenAddress = await this.actions.deployContractAndGetAddress(kernelClient, MockTokenAbi, MockTokenBytecode, [
78903
78903
  "MockToken",
78904
78904
  "MTK",
78905
78905
  BigInt(1e6) * BigInt(10 ** 6),
78906
78906
  6
78907
78907
  ]);
78908
- await new Promise((resolve) => setTimeout(resolve, 3e3));
78908
+ await new Promise((resolve3) => setTimeout(resolve3, 3e3));
78909
78909
  const paymentManagersRegistryAddress = await this.actions.deployContractAndGetAddress(kernelClient, PaymentManagersRegistryAbi, PaymentManagersRegistryBytecode, []);
78910
- await new Promise((resolve) => setTimeout(resolve, 3e3));
78910
+ await new Promise((resolve3) => setTimeout(resolve3, 3e3));
78911
78911
  return {
78912
78912
  recoveryEscrowFactoryAddress,
78913
78913
  mockTokenAddress,
@@ -78918,9 +78918,9 @@ var init_initialization = __esm({
78918
78918
  async initializePolicies() {
78919
78919
  const eoaAccount = await this.actions.createEoaAccount();
78920
78920
  const kernelClient = await this.actions.createKernelClientWithEoa(eoaAccount);
78921
- await new Promise((resolve) => setTimeout(resolve, 3e3));
78921
+ await new Promise((resolve3) => setTimeout(resolve3, 3e3));
78922
78922
  const timestampPolicyAddress = await this.actions.deployContractAndGetAddress(kernelClient, TimestampPolicyAbi, TimestampPolicyBytecode, []);
78923
- await new Promise((resolve) => setTimeout(resolve, 3e3));
78923
+ await new Promise((resolve3) => setTimeout(resolve3, 3e3));
78924
78924
  return {
78925
78925
  timestampPolicyAddress
78926
78926
  };
@@ -78929,7 +78929,7 @@ var init_initialization = __esm({
78929
78929
  const newPrivateKey = generatePrivateKey();
78930
78930
  const eoaAccount = privateKeyToAccount(newPrivateKey);
78931
78931
  const kernelClient = await this.actions.createKernelClientWithEoa(eoaAccount);
78932
- await new Promise((resolve) => setTimeout(resolve, 3e3));
78932
+ await new Promise((resolve3) => setTimeout(resolve3, 3e3));
78933
78933
  return { address: eoaAccount.address, privateKey: newPrivateKey, smartAccount: kernelClient.account.address };
78934
78934
  }
78935
78935
  async addMoneyToTestAccount(testAccount, mockTokenAddress) {
@@ -78961,13 +78961,13 @@ var init_initialization = __esm({
78961
78961
  const txReceipt = await publicClient.waitForTransactionReceipt({
78962
78962
  hash: userOpReceipt.receipt.transactionHash
78963
78963
  });
78964
- await new Promise((resolve) => setTimeout(resolve, 3e3));
78964
+ await new Promise((resolve3) => setTimeout(resolve3, 3e3));
78965
78965
  return true;
78966
78966
  }
78967
78967
  async sendMoneyToTestAccount(testAccount, mockTokenAddress, amount, recipientAddress) {
78968
78968
  const eoaAccount = privateKeyToAccount(testAccount.privateKey);
78969
78969
  const kernelClient = await this.actions.createKernelClientWithEoa(eoaAccount);
78970
- await new Promise((resolve) => setTimeout(resolve, 5e3));
78970
+ await new Promise((resolve3) => setTimeout(resolve3, 5e3));
78971
78971
  const publicClient = createPublicClient({
78972
78972
  chain: CHAINS.BASE_SEPOLIA,
78973
78973
  transport: http(this.bundlerPaymasterUrl)
@@ -78994,7 +78994,7 @@ var init_initialization = __esm({
78994
78994
  const txReceipt = await publicClient.waitForTransactionReceipt({
78995
78995
  hash: userOpReceipt.receipt.transactionHash
78996
78996
  });
78997
- await new Promise((resolve) => setTimeout(resolve, 3e3));
78997
+ await new Promise((resolve3) => setTimeout(resolve3, 3e3));
78998
78998
  return true;
78999
78999
  }
79000
79000
  async createPolicyFreeSessionKey(kernelClient, kernelAccountAddress, paymentManagerAddress) {
@@ -79017,7 +79017,7 @@ var init_initialization = __esm({
79017
79017
  policies: [rootPolicy]
79018
79018
  });
79019
79019
  const configurePermissions = await this.permissions.configurePermissions(kernelClient, publicClient, sessionPermission, kernelAccountAddress, paymentManagerAddress);
79020
- await new Promise((resolve) => setTimeout(resolve, 5e3));
79020
+ await new Promise((resolve3) => setTimeout(resolve3, 5e3));
79021
79021
  return { sessionKeyAddress: sessionKeySigner.account.address, sessionKeyPrivateKey: sessionPrivateKey };
79022
79022
  }
79023
79023
  };
@@ -79753,13 +79753,13 @@ var init_financial_accounts = __esm({
79753
79753
  await this.installExecutor(kernelClient, publicClient, kernelAccountAddress, paymentManagerAddress);
79754
79754
  console.error("[SIGNUP 8] installExecutor DONE");
79755
79755
  console.error("[SIGNUP 9] waiting 10s for nonce propagation...");
79756
- await new Promise((resolve) => setTimeout(resolve, 1e4));
79756
+ await new Promise((resolve3) => setTimeout(resolve3, 1e4));
79757
79757
  onProgress?.("configure_permissions");
79758
79758
  console.error("[SIGNUP 10] calling permissions.configurePermissions (PASSKEY SIGN #2 expected)...");
79759
79759
  const configurePermissions = await this.permissions.configurePermissions(kernelClient, publicClient, sessionPermission, kernelAccountAddress, paymentManagerAddress);
79760
79760
  console.error("[SIGNUP 10b] configurePermissions DONE", configurePermissions);
79761
79761
  console.error("[SIGNUP 11] waiting 5s...");
79762
- await new Promise((resolve) => setTimeout(resolve, 5e3));
79762
+ await new Promise((resolve3) => setTimeout(resolve3, 5e3));
79763
79763
  }
79764
79764
  const sessionKernelAccountConfig = {
79765
79765
  address: kernelAccountAddress,
@@ -81898,7 +81898,7 @@ var init_permissions = __esm({
81898
81898
  const permissionInstallReceipt = await publicClient.waitForTransactionReceipt({
81899
81899
  hash: permissionInstallUserOpReceipt.receipt.transactionHash
81900
81900
  });
81901
- await new Promise((resolve) => setTimeout(resolve, 5e3));
81901
+ await new Promise((resolve3) => setTimeout(resolve3, 5e3));
81902
81902
  const grantAccessUserOpHash = await kernelClient.sendUserOperation({
81903
81903
  callData: delegateCall,
81904
81904
  callGasLimit: 2000000n
@@ -81957,7 +81957,7 @@ var init_permissions = __esm({
81957
81957
  let lastTxHash = batchUserOpReceipt.receipt.transactionHash;
81958
81958
  for (const input of installInputs) {
81959
81959
  if (grantDelayMs > 0) {
81960
- await new Promise((resolve) => setTimeout(resolve, grantDelayMs));
81960
+ await new Promise((resolve3) => setTimeout(resolve3, grantDelayMs));
81961
81961
  }
81962
81962
  const grantAccessFunctionData = buildGrantAccessFunctionData(input.identifier);
81963
81963
  const delegateCall = await encodeCallData2([
@@ -82011,7 +82011,7 @@ var init_permissions = __esm({
82011
82011
  await publicClient.waitForTransactionReceipt({
82012
82012
  hash: revokeAccessUserOpReceipt.receipt.transactionHash
82013
82013
  });
82014
- await new Promise((resolve) => setTimeout(resolve, 5e3));
82014
+ await new Promise((resolve3) => setTimeout(resolve3, 5e3));
82015
82015
  const deinitData = await permissionPlugin.getEnableData(kernelAccountAddress);
82016
82016
  const uninstallFunctionData = encodeFunctionData({
82017
82017
  abi: KernelV3_3AccountAbi,
@@ -82428,7 +82428,7 @@ var init_virtual_wallets_managers = __esm({
82428
82428
  policyValidUntil = built.policyValidUntil;
82429
82429
  spendingLimitWire = built.spendingLimitWire;
82430
82430
  const configurePermissions = await this.permissions.configurePermissions(kernelClient, publicClient, built.sessionPermission, kernelAccountAddress, paymentManagerAddress);
82431
- await new Promise((resolve) => setTimeout(resolve, 5e3));
82431
+ await new Promise((resolve3) => setTimeout(resolve3, 5e3));
82432
82432
  }
82433
82433
  }
82434
82434
  const response = await this.buyerAPIs.walletApproval(jwtToken, {
@@ -82819,7 +82819,7 @@ var init_bundler_retry = __esm({
82819
82819
  factor: 2,
82820
82820
  maxMs: 8e3
82821
82821
  };
82822
- defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
82822
+ defaultSleep = (ms) => new Promise((resolve3) => setTimeout(resolve3, ms));
82823
82823
  }
82824
82824
  });
82825
82825
 
@@ -86276,7 +86276,7 @@ var init_transactions = __esm({
86276
86276
  async waitBeforeDeferredPermitRetry(attempt) {
86277
86277
  const delayMs = _transactions.DEFERRED_PERMIT_RETRY_DELAYS_MS[attempt] ?? 0;
86278
86278
  if (delayMs > 0)
86279
- await new Promise((resolve) => setTimeout(resolve, delayMs));
86279
+ await new Promise((resolve3) => setTimeout(resolve3, delayMs));
86280
86280
  }
86281
86281
  async cancelAuthorization(kernelClient, paymentManagerAddress, wrappedHash) {
86282
86282
  console.error("[spend] cancelAuthorization called with:", {
@@ -90107,11 +90107,11 @@ var require_codegen = __commonJS({
90107
90107
  const rhs = this.rhs === void 0 ? "" : ` = ${this.rhs}`;
90108
90108
  return `${varKind} ${this.name}${rhs};` + _n;
90109
90109
  }
90110
- optimizeNames(names, constants3) {
90110
+ optimizeNames(names, constants5) {
90111
90111
  if (!names[this.name.str])
90112
90112
  return;
90113
90113
  if (this.rhs)
90114
- this.rhs = optimizeExpr(this.rhs, names, constants3);
90114
+ this.rhs = optimizeExpr(this.rhs, names, constants5);
90115
90115
  return this;
90116
90116
  }
90117
90117
  get names() {
@@ -90128,10 +90128,10 @@ var require_codegen = __commonJS({
90128
90128
  render({ _n }) {
90129
90129
  return `${this.lhs} = ${this.rhs};` + _n;
90130
90130
  }
90131
- optimizeNames(names, constants3) {
90131
+ optimizeNames(names, constants5) {
90132
90132
  if (this.lhs instanceof code_1.Name && !names[this.lhs.str] && !this.sideEffects)
90133
90133
  return;
90134
- this.rhs = optimizeExpr(this.rhs, names, constants3);
90134
+ this.rhs = optimizeExpr(this.rhs, names, constants5);
90135
90135
  return this;
90136
90136
  }
90137
90137
  get names() {
@@ -90192,8 +90192,8 @@ var require_codegen = __commonJS({
90192
90192
  optimizeNodes() {
90193
90193
  return `${this.code}` ? this : void 0;
90194
90194
  }
90195
- optimizeNames(names, constants3) {
90196
- this.code = optimizeExpr(this.code, names, constants3);
90195
+ optimizeNames(names, constants5) {
90196
+ this.code = optimizeExpr(this.code, names, constants5);
90197
90197
  return this;
90198
90198
  }
90199
90199
  get names() {
@@ -90222,12 +90222,12 @@ var require_codegen = __commonJS({
90222
90222
  }
90223
90223
  return nodes.length > 0 ? this : void 0;
90224
90224
  }
90225
- optimizeNames(names, constants3) {
90225
+ optimizeNames(names, constants5) {
90226
90226
  const { nodes } = this;
90227
90227
  let i = nodes.length;
90228
90228
  while (i--) {
90229
90229
  const n = nodes[i];
90230
- if (n.optimizeNames(names, constants3))
90230
+ if (n.optimizeNames(names, constants5))
90231
90231
  continue;
90232
90232
  subtractNames(names, n.names);
90233
90233
  nodes.splice(i, 1);
@@ -90280,12 +90280,12 @@ var require_codegen = __commonJS({
90280
90280
  return void 0;
90281
90281
  return this;
90282
90282
  }
90283
- optimizeNames(names, constants3) {
90283
+ optimizeNames(names, constants5) {
90284
90284
  var _a;
90285
- this.else = (_a = this.else) === null || _a === void 0 ? void 0 : _a.optimizeNames(names, constants3);
90286
- if (!(super.optimizeNames(names, constants3) || this.else))
90285
+ this.else = (_a = this.else) === null || _a === void 0 ? void 0 : _a.optimizeNames(names, constants5);
90286
+ if (!(super.optimizeNames(names, constants5) || this.else))
90287
90287
  return;
90288
- this.condition = optimizeExpr(this.condition, names, constants3);
90288
+ this.condition = optimizeExpr(this.condition, names, constants5);
90289
90289
  return this;
90290
90290
  }
90291
90291
  get names() {
@@ -90308,10 +90308,10 @@ var require_codegen = __commonJS({
90308
90308
  render(opts) {
90309
90309
  return `for(${this.iteration})` + super.render(opts);
90310
90310
  }
90311
- optimizeNames(names, constants3) {
90312
- if (!super.optimizeNames(names, constants3))
90311
+ optimizeNames(names, constants5) {
90312
+ if (!super.optimizeNames(names, constants5))
90313
90313
  return;
90314
- this.iteration = optimizeExpr(this.iteration, names, constants3);
90314
+ this.iteration = optimizeExpr(this.iteration, names, constants5);
90315
90315
  return this;
90316
90316
  }
90317
90317
  get names() {
@@ -90347,10 +90347,10 @@ var require_codegen = __commonJS({
90347
90347
  render(opts) {
90348
90348
  return `for(${this.varKind} ${this.name} ${this.loop} ${this.iterable})` + super.render(opts);
90349
90349
  }
90350
- optimizeNames(names, constants3) {
90351
- if (!super.optimizeNames(names, constants3))
90350
+ optimizeNames(names, constants5) {
90351
+ if (!super.optimizeNames(names, constants5))
90352
90352
  return;
90353
- this.iterable = optimizeExpr(this.iterable, names, constants3);
90353
+ this.iterable = optimizeExpr(this.iterable, names, constants5);
90354
90354
  return this;
90355
90355
  }
90356
90356
  get names() {
@@ -90392,11 +90392,11 @@ var require_codegen = __commonJS({
90392
90392
  (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNodes();
90393
90393
  return this;
90394
90394
  }
90395
- optimizeNames(names, constants3) {
90395
+ optimizeNames(names, constants5) {
90396
90396
  var _a, _b;
90397
- super.optimizeNames(names, constants3);
90398
- (_a = this.catch) === null || _a === void 0 ? void 0 : _a.optimizeNames(names, constants3);
90399
- (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants3);
90397
+ super.optimizeNames(names, constants5);
90398
+ (_a = this.catch) === null || _a === void 0 ? void 0 : _a.optimizeNames(names, constants5);
90399
+ (_b = this.finally) === null || _b === void 0 ? void 0 : _b.optimizeNames(names, constants5);
90400
90400
  return this;
90401
90401
  }
90402
90402
  get names() {
@@ -90697,7 +90697,7 @@ var require_codegen = __commonJS({
90697
90697
  function addExprNames(names, from14) {
90698
90698
  return from14 instanceof code_1._CodeOrName ? addNames(names, from14.names) : names;
90699
90699
  }
90700
- function optimizeExpr(expr, names, constants3) {
90700
+ function optimizeExpr(expr, names, constants5) {
90701
90701
  if (expr instanceof code_1.Name)
90702
90702
  return replaceName(expr);
90703
90703
  if (!canOptimize(expr))
@@ -90712,14 +90712,14 @@ var require_codegen = __commonJS({
90712
90712
  return items;
90713
90713
  }, []));
90714
90714
  function replaceName(n) {
90715
- const c = constants3[n.str];
90715
+ const c = constants5[n.str];
90716
90716
  if (c === void 0 || names[n.str] !== 1)
90717
90717
  return n;
90718
90718
  delete names[n.str];
90719
90719
  return c;
90720
90720
  }
90721
90721
  function canOptimize(e) {
90722
- return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants3[c.str] !== void 0);
90722
+ return e instanceof code_1._Code && e._items.some((c) => c instanceof code_1.Name && names[c.str] === 1 && constants5[c.str] !== void 0);
90723
90723
  }
90724
90724
  }
90725
90725
  function subtractNames(names, from14) {
@@ -92699,7 +92699,7 @@ var require_compile = __commonJS({
92699
92699
  const schOrFunc = root2.refs[ref];
92700
92700
  if (schOrFunc)
92701
92701
  return schOrFunc;
92702
- let _sch = resolve.call(this, root2, ref);
92702
+ let _sch = resolve3.call(this, root2, ref);
92703
92703
  if (_sch === void 0) {
92704
92704
  const schema = (_a = root2.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
92705
92705
  const { schemaId } = this.opts;
@@ -92726,7 +92726,7 @@ var require_compile = __commonJS({
92726
92726
  function sameSchemaEnv(s1, s2) {
92727
92727
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
92728
92728
  }
92729
- function resolve(root2, ref) {
92729
+ function resolve3(root2, ref) {
92730
92730
  let sch;
92731
92731
  while (typeof (sch = this.refs[ref]) == "string")
92732
92732
  ref = sch;
@@ -93356,21 +93356,21 @@ var require_fast_uri = __commonJS({
93356
93356
  normalizeString(uri, options);
93357
93357
  } else if (typeof uri === "object") {
93358
93358
  uri = /** @type {T} */
93359
- parse3(serialize(uri, options), options);
93359
+ parse5(serialize(uri, options), options);
93360
93360
  }
93361
93361
  return uri;
93362
93362
  }
93363
- function resolve(baseURI, relativeURI, options) {
93363
+ function resolve3(baseURI, relativeURI, options) {
93364
93364
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
93365
- const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
93365
+ const resolved = resolveComponent(parse5(baseURI, schemelessOptions), parse5(relativeURI, schemelessOptions), schemelessOptions, true);
93366
93366
  schemelessOptions.skipEscape = true;
93367
93367
  return serialize(resolved, schemelessOptions);
93368
93368
  }
93369
93369
  function resolveComponent(base2, relative, options, skipNormalization) {
93370
93370
  const target = {};
93371
93371
  if (!skipNormalization) {
93372
- base2 = parse3(serialize(base2, options), options);
93373
- relative = parse3(serialize(relative, options), options);
93372
+ base2 = parse5(serialize(base2, options), options);
93373
+ relative = parse5(serialize(relative, options), options);
93374
93374
  }
93375
93375
  options = options || {};
93376
93376
  if (!options.tolerant && relative.scheme) {
@@ -93593,7 +93593,7 @@ var require_fast_uri = __commonJS({
93593
93593
  }
93594
93594
  return { parsed, malformedAuthorityOrPort };
93595
93595
  }
93596
- function parse3(uri, opts) {
93596
+ function parse5(uri, opts) {
93597
93597
  return parseWithStatus(uri, opts).parsed;
93598
93598
  }
93599
93599
  function normalizeString(uri, opts) {
@@ -93618,11 +93618,11 @@ var require_fast_uri = __commonJS({
93618
93618
  var fastUri = {
93619
93619
  SCHEMES,
93620
93620
  normalize,
93621
- resolve,
93621
+ resolve: resolve3,
93622
93622
  resolveComponent,
93623
93623
  equal,
93624
93624
  serialize,
93625
- parse: parse3
93625
+ parse: parse5
93626
93626
  };
93627
93627
  module.exports = fastUri;
93628
93628
  module.exports.default = fastUri;
@@ -97837,8 +97837,8 @@ function paymentMiddleware(routes, server2, paywallConfig, paywall, syncFacilita
97837
97837
  let bufferedCalls = [];
97838
97838
  let settled = false;
97839
97839
  let endCalled;
97840
- const endPromise = new Promise((resolve) => {
97841
- endCalled = resolve;
97840
+ const endPromise = new Promise((resolve3) => {
97841
+ endCalled = resolve3;
97842
97842
  });
97843
97843
  res.writeHead = function(...args) {
97844
97844
  if (!settled) {
@@ -100907,7 +100907,7 @@ var require_ms = __commonJS({
100907
100907
  options = options || {};
100908
100908
  var type = typeof val;
100909
100909
  if (type === "string" && val.length > 0) {
100910
- return parse3(val);
100910
+ return parse5(val);
100911
100911
  } else if (type === "number" && isFinite(val)) {
100912
100912
  return options.long ? fmtLong(val) : fmtShort(val);
100913
100913
  }
@@ -100915,7 +100915,7 @@ var require_ms = __commonJS({
100915
100915
  "val is not a non-empty string or a valid number. val=" + JSON.stringify(val)
100916
100916
  );
100917
100917
  };
100918
- function parse3(str2) {
100918
+ function parse5(str2) {
100919
100919
  str2 = String(str2);
100920
100920
  if (str2.length > 100) {
100921
100921
  return;
@@ -104457,9 +104457,9 @@ var init_socket3 = __esm({
104457
104457
  * @return a Promise that will be fulfilled when the server acknowledges the event
104458
104458
  */
104459
104459
  emitWithAck(ev, ...args) {
104460
- return new Promise((resolve, reject) => {
104460
+ return new Promise((resolve3, reject) => {
104461
104461
  const fn = (arg1, arg2) => {
104462
- return arg1 ? reject(arg1) : resolve(arg2);
104462
+ return arg1 ? reject(arg1) : resolve3(arg2);
104463
104463
  };
104464
104464
  fn.withError = true;
104465
104465
  args.push(fn);
@@ -105532,7 +105532,7 @@ var init_eventSubscriber = __esm({
105532
105532
  this.apiKey = apiKey;
105533
105533
  }
105534
105534
  async connect() {
105535
- return new Promise((resolve, reject) => {
105535
+ return new Promise((resolve3, reject) => {
105536
105536
  this.socket = lookup(`${this.apiUrl}/events`, {
105537
105537
  auth: { apiKey: this.apiKey },
105538
105538
  transports: ["websocket"],
@@ -105541,7 +105541,7 @@ var init_eventSubscriber = __esm({
105541
105541
  this.socket.on("connect", () => {
105542
105542
  this.isConnected = true;
105543
105543
  console.error("\u2705 Connected to Ametyst Events WebSocket");
105544
- resolve();
105544
+ resolve3();
105545
105545
  });
105546
105546
  this.socket.on("connectionStatus", (status) => {
105547
105547
  console.error("\u{1F4E1} Blockchain connection status:", status);
@@ -106359,33 +106359,74 @@ var init_dist = __esm({
106359
106359
  });
106360
106360
 
106361
106361
  // src/config/paths.ts
106362
- import { existsSync, mkdirSync } from "fs";
106362
+ import { accessSync, constants, existsSync, mkdirSync } from "fs";
106363
106363
  import { homedir } from "os";
106364
- import { join } from "path";
106364
+ import { join, parse as parse3, resolve } from "path";
106365
106365
  function ensureDirectories() {
106366
106366
  if (!existsSync(AMETYST_DIR)) mkdirSync(AMETYST_DIR, { mode: 448 });
106367
106367
  if (!existsSync(WALLETS_DIR)) mkdirSync(WALLETS_DIR, { mode: 448 });
106368
106368
  }
106369
- function loopsRoot() {
106370
- return join(process.cwd(), `.ametyst${ENV_SUFFIX}`, "loops");
106369
+ function isFilesystemRoot(dir) {
106370
+ const abs = resolve(dir);
106371
+ return parse3(abs).root === abs;
106371
106372
  }
106372
- function loopDir(slug) {
106373
+ function whyUnusable(dir, deps) {
106374
+ if (isFilesystemRoot(dir)) return "it is the filesystem root, not a project folder";
106375
+ if (!deps.existsSync(dir)) return "it does not exist";
106376
+ try {
106377
+ deps.accessSync(dir, constants.W_OK);
106378
+ } catch (err) {
106379
+ const code = err?.code;
106380
+ return `it is not writable${code ? ` (${code})` : ""}`;
106381
+ }
106382
+ return void 0;
106383
+ }
106384
+ function resolveRunRoot(explicitDir, deps = {}) {
106385
+ const probes = { existsSync: deps.existsSync ?? existsSync, accessSync: deps.accessSync ?? accessSync };
106386
+ const rejected = [];
106387
+ const explicit = typeof explicitDir === "string" ? explicitDir.trim() : "";
106388
+ if (explicit) {
106389
+ const abs = resolve(explicit);
106390
+ const why = whyUnusable(abs, probes);
106391
+ if (!why) return { root: abs, reason: "explicit" };
106392
+ rejected.push({ dir: abs, why });
106393
+ }
106394
+ let cwd;
106395
+ try {
106396
+ cwd = (deps.cwd ?? (() => process.cwd()))();
106397
+ } catch (err) {
106398
+ rejected.push({ dir: "<cwd>", why: `it cannot be read (${err instanceof Error ? err.message : String(err)})` });
106399
+ }
106400
+ if (cwd !== void 0) {
106401
+ const why = whyUnusable(cwd, probes);
106402
+ if (!why) return { root: cwd, reason: "cwd", ...rejected.length ? { rejected } : {} };
106403
+ rejected.push({ dir: cwd, why });
106404
+ }
106405
+ const home = deps.homedir ? deps.homedir() : void 0;
106406
+ const fallback2 = home === void 0 ? join(AMETYST_DIR, "runs") : join(home, `.ametyst${ENV_SUFFIX}`, "runs");
106407
+ (deps.mkdirSync ?? mkdirSync)(fallback2, { recursive: true, mode: 448 });
106408
+ return { root: fallback2, reason: "fallback", rejected };
106409
+ }
106410
+ function loopsRoot(runRoot) {
106411
+ return join(runRoot ?? resolveRunRoot().root, `.ametyst${ENV_SUFFIX}`, "loops");
106412
+ }
106413
+ function loopDir(slug, runRoot) {
106373
106414
  const safe = String(slug).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, "");
106374
106415
  if (!safe) throw new Error(`invalid loop slug: ${JSON.stringify(slug)}`);
106375
- return join(loopsRoot(), safe);
106416
+ return join(loopsRoot(runRoot), safe);
106376
106417
  }
106377
- function loopFiresRoot(slug) {
106378
- return join(loopDir(slug), "fires");
106418
+ function loopFiresRoot(slug, runRoot) {
106419
+ return join(loopDir(slug, runRoot), "fires");
106379
106420
  }
106380
- function loopFireDir(slug, fireId) {
106421
+ function loopFireDir(slug, fireId, runRoot) {
106381
106422
  const safe = String(fireId).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, "");
106382
106423
  if (!safe) throw new Error(`invalid fire id: ${JSON.stringify(fireId)}`);
106383
- return join(loopFiresRoot(slug), safe);
106424
+ return join(loopFiresRoot(slug, runRoot), safe);
106384
106425
  }
106385
- function refusedConstraintsPath(slug, fireId) {
106426
+ function refusedConstraintsPath(slug, fireId, runRoot) {
106386
106427
  const safe = String(fireId).toLowerCase().replace(/[^a-z0-9-]/g, "-").replace(/^-+|-+$/g, "");
106387
106428
  if (!safe) throw new Error(`invalid fire id: ${JSON.stringify(fireId)}`);
106388
- return join(loopDir(slug), ".state", `constraints-refused-${safe}.md`);
106429
+ return join(loopDir(slug, runRoot), ".state", `constraints-refused-${safe}.md`);
106389
106430
  }
106390
106431
  function skillsRoot(target = "claude", global2 = false) {
106391
106432
  return join(global2 ? homedir() : process.cwd(), SKILLS_DIR_BY_TARGET[target], "skills");
@@ -107040,7 +107081,7 @@ var require_text = __commonJS({
107040
107081
  "node_modules/.pnpm/prompts@2.4.2/node_modules/prompts/dist/elements/text.js"(exports, module) {
107041
107082
  "use strict";
107042
107083
  init_esm_shims();
107043
- function asyncGeneratorStep(gen2, resolve, reject, _next, _throw, key, arg) {
107084
+ function asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, key, arg) {
107044
107085
  try {
107045
107086
  var info = gen2[key](arg);
107046
107087
  var value2 = info.value;
@@ -107049,7 +107090,7 @@ var require_text = __commonJS({
107049
107090
  return;
107050
107091
  }
107051
107092
  if (info.done) {
107052
- resolve(value2);
107093
+ resolve3(value2);
107053
107094
  } else {
107054
107095
  Promise.resolve(value2).then(_next, _throw);
107055
107096
  }
@@ -107057,13 +107098,13 @@ var require_text = __commonJS({
107057
107098
  function _asyncToGenerator(fn) {
107058
107099
  return function() {
107059
107100
  var self2 = this, args = arguments;
107060
- return new Promise(function(resolve, reject) {
107101
+ return new Promise(function(resolve3, reject) {
107061
107102
  var gen2 = fn.apply(self2, args);
107062
107103
  function _next(value2) {
107063
- asyncGeneratorStep(gen2, resolve, reject, _next, _throw, "next", value2);
107104
+ asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, "next", value2);
107064
107105
  }
107065
107106
  function _throw(err) {
107066
- asyncGeneratorStep(gen2, resolve, reject, _next, _throw, "throw", err);
107107
+ asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, "throw", err);
107067
107108
  }
107068
107109
  _next(void 0);
107069
107110
  });
@@ -107792,7 +107833,7 @@ var require_date = __commonJS({
107792
107833
  "node_modules/.pnpm/prompts@2.4.2/node_modules/prompts/dist/elements/date.js"(exports, module) {
107793
107834
  "use strict";
107794
107835
  init_esm_shims();
107795
- function asyncGeneratorStep(gen2, resolve, reject, _next, _throw, key, arg) {
107836
+ function asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, key, arg) {
107796
107837
  try {
107797
107838
  var info = gen2[key](arg);
107798
107839
  var value2 = info.value;
@@ -107801,7 +107842,7 @@ var require_date = __commonJS({
107801
107842
  return;
107802
107843
  }
107803
107844
  if (info.done) {
107804
- resolve(value2);
107845
+ resolve3(value2);
107805
107846
  } else {
107806
107847
  Promise.resolve(value2).then(_next, _throw);
107807
107848
  }
@@ -107809,13 +107850,13 @@ var require_date = __commonJS({
107809
107850
  function _asyncToGenerator(fn) {
107810
107851
  return function() {
107811
107852
  var self2 = this, args = arguments;
107812
- return new Promise(function(resolve, reject) {
107853
+ return new Promise(function(resolve3, reject) {
107813
107854
  var gen2 = fn.apply(self2, args);
107814
107855
  function _next(value2) {
107815
- asyncGeneratorStep(gen2, resolve, reject, _next, _throw, "next", value2);
107856
+ asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, "next", value2);
107816
107857
  }
107817
107858
  function _throw(err) {
107818
- asyncGeneratorStep(gen2, resolve, reject, _next, _throw, "throw", err);
107859
+ asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, "throw", err);
107819
107860
  }
107820
107861
  _next(void 0);
107821
107862
  });
@@ -108019,7 +108060,7 @@ var require_number = __commonJS({
108019
108060
  "node_modules/.pnpm/prompts@2.4.2/node_modules/prompts/dist/elements/number.js"(exports, module) {
108020
108061
  "use strict";
108021
108062
  init_esm_shims();
108022
- function asyncGeneratorStep(gen2, resolve, reject, _next, _throw, key, arg) {
108063
+ function asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, key, arg) {
108023
108064
  try {
108024
108065
  var info = gen2[key](arg);
108025
108066
  var value2 = info.value;
@@ -108028,7 +108069,7 @@ var require_number = __commonJS({
108028
108069
  return;
108029
108070
  }
108030
108071
  if (info.done) {
108031
- resolve(value2);
108072
+ resolve3(value2);
108032
108073
  } else {
108033
108074
  Promise.resolve(value2).then(_next, _throw);
108034
108075
  }
@@ -108036,13 +108077,13 @@ var require_number = __commonJS({
108036
108077
  function _asyncToGenerator(fn) {
108037
108078
  return function() {
108038
108079
  var self2 = this, args = arguments;
108039
- return new Promise(function(resolve, reject) {
108080
+ return new Promise(function(resolve3, reject) {
108040
108081
  var gen2 = fn.apply(self2, args);
108041
108082
  function _next(value2) {
108042
- asyncGeneratorStep(gen2, resolve, reject, _next, _throw, "next", value2);
108083
+ asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, "next", value2);
108043
108084
  }
108044
108085
  function _throw(err) {
108045
- asyncGeneratorStep(gen2, resolve, reject, _next, _throw, "throw", err);
108086
+ asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, "throw", err);
108046
108087
  }
108047
108088
  _next(void 0);
108048
108089
  });
@@ -108467,7 +108508,7 @@ var require_autocomplete = __commonJS({
108467
108508
  "node_modules/.pnpm/prompts@2.4.2/node_modules/prompts/dist/elements/autocomplete.js"(exports, module) {
108468
108509
  "use strict";
108469
108510
  init_esm_shims();
108470
- function asyncGeneratorStep(gen2, resolve, reject, _next, _throw, key, arg) {
108511
+ function asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, key, arg) {
108471
108512
  try {
108472
108513
  var info = gen2[key](arg);
108473
108514
  var value2 = info.value;
@@ -108476,7 +108517,7 @@ var require_autocomplete = __commonJS({
108476
108517
  return;
108477
108518
  }
108478
108519
  if (info.done) {
108479
- resolve(value2);
108520
+ resolve3(value2);
108480
108521
  } else {
108481
108522
  Promise.resolve(value2).then(_next, _throw);
108482
108523
  }
@@ -108484,13 +108525,13 @@ var require_autocomplete = __commonJS({
108484
108525
  function _asyncToGenerator(fn) {
108485
108526
  return function() {
108486
108527
  var self2 = this, args = arguments;
108487
- return new Promise(function(resolve, reject) {
108528
+ return new Promise(function(resolve3, reject) {
108488
108529
  var gen2 = fn.apply(self2, args);
108489
108530
  function _next(value2) {
108490
- asyncGeneratorStep(gen2, resolve, reject, _next, _throw, "next", value2);
108531
+ asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, "next", value2);
108491
108532
  }
108492
108533
  function _throw(err) {
108493
- asyncGeneratorStep(gen2, resolve, reject, _next, _throw, "throw", err);
108534
+ asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, "throw", err);
108494
108535
  }
108495
108536
  _next(void 0);
108496
108537
  });
@@ -109126,7 +109167,7 @@ var require_dist = __commonJS({
109126
109167
  for (var i = 0, arr22 = new Array(len); i < len; i++) arr22[i] = arr2[i];
109127
109168
  return arr22;
109128
109169
  }
109129
- function asyncGeneratorStep(gen2, resolve, reject, _next, _throw, key, arg) {
109170
+ function asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, key, arg) {
109130
109171
  try {
109131
109172
  var info = gen2[key](arg);
109132
109173
  var value2 = info.value;
@@ -109135,7 +109176,7 @@ var require_dist = __commonJS({
109135
109176
  return;
109136
109177
  }
109137
109178
  if (info.done) {
109138
- resolve(value2);
109179
+ resolve3(value2);
109139
109180
  } else {
109140
109181
  Promise.resolve(value2).then(_next, _throw);
109141
109182
  }
@@ -109143,13 +109184,13 @@ var require_dist = __commonJS({
109143
109184
  function _asyncToGenerator(fn) {
109144
109185
  return function() {
109145
109186
  var self2 = this, args = arguments;
109146
- return new Promise(function(resolve, reject) {
109187
+ return new Promise(function(resolve3, reject) {
109147
109188
  var gen2 = fn.apply(self2, args);
109148
109189
  function _next(value2) {
109149
- asyncGeneratorStep(gen2, resolve, reject, _next, _throw, "next", value2);
109190
+ asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, "next", value2);
109150
109191
  }
109151
109192
  function _throw(err) {
109152
- asyncGeneratorStep(gen2, resolve, reject, _next, _throw, "throw", err);
109193
+ asyncGeneratorStep(gen2, resolve3, reject, _next, _throw, "throw", err);
109153
109194
  }
109154
109195
  _next(void 0);
109155
109196
  });
@@ -112026,6 +112067,7 @@ var init_core = __esm({
112026
112067
  var grant_keystore_exports = {};
112027
112068
  __export(grant_keystore_exports, {
112028
112069
  GRANT_ENTRY_FORMAT: () => GRANT_ENTRY_FORMAT,
112070
+ MissingGrantKeyError: () => MissingGrantKeyError,
112029
112071
  buildGrantVault: () => buildGrantVault,
112030
112072
  createGrantKeyIssuer: () => createGrantKeyIssuer,
112031
112073
  deleteGrantEntry: () => deleteGrantEntry,
@@ -112033,6 +112075,8 @@ __export(grant_keystore_exports, {
112033
112075
  generateGrantKey: () => generateGrantKey,
112034
112076
  grantEntryPath: () => grantEntryPath,
112035
112077
  grantsDir: () => grantsDir,
112078
+ hasGrantSigningKey: () => hasGrantSigningKey,
112079
+ isMissingGrantKeyError: () => isMissingGrantKeyError,
112036
112080
  listGrantAddresses: () => listGrantAddresses,
112037
112081
  listGrantEntries: () => listGrantEntries,
112038
112082
  missingGrantKeyMessage: () => missingGrantKeyMessage,
@@ -112180,6 +112224,19 @@ function deleteGrantEntry(address, dir) {
112180
112224
  function missingGrantKeyMessage(address) {
112181
112225
  return `no local key for grant address ${address} \u2014 this machine cannot sign for that grant. Run requestAccess again to mint a fresh session key and have your admin approve it.`;
112182
112226
  }
112227
+ function isMissingGrantKeyError(err) {
112228
+ return err instanceof MissingGrantKeyError;
112229
+ }
112230
+ function hasGrantSigningKey(params) {
112231
+ let address;
112232
+ try {
112233
+ address = normalizeGrantAddress(params.address);
112234
+ } catch {
112235
+ return false;
112236
+ }
112237
+ if (readGrantEntry(address, params.dir)) return true;
112238
+ return typeof params.vaultAddress === "string" && params.vaultAddress.toLowerCase() === address;
112239
+ }
112183
112240
  function resolveGrantSigningKey(params) {
112184
112241
  const address = normalizeGrantAddress(params.address);
112185
112242
  const entry = readGrantEntry(address, params.dir);
@@ -112190,7 +112247,7 @@ function resolveGrantSigningKey(params) {
112190
112247
  if (params.vaultJson && typeof vaultAddress === "string" && vaultAddress.toLowerCase() === address) {
112191
112248
  return readVaultPrivateKey(params.vaultJson, params.passphrase);
112192
112249
  }
112193
- throw new Error(missingGrantKeyMessage(address));
112250
+ throw new MissingGrantKeyError(address);
112194
112251
  }
112195
112252
  function createGrantKeyIssuer(options) {
112196
112253
  return {
@@ -112214,7 +112271,7 @@ function createGrantKeyIssuer(options) {
112214
112271
  }
112215
112272
  };
112216
112273
  }
112217
- var GRANT_ENTRY_FORMAT, ADDRESS_RE2;
112274
+ var GRANT_ENTRY_FORMAT, ADDRESS_RE2, MissingGrantKeyError;
112218
112275
  var init_grant_keystore = __esm({
112219
112276
  "src/wallet/grant-keystore.ts"() {
112220
112277
  "use strict";
@@ -112225,6 +112282,14 @@ var init_grant_keystore = __esm({
112225
112282
  init_plaintext_vault();
112226
112283
  GRANT_ENTRY_FORMAT = "grant-key-v1";
112227
112284
  ADDRESS_RE2 = /^0x[0-9a-fA-F]{40}$/;
112285
+ MissingGrantKeyError = class extends Error {
112286
+ grantAddress;
112287
+ constructor(address) {
112288
+ super(missingGrantKeyMessage(address));
112289
+ this.name = "MissingGrantKeyError";
112290
+ this.grantAddress = address;
112291
+ }
112292
+ };
112228
112293
  }
112229
112294
  });
112230
112295
 
@@ -112412,7 +112477,7 @@ var init_version5 = __esm({
112412
112477
  "src/version.ts"() {
112413
112478
  "use strict";
112414
112479
  init_esm_shims();
112415
- CLI_VERSION = true ? "0.3.6" : "0.0.0-dev";
112480
+ CLI_VERSION = true ? "0.3.8" : "0.0.0-dev";
112416
112481
  }
112417
112482
  });
112418
112483
 
@@ -113753,8 +113818,8 @@ function sqliteWasmDriver(db, raw) {
113753
113818
  init: () => Promise.resolve(),
113754
113819
  acquireConnection: async () => {
113755
113820
  while (inUse) await inUse;
113756
- inUse = new Promise((resolve) => {
113757
- release = resolve;
113821
+ inUse = new Promise((resolve3) => {
113822
+ release = resolve3;
113758
113823
  });
113759
113824
  return connection;
113760
113825
  },
@@ -113768,10 +113833,10 @@ function sqliteWasmDriver(db, raw) {
113768
113833
  await conn.executeQuery(raw("rollback"));
113769
113834
  },
113770
113835
  releaseConnection: () => {
113771
- const resolve = release;
113836
+ const resolve3 = release;
113772
113837
  inUse = void 0;
113773
113838
  release = void 0;
113774
- resolve?.();
113839
+ resolve3?.();
113775
113840
  return Promise.resolve();
113776
113841
  },
113777
113842
  destroy: () => {
@@ -113886,8 +113951,8 @@ var init_engine_store = __esm({
113886
113951
  SCHEMA_VERSION = "1.0.0";
113887
113952
  SCHEMA_NAMESPACE = "ametyst_connections";
113888
113953
  IN_MEMORY_DB = ":memory:";
113889
- sleep = (ms) => new Promise((resolve) => {
113890
- setTimeout(resolve, ms);
113954
+ sleep = (ms) => new Promise((resolve3) => {
113955
+ setTimeout(resolve3, ms);
113891
113956
  });
113892
113957
  monotonicNowMs = () => performance.now();
113893
113958
  CAUSE_CHAIN_MAX_DEPTH = 8;
@@ -114178,8 +114243,8 @@ import { createServer as createServer4 } from "http";
114178
114243
  async function startOAuthCallbackListener(options = {}) {
114179
114244
  let settle = null;
114180
114245
  let fail2 = null;
114181
- const received = new Promise((resolve, reject) => {
114182
- settle = resolve;
114246
+ const received = new Promise((resolve3, reject) => {
114247
+ settle = resolve3;
114183
114248
  fail2 = reject;
114184
114249
  });
114185
114250
  const server2 = createServer4((req, res) => {
@@ -114200,12 +114265,12 @@ async function startOAuthCallbackListener(options = {}) {
114200
114265
  else if (!code) fail2?.(new Error("The provider's callback carried no authorization code."));
114201
114266
  else settle?.({ code, state });
114202
114267
  });
114203
- await new Promise((resolve) => server2.listen(0, "127.0.0.1", resolve));
114268
+ await new Promise((resolve3) => server2.listen(0, "127.0.0.1", resolve3));
114204
114269
  const address = server2.address();
114205
114270
  const port = typeof address === "object" && address ? address.port : 0;
114206
- const close = () => new Promise((resolve) => {
114271
+ const close = () => new Promise((resolve3) => {
114207
114272
  server2.closeAllConnections?.();
114208
- server2.close(() => resolve());
114273
+ server2.close(() => resolve3());
114209
114274
  });
114210
114275
  return {
114211
114276
  redirectUri: `http://127.0.0.1:${port}${OAUTH_CALLBACK_PATH2}`,
@@ -114293,7 +114358,7 @@ init_credentials();
114293
114358
  // src/config/host-registry.ts
114294
114359
  init_esm_shims();
114295
114360
  init_resolve();
114296
- import { accessSync, constants, existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync5, statSync, writeFileSync as writeFileSync5 } from "fs";
114361
+ import { accessSync as accessSync2, constants as constants2, existsSync as existsSync5, mkdirSync as mkdirSync5, readFileSync as readFileSync5, statSync, writeFileSync as writeFileSync5 } from "fs";
114297
114362
  import { homedir as homedir4 } from "os";
114298
114363
  import { delimiter, dirname as dirname4, isAbsolute, join as join4 } from "path";
114299
114364
 
@@ -114638,7 +114703,7 @@ function findBinary(name, env = process.env) {
114638
114703
  const candidate = join4(dir, name);
114639
114704
  try {
114640
114705
  if (!statSync(candidate).isFile()) continue;
114641
- accessSync(candidate, constants.X_OK);
114706
+ accessSync2(candidate, constants2.X_OK);
114642
114707
  return candidate;
114643
114708
  } catch {
114644
114709
  }
@@ -115271,8 +115336,8 @@ async function readJson(url2, apiKey) {
115271
115336
  function withSourceTimeout(work) {
115272
115337
  return Promise.race([
115273
115338
  work,
115274
- new Promise((resolve) => {
115275
- setTimeout(() => resolve(null), SOURCE_TIMEOUT_MS).unref();
115339
+ new Promise((resolve3) => {
115340
+ setTimeout(() => resolve3(null), SOURCE_TIMEOUT_MS).unref();
115276
115341
  })
115277
115342
  ]);
115278
115343
  }
@@ -115738,6 +115803,56 @@ function findCurrentApprovedWallet(wallets, eoaAddress, pendingWalletId) {
115738
115803
  );
115739
115804
  }
115740
115805
 
115806
+ // src/mcp-server/signer-binding.ts
115807
+ init_esm_shims();
115808
+ var BINDING_DERIVED_KEYS = [
115809
+ "virtualWalletKernelAccountClient",
115810
+ "permissionPlugin",
115811
+ "kernelDomain",
115812
+ "policyPrecheckPassed"
115813
+ ];
115814
+ function nonEmpty(value2) {
115815
+ return typeof value2 === "string" && value2.trim() !== "" ? value2 : void 0;
115816
+ }
115817
+ function sameAddress(a, b) {
115818
+ return String(a ?? "").toLowerCase() === String(b ?? "").toLowerCase();
115819
+ }
115820
+ function signerBindingMoved(state, row) {
115821
+ const rowId = row?.id != null ? String(row.id) : void 0;
115822
+ const rowAddress = nonEmpty(row?.address);
115823
+ if (state.virtualWalletId && rowId && state.virtualWalletId !== rowId) return true;
115824
+ if (state.signerAddress && rowAddress && !sameAddress(state.signerAddress, rowAddress)) return true;
115825
+ return false;
115826
+ }
115827
+ function bindSignerToGrantRow(state, row) {
115828
+ const changed = signerBindingMoved(state, row);
115829
+ if (changed) {
115830
+ for (const key of BINDING_DERIVED_KEYS) delete state[key];
115831
+ }
115832
+ const rowAddress = nonEmpty(row?.address);
115833
+ if (rowAddress) state.signerAddress = rowAddress;
115834
+ const rowWalletAddress = nonEmpty(row?.walletAddress) ?? nonEmpty(row?.kernelAccountAddress);
115835
+ const rowPaymentManagerAddress = nonEmpty(row?.paymentManagerAddress);
115836
+ const rowPolicyId = row?.policyAssociated != null ? String(row.policyAssociated) : void 0;
115837
+ const rowId = row?.id != null ? String(row.id) : void 0;
115838
+ if (changed) {
115839
+ state.walletAddress = rowWalletAddress;
115840
+ state.paymentManagerAddress = rowPaymentManagerAddress;
115841
+ state.policyId = rowPolicyId;
115842
+ state.policyOnchainPermissions = nonEmpty(row?.policyOnchainPermissions);
115843
+ } else {
115844
+ state.walletAddress = rowWalletAddress ?? state.walletAddress;
115845
+ state.paymentManagerAddress = rowPaymentManagerAddress ?? state.paymentManagerAddress;
115846
+ state.policyId = rowPolicyId ?? state.policyId;
115847
+ state.policyOnchainPermissions = nonEmpty(row?.policyOnchainPermissions) ?? state.policyOnchainPermissions;
115848
+ }
115849
+ if (rowId) state.virtualWalletId = rowId;
115850
+ if (row?.policyName != null) state.policyName = String(row.policyName);
115851
+ if (row?.policyValidUntil != null) state.policyValidUntil = BigInt(row.policyValidUntil);
115852
+ state.authorizationStatus = "approved";
115853
+ return { changed, signerAddress: state.signerAddress };
115854
+ }
115855
+
115741
115856
  // src/mcp-server/start-session.ts
115742
115857
  init_esm_shims();
115743
115858
  init_dist();
@@ -116049,11 +116164,11 @@ function clearWalletScopedCredentials(target) {
116049
116164
  delete target[key];
116050
116165
  }
116051
116166
  }
116052
- function sameAddress(a, b) {
116167
+ function sameAddress2(a, b) {
116053
116168
  return String(a ?? "").toLowerCase() === String(b ?? "").toLowerCase();
116054
116169
  }
116055
116170
  function mergeStartSessionCredentials(target, patch, responseKey, options = {}) {
116056
- const walletChanged = patch.eoaAddress !== void 0 && !sameAddress(patch.eoaAddress, target.eoaAddress);
116171
+ const walletChanged = patch.eoaAddress !== void 0 && !sameAddress2(patch.eoaAddress, target.eoaAddress);
116057
116172
  if (walletChanged || options.grantChanged) {
116058
116173
  clearWalletScopedCredentials(target);
116059
116174
  }
@@ -116102,7 +116217,7 @@ function esc(value2) {
116102
116217
  return value2.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
116103
116218
  }
116104
116219
  function readBody(req) {
116105
- return new Promise((resolve) => {
116220
+ return new Promise((resolve3) => {
116106
116221
  let data = "";
116107
116222
  let over = false;
116108
116223
  req.setEncoding("utf-8");
@@ -116112,14 +116227,14 @@ function readBody(req) {
116112
116227
  if (data.length > MAX_BODY_BYTES) {
116113
116228
  over = true;
116114
116229
  data = "";
116115
- resolve({ body: "", tooLarge: true });
116230
+ resolve3({ body: "", tooLarge: true });
116116
116231
  }
116117
116232
  });
116118
116233
  req.on("end", () => {
116119
- if (!over) resolve({ body: data, tooLarge: false });
116234
+ if (!over) resolve3({ body: data, tooLarge: false });
116120
116235
  });
116121
116236
  req.on("error", () => {
116122
- if (!over) resolve({ body: "", tooLarge: false });
116237
+ if (!over) resolve3({ body: "", tooLarge: false });
116123
116238
  });
116124
116239
  });
116125
116240
  }
@@ -116257,18 +116372,18 @@ async function startUnlockListener(deps) {
116257
116372
  expiryTimer = void 0;
116258
116373
  }
116259
116374
  resolveDone(state);
116260
- return new Promise((resolve) => {
116375
+ return new Promise((resolve3) => {
116261
116376
  try {
116262
- server2.close(() => resolve());
116377
+ server2.close(() => resolve3());
116263
116378
  setTimeout(() => {
116264
116379
  try {
116265
116380
  server2.closeAllConnections?.();
116266
116381
  } catch {
116267
116382
  }
116268
- resolve();
116383
+ resolve3();
116269
116384
  }, 50).unref?.();
116270
116385
  } catch {
116271
- resolve();
116386
+ resolve3();
116272
116387
  }
116273
116388
  });
116274
116389
  };
@@ -116436,12 +116551,12 @@ async function startUnlockListener(deps) {
116436
116551
  }
116437
116552
  });
116438
116553
  });
116439
- const listened = await new Promise((resolve) => {
116554
+ const listened = await new Promise((resolve3) => {
116440
116555
  let settled = false;
116441
116556
  const settle = (value2) => {
116442
116557
  if (settled) return;
116443
116558
  settled = true;
116444
- resolve(value2);
116559
+ resolve3(value2);
116445
116560
  };
116446
116561
  try {
116447
116562
  server2.once("error", (err) => {
@@ -116943,9 +117058,9 @@ async function buildMerchantErrorHelp(opts) {
116943
117058
  let timer;
116944
117059
  const fetched = await Promise.race([
116945
117060
  opts.fetchInstructions(provider),
116946
- new Promise((resolve) => {
117061
+ new Promise((resolve3) => {
116947
117062
  timer = setTimeout(
116948
- () => resolve({ status: "nok", error: `instructions fetch timed out after ${timeoutMs}ms` }),
117063
+ () => resolve3({ status: "nok", error: `instructions fetch timed out after ${timeoutMs}ms` }),
116949
117064
  timeoutMs
116950
117065
  );
116951
117066
  })
@@ -117746,8 +117861,8 @@ var TASK_DEFINITION_FILES = [
117746
117861
  ["dashboardHtml", "dashboard.html", "dashboardHtml"],
117747
117862
  ["dashboardManifest", "dashboard.manifest.json", "dashboardManifest"]
117748
117863
  ];
117749
- function materializeTask(task, runId) {
117750
- const dir = loopFireDir(task.slug, runId);
117864
+ function materializeTask(task, runId, runRoot) {
117865
+ const dir = loopFireDir(task.slug, runId, runRoot);
117751
117866
  mkdirSync7(dir, { recursive: true, mode: 448 });
117752
117867
  const files = {};
117753
117868
  const skipped = [];
@@ -117907,18 +118022,18 @@ function startDashboardServer(args) {
117907
118022
  }
117908
118023
  }
117909
118024
  };
117910
- const bind = (port) => new Promise((resolve) => {
118025
+ const bind = (port) => new Promise((resolve3) => {
117911
118026
  const server2 = make(handler);
117912
118027
  server2.once("error", (err) => {
117913
118028
  try {
117914
118029
  server2.close();
117915
118030
  } catch {
117916
118031
  }
117917
- resolve({ ok: false, err });
118032
+ resolve3({ ok: false, err });
117918
118033
  });
117919
118034
  server2.listen(port, "127.0.0.1", () => {
117920
118035
  server2.unref();
117921
- resolve({
118036
+ resolve3({
117922
118037
  ok: true,
117923
118038
  handle: {
117924
118039
  server: server2,
@@ -119350,12 +119465,12 @@ async function openBridgeConnection(socketPath, deps = {}) {
119350
119465
  } catch {
119351
119466
  return null;
119352
119467
  }
119353
- const opened = await new Promise((resolve) => {
119468
+ const opened = await new Promise((resolve3) => {
119354
119469
  let settled = false;
119355
119470
  const done = (ok) => {
119356
119471
  if (settled) return;
119357
119472
  settled = true;
119358
- resolve(ok);
119473
+ resolve3(ok);
119359
119474
  };
119360
119475
  socket.once("connect", () => done(true));
119361
119476
  socket.once("error", () => done(false));
@@ -119375,17 +119490,17 @@ async function openBridgeConnection(socketPath, deps = {}) {
119375
119490
  for (const frame of frames) {
119376
119491
  const res = parseBridgeResponse(frame);
119377
119492
  if (!res) continue;
119378
- const resolve = pending.get(res.id);
119379
- if (resolve) {
119493
+ const resolve3 = pending.get(res.id);
119494
+ if (resolve3) {
119380
119495
  pending.delete(res.id);
119381
- resolve(res);
119496
+ resolve3(res);
119382
119497
  }
119383
119498
  }
119384
119499
  });
119385
119500
  const failAll = (error) => {
119386
119501
  closed = true;
119387
- for (const [id, resolve] of pending) {
119388
- resolve({ v: BRIDGE_PROTOCOL_VERSION, id, ok: false, error });
119502
+ for (const [id, resolve3] of pending) {
119503
+ resolve3({ v: BRIDGE_PROTOCOL_VERSION, id, ok: false, error });
119389
119504
  }
119390
119505
  pending.clear();
119391
119506
  };
@@ -119396,10 +119511,10 @@ async function openBridgeConnection(socketPath, deps = {}) {
119396
119511
  if (closed) {
119397
119512
  return Promise.resolve({ v: BRIDGE_PROTOCOL_VERSION, id, ok: false, error: "bridge_closed" });
119398
119513
  }
119399
- return new Promise((resolve) => {
119514
+ return new Promise((resolve3) => {
119400
119515
  const timer = setTimeout(() => {
119401
119516
  pending.delete(id);
119402
- resolve({
119517
+ resolve3({
119403
119518
  v: BRIDGE_PROTOCOL_VERSION,
119404
119519
  id,
119405
119520
  ok: false,
@@ -119410,7 +119525,7 @@ async function openBridgeConnection(socketPath, deps = {}) {
119410
119525
  if (typeof timer.unref === "function") timer.unref();
119411
119526
  pending.set(id, (res) => {
119412
119527
  clearTimeout(timer);
119413
- resolve(res);
119528
+ resolve3(res);
119414
119529
  });
119415
119530
  socket.write(encodeFrame({ ...req, v: BRIDGE_PROTOCOL_VERSION, id, clientPid, nonce }));
119416
119531
  });
@@ -119614,7 +119729,7 @@ function createShimHandler(deps) {
119614
119729
  }
119615
119730
  var TOO_LARGE = /* @__PURE__ */ Symbol.for("ametyst.delegate.shim.too-large");
119616
119731
  function readBody2(req) {
119617
- return new Promise((resolve) => {
119732
+ return new Promise((resolve3) => {
119618
119733
  let data = "";
119619
119734
  let over = false;
119620
119735
  req.setEncoding("utf-8");
@@ -119624,14 +119739,14 @@ function readBody2(req) {
119624
119739
  if (data.length > MAX_FRAME_BYTES) {
119625
119740
  over = true;
119626
119741
  data = "";
119627
- resolve(TOO_LARGE);
119742
+ resolve3(TOO_LARGE);
119628
119743
  }
119629
119744
  });
119630
119745
  req.on("end", () => {
119631
- if (!over) resolve(data);
119746
+ if (!over) resolve3(data);
119632
119747
  });
119633
119748
  req.on("error", () => {
119634
- if (!over) resolve(data);
119749
+ if (!over) resolve3(data);
119635
119750
  });
119636
119751
  });
119637
119752
  }
@@ -119643,17 +119758,17 @@ async function startShim(deps) {
119643
119758
  res.end(JSON.stringify({ error: { message: "shim failure", type: "internal_error" } }));
119644
119759
  });
119645
119760
  });
119646
- await new Promise((resolve, reject) => {
119761
+ await new Promise((resolve3, reject) => {
119647
119762
  server2.once("error", reject);
119648
- server2.listen(0, "127.0.0.1", () => resolve());
119763
+ server2.listen(0, "127.0.0.1", () => resolve3());
119649
119764
  });
119650
119765
  const port = server2.address().port;
119651
119766
  return {
119652
119767
  port,
119653
119768
  baseURL: `http://127.0.0.1:${port}/v1`,
119654
- close: () => new Promise((resolve) => {
119769
+ close: () => new Promise((resolve3) => {
119655
119770
  server2.closeAllConnections?.();
119656
- server2.close(() => resolve());
119771
+ server2.close(() => resolve3());
119657
119772
  })
119658
119773
  };
119659
119774
  }
@@ -120304,25 +120419,26 @@ function killChild(child, signal, detached, kill = (pid, sig) => process.kill(pi
120304
120419
  function collectStream(child, which, onChunk) {
120305
120420
  const stream = child[which];
120306
120421
  if (!stream) return Promise.resolve("");
120307
- return new Promise((resolve) => {
120422
+ return new Promise((resolve3) => {
120308
120423
  let data = "";
120309
120424
  stream.setEncoding("utf-8");
120310
120425
  stream.on("data", (chunk) => {
120311
120426
  data += chunk;
120312
120427
  onChunk(chunk);
120313
120428
  });
120314
- stream.on("end", () => resolve(data));
120315
- stream.on("error", () => resolve(data));
120429
+ stream.on("end", () => resolve3(data));
120430
+ stream.on("error", () => resolve3(data));
120316
120431
  });
120317
120432
  }
120318
120433
  function waitForExit(child) {
120319
- return new Promise((resolve) => {
120320
- child.on("close", (code) => resolve(code));
120321
- child.on("error", () => resolve(1));
120434
+ return new Promise((resolve3) => {
120435
+ child.on("close", (code) => resolve3(code));
120436
+ child.on("error", () => resolve3(1));
120322
120437
  });
120323
120438
  }
120324
120439
 
120325
120440
  // src/delegate/jobs.ts
120441
+ init_paths();
120326
120442
  var DEFAULT_DELEGATE_TIMEOUT_MS = 30 * 6e4;
120327
120443
  var MAX_DELEGATE_TIMEOUT_MS = MAX_DELEGATE_DEADLINE_MS;
120328
120444
  function resolveDelegateTimeoutMs(env = process.env) {
@@ -120384,9 +120500,10 @@ function validateStartInput(input, deps = {}) {
120384
120500
  message: "delegate_start needs `model` \u2014 the model slug the openrouter passthrough should run, e.g. openai/gpt-5-mini."
120385
120501
  };
120386
120502
  }
120387
- const dir = typeof input.dir === "string" && input.dir.trim() ? input.dir.trim() : (deps.cwd ?? (() => process.cwd()))();
120503
+ const explicitDir = typeof input.dir === "string" && input.dir.trim() ? input.dir.trim() : "";
120504
+ const dir = explicitDir || resolveRunRoot(void 0, { ...deps.runRoot, ...deps.cwd ? { cwd: deps.cwd } : {} }).root;
120388
120505
  const isDirectory = deps.isDirectory;
120389
- if (isDirectory && !isDirectory(dir)) {
120506
+ if (explicitDir && isDirectory && !isDirectory(dir)) {
120390
120507
  return {
120391
120508
  ok: false,
120392
120509
  error: "dir_not_found",
@@ -120855,23 +120972,23 @@ async function startDelegateBridge(deps) {
120855
120972
  socket.on("close", () => sockets.delete(socket));
120856
120973
  };
120857
120974
  const server2 = (deps.createServer ?? ((h) => createNetServer(h)))(onConnection);
120858
- const listening = await new Promise((resolve) => {
120975
+ const listening = await new Promise((resolve3) => {
120859
120976
  server2.once("error", (err) => {
120860
120977
  log(`[delegate-bridge] listen failed: ${errText(err)}`);
120861
- resolve(false);
120978
+ resolve3(false);
120862
120979
  });
120863
120980
  try {
120864
- server2.listen(socketPath, () => resolve(true));
120981
+ server2.listen(socketPath, () => resolve3(true));
120865
120982
  } catch (err) {
120866
120983
  log(`[delegate-bridge] listen threw: ${errText(err)}`);
120867
- resolve(false);
120984
+ resolve3(false);
120868
120985
  }
120869
120986
  });
120870
120987
  if (!listening) return null;
120871
120988
  const close = async () => {
120872
120989
  for (const s of sockets) s.destroy();
120873
120990
  sockets.clear();
120874
- await new Promise((resolve) => server2.close(() => resolve()));
120991
+ await new Promise((resolve3) => server2.close(() => resolve3()));
120875
120992
  try {
120876
120993
  fs.rmSync(socketPath, { force: true });
120877
120994
  } catch {
@@ -121919,6 +122036,49 @@ function signingKeyForAddress(address, passphrase) {
121919
122036
  passphrase: passphrase ?? currentCredentials.passphrase
121920
122037
  });
121921
122038
  }
122039
+ async function refreshSignerBinding() {
122040
+ if (!currentCredentials.apiKey) return { changed: false, address: currentCredentials.signerAddress };
122041
+ let wallets;
122042
+ try {
122043
+ wallets = await fetchVirtualWalletsFromBackend(currentCredentials.apiKey, true);
122044
+ } catch (err) {
122045
+ console.error(
122046
+ `\u26A0\uFE0F [signer-binding] could not re-read the grants \u2014 signing with the cached binding (${currentCredentials.signerAddress ?? "none"}): ${err instanceof Error ? err.message : String(err)}`
122047
+ );
122048
+ wallets = walletsCache || [];
122049
+ }
122050
+ const row = currentCredentials.pendingWalletId ? findCurrentApprovedWallet(wallets, ownedSigningAddresses(), currentCredentials.pendingWalletId) : selectNewestApprovedWalletAmong(
122051
+ wallets,
122052
+ (Array.isArray(wallets) ? wallets : []).map((w) => w?.address)
122053
+ );
122054
+ if (!row) return { changed: false, address: currentCredentials.signerAddress };
122055
+ const previousSigner = currentCredentials.signerAddress;
122056
+ const { changed, signerAddress } = bindSignerToGrantRow(currentCredentials, row);
122057
+ if (changed) {
122058
+ console.error(
122059
+ `\u{1F501} [signer-binding] the active grant moved \u2014 signer ${previousSigner ?? "none"} -> ${signerAddress ?? "none"} (virtual wallet ${currentCredentials.virtualWalletId}, policy ${currentCredentials.policyId ?? "unknown"}). Dropping the signer state derived from the old grant.`
122060
+ );
122061
+ }
122062
+ return { changed, address: signerAddress };
122063
+ }
122064
+ async function resolveSignerForMaterialization(passphrase) {
122065
+ await refreshSignerBinding();
122066
+ const address = currentCredentials.signerAddress || currentCredentials.eoaAddress || "";
122067
+ if (!address) {
122068
+ throw new Error(
122069
+ "no signer address for this session \u2014 no approved grant and no install wallet. Run requestAccess first."
122070
+ );
122071
+ }
122072
+ return { address, privateKey: signingKeyForAddress(address, passphrase) };
122073
+ }
122074
+ function hasSigningKeyForAddress(address) {
122075
+ if (!address) return false;
122076
+ try {
122077
+ return hasGrantSigningKey({ address, vaultAddress: currentCredentials.eoaAddress });
122078
+ } catch {
122079
+ return false;
122080
+ }
122081
+ }
121922
122082
  var plaintextVaultMode = false;
121923
122083
  function refreshPlaintextVaultMode() {
121924
122084
  const vault = currentCredentials.walletKeystoreJson;
@@ -122763,7 +122923,7 @@ async function refreshGetAllowlistDescription() {
122763
122923
  }
122764
122924
  } catch (err) {
122765
122925
  console.warn("[mcp] fetchCapabilityIndex attempt 1 failed:", err);
122766
- await new Promise((resolve) => setTimeout(resolve, 2e3));
122926
+ await new Promise((resolve3) => setTimeout(resolve3, 2e3));
122767
122927
  try {
122768
122928
  index2 = await fetchCapabilityIndex(currentCredentials.apiKey, true);
122769
122929
  if (index2 === null) {
@@ -122799,7 +122959,7 @@ async function refreshGetAllowlistDescription() {
122799
122959
  const msg = first.err instanceof Error ? first.err.message : String(first.err);
122800
122960
  if (msg.includes("Not connected")) {
122801
122961
  } else {
122802
- await new Promise((resolve) => setTimeout(resolve, 500));
122962
+ await new Promise((resolve3) => setTimeout(resolve3, 500));
122803
122963
  const second = await tryNotify();
122804
122964
  if (!second.ok) {
122805
122965
  console.error("[capability-index] tools/list_changed failed twice", second.err);
@@ -122897,7 +123057,7 @@ async function refreshDynamicPrompts() {
122897
123057
  } else {
122898
123058
  const msg = first.err instanceof Error ? first.err.message : String(first.err);
122899
123059
  if (!msg.includes("Not connected")) {
122900
- await new Promise((resolve) => setTimeout(resolve, 500));
123060
+ await new Promise((resolve3) => setTimeout(resolve3, 500));
122901
123061
  const second = await tryNotify();
122902
123062
  if (!second.ok) console.error("[dynamic-prompts] prompts/list_changed failed twice", second.err);
122903
123063
  }
@@ -122983,12 +123143,15 @@ async function initializeCredentials(walletKeystoreJson, eoaAddress, config) {
122983
123143
  const wallets = walletsCache || [];
122984
123144
  const approvedWallet = findCurrentApprovedWallet(
122985
123145
  wallets,
122986
- eoaAddress,
123146
+ ownedSigningAddresses(),
122987
123147
  currentCredentials.pendingWalletId
122988
123148
  );
122989
123149
  if (approvedWallet) {
122990
123150
  console.error("\u2705 Found approved wallet from backend \u2014 authorization data stored");
122991
123151
  currentCredentials.authorizationStatus = "approved";
123152
+ if (typeof approvedWallet.address === "string" && approvedWallet.address.trim() !== "") {
123153
+ currentCredentials.signerAddress = approvedWallet.address;
123154
+ }
122992
123155
  currentCredentials.virtualWalletStatus = approvedWallet.status;
122993
123156
  currentCredentials.walletAddress = approvedWallet.walletAddress || approvedWallet.kernelAccountAddress;
122994
123157
  currentCredentials.virtualWalletId = String(approvedWallet.id);
@@ -123035,10 +123198,9 @@ async function createKernelClientFromVault() {
123035
123198
  throw new Error("No passphrase or keystore available");
123036
123199
  }
123037
123200
  if (!cliConfig) throw new Error("CLI config not initialized");
123038
- let privateKey = signingKeyForAddress(
123039
- currentCredentials.signerAddress || currentCredentials.eoaAddress || ""
123040
- );
123041
- console.error(`${ts()} Wallet key loaded`);
123201
+ const signer = await resolveSignerForMaterialization();
123202
+ let privateKey = signer.privateKey;
123203
+ console.error(`${ts()} Wallet key loaded \u2014 signing as ${signer.address}`);
123042
123204
  try {
123043
123205
  const { virtualWalletsManagers: virtualWalletsManagers2, financialAccounts: financialAccounts2 } = await getSDK();
123044
123206
  console.error(`${ts()} Fetching wallet data by API key...`);
@@ -123164,7 +123326,7 @@ var approvalWaitConfig = (() => {
123164
123326
  return {
123165
123327
  attempts,
123166
123328
  intervalMs,
123167
- delay: (ms) => new Promise((resolve) => setTimeout(resolve, ms))
123329
+ delay: (ms) => new Promise((resolve3) => setTimeout(resolve3, ms))
123168
123330
  };
123169
123331
  })();
123170
123332
  async function tryResolvePendingApproval(probe) {
@@ -123799,7 +123961,7 @@ server.tool(
123799
123961
  server.tool(
123800
123962
  {
123801
123963
  name: "getWalletStatus",
123802
- description: "Get wallet status: auth, balance, policy, allowlist, WHICH GRANT AND KEY THIS SESSION SIGNS WITH, WHICH WORKSPACE this server is acting in, and the last 10 transactions (amount, merchant, timestamp, status). `signerAddress` is the address of the approved grant this session signs with \u2014 since every access request now mints its OWN ephemeral session key, it is NOT the same as `eoaAddress` (the install wallet) except for a grant approved before rotation; `activeVirtualWalletId` / `activePolicyId` name that grant's row. `workspace` is `{companyName, employeeName}` \u2014 the Ametyst workspace every task, memory document and payment from this server lands in; both fields are null when the profile could not be read, which means UNKNOWN, never 'no workspace'. A transaction `amount` is a EUR display string like `\u20AC0.0126`, or the em dash `\u2014` when the row carries no usable amount (none recorded, or a value that is not a base-units integer) \u2014 `\u2014` means UNKNOWN, never zero. The unformatted base-units value is on `amountRaw`, which is null for exactly those rows.",
123964
+ description: "Get wallet status: auth, balance, policy, allowlist, WHICH GRANT AND KEY THIS SESSION SIGNS WITH, WHICH WORKSPACE this server is acting in, and the last 10 transactions (amount, merchant, timestamp, status). `signerAddress` is the address of the approved grant this session signs with \u2014 since every access request now mints its OWN ephemeral session key, it is NOT the same as `eoaAddress` (the install wallet) except for a grant approved before rotation; `activeVirtualWalletId` / `activePolicyId` name that grant's row, and `signerKeyPresent` says whether this machine still holds the private key for `signerAddress` \u2014 `false` means no spend can be signed until `requestAccess` mints a fresh session key and an admin approves it. `workspace` is `{companyName, employeeName}` \u2014 the Ametyst workspace every task, memory document and payment from this server lands in; both fields are null when the profile could not be read, which means UNKNOWN, never 'no workspace'. A transaction `amount` is a EUR display string like `\u20AC0.0126`, or the em dash `\u2014` when the row carries no usable amount (none recorded, or a value that is not a base-units integer) \u2014 `\u2014` means UNKNOWN, never zero. The unformatted base-units value is on `amountRaw`, which is null for exactly those rows.",
123803
123965
  inputs: []
123804
123966
  },
123805
123967
  async () => {
@@ -123834,6 +123996,9 @@ server.tool(
123834
123996
  const freshWallet = selectNewestApprovedWalletAmong(freshWallets, ownedSigningAddresses());
123835
123997
  const freshWalletIsActiveGrant = String(freshWallet?.id) === String(currentCredentials.virtualWalletId);
123836
123998
  if (freshWallet && freshWalletIsActiveGrant) {
123999
+ if (typeof freshWallet.address === "string" && freshWallet.address.trim() !== "") {
124000
+ currentCredentials.signerAddress = freshWallet.address;
124001
+ }
123837
124002
  if (freshWallet.policyAssociated != null) {
123838
124003
  currentCredentials.policyId = String(freshWallet.policyAssociated);
123839
124004
  }
@@ -123860,6 +124025,16 @@ server.tool(
123860
124025
  // "which key signed this" readable from a payload instead of from a
123861
124026
  // nonce-key autopsy — the same lesson as `activeVirtualWalletId` below.
123862
124027
  signerAddress: currentCredentials.signerAddress || currentCredentials.eoaAddress || null,
124028
+ // CAN THIS MACHINE ACTUALLY SIGN FOR THAT GRANT? A rotated grant is
124029
+ // signable only from the per-grant keystore entry minted with it, and a
124030
+ // machine that lost it (a re-install, a restored home, a grant approved
124031
+ // on another laptop) is bound to a signer it cannot produce. Presence
124032
+ // only — no decryption, so an encrypted vault with no cached passphrase
124033
+ // still reports `true` here and bounces at spend time on the passphrase,
124034
+ // which is a different and recoverable problem.
124035
+ signerKeyPresent: hasSigningKeyForAddress(
124036
+ currentCredentials.signerAddress || currentCredentials.eoaAddress
124037
+ ),
123863
124038
  walletAddress: currentCredentials.walletAddress || null,
123864
124039
  kernelClientActive: !!currentCredentials.virtualWalletKernelAccountClient,
123865
124040
  // WHICH GRANT THIS SESSION SIGNS WITH. The 2026-09-01 incident — three
@@ -124357,7 +124532,9 @@ server.tool(
124357
124532
  toolName: "getTask",
124358
124533
  responseKey: "tasks",
124359
124534
  resolve: (sdk, apiKey, intent, category) => sdk.tasks.resolve(apiKey, intent, category),
124360
- sayToUser: "Present these matching tasks to the user, briefly explain them, and ask which one to run before proceeding. Run the one they pick with runTask.",
124535
+ // Same wording as the slash-prompt directive (src/tasks/task-run-section.ts): after the pick,
124536
+ // ASK HOW to run it — a run mode is a spend decision, so no surface picks one silently.
124537
+ sayToUser: "Present these matching tasks to the user, briefly explain them, and ask which one to run before proceeding. Then, before running the one they pick, ASK HOW to run it and wait for an answer \u2014 always ask, never pick one silently: (1) one-time, in this chat, followed here; (2) one-time, headless in its own process via `ametyst task run <slug>`; (3) scheduled, recurring via `ametyst task schedule <slug> --every <dur>` (ask which cadence). Only then call runTask with the chosen mode (`in-chat` for 1, `headless` for 2) \u2014 for 3, hand the user the schedule command instead.",
124361
124538
  resolverFailedSayToUser: "Couldn't search tasks right now.",
124362
124539
  surfaceRawBodies: true,
124363
124540
  fetchManifest: (sdk, apiKey, slug) => readTaskManifest(sdk, apiKey, slug)
@@ -124481,7 +124658,13 @@ async function runTaskCore(params, flavor) {
124481
124658
  if (resolved.mode === "headless") return headless(resolved.source);
124482
124659
  }
124483
124660
  const memoryDocKey = defaultDocKey(normalizeMemoryManifest(entity?.stateDocs ?? null));
124484
- const materialized = flavor.materialize(entity, randomUUID4());
124661
+ const runRoot = resolveRunRoot(typeof params.dir === "string" ? params.dir : void 0);
124662
+ if (runRoot.reason === "fallback") {
124663
+ console.error(
124664
+ `(${entity.slug}: run folder anchored on the fallback ${runRoot.root} \u2014 ${(runRoot.rejected ?? []).map((r) => `${r.dir}: ${r.why}`).join("; ")})`
124665
+ );
124666
+ }
124667
+ const materialized = flavor.materialize(entity, randomUUID4(), runRoot.root);
124485
124668
  const docBoot = await materializeMemoryDocs(sdk, apiKey, entity, materialized.dir);
124486
124669
  for (const note of docBoot.notes) console.error(`(${entity.slug} memory docs: ${note})`);
124487
124670
  const runFiles = { ...materialized.files, ...docBoot.files };
@@ -124494,6 +124677,10 @@ async function runTaskCore(params, flavor) {
124494
124677
  mode: "in-chat",
124495
124678
  ...modeSource ? { modeSource } : {},
124496
124679
  dir: materialized.dir,
124680
+ // Which root the folder hangs off and why — `fallback` means "not under your project".
124681
+ runRoot: runRoot.root,
124682
+ runRootReason: runRoot.reason,
124683
+ ...runRoot.rejected?.length ? { runRootRejected: runRoot.rejected } : {},
124497
124684
  ...dashboardUrl ? { dashboard: dashboardUrl } : {},
124498
124685
  blastRadius: est,
124499
124686
  files: runFiles,
@@ -124503,7 +124690,7 @@ async function runTaskCore(params, flavor) {
124503
124690
  // the slug because the run context carries no task identity — which is exactly why
124504
124691
  // the taskMemory* tools take an explicit `taskSlug`.
124505
124692
  memory: taskMemoryBlock(entity.slug, memoryDocKey),
124506
- directive: flavor.buildDirective({ dir: materialized.dir, slug: entity.slug, files: runFiles, docKey: memoryDocKey }),
124693
+ directive: flavor.buildDirective({ dir: materialized.dir, slug: entity.slug, files: runFiles, docKey: memoryDocKey, runRoot }),
124507
124694
  ...shipBack ? { shipBack } : {}
124508
124695
  }) }, { type: "text", text: dashboardLine }] };
124509
124696
  } catch (error) {
@@ -124517,7 +124704,8 @@ server.tool(
124517
124704
  description: "Run a workspace TASK after the user has confirmed it (getTask already presented + stopped). A task is the unified card \u2014 what used to be a 'compound skill' or a 'loop' is one row now, and this ONE tool runs either. Two modes: `in-chat` (default) materializes the task's definition files locally and returns them plus a directive so YOU execute it inline in this session, paying for any step via the `spend` tool; `headless` returns the shell command to run it unattended in its own process. Only the NON-EMPTY definition files are materialized \u2014 a compound-shaped task (no VISION/CONSTRAINTS) gets just SKILL.md (+README.md) and NO constraints ship-back, instead of empty files that look checked but say nothing. DEFAULT RUN MODE: when you OMIT `mode` (or pass it empty), the task body's YAML frontmatter is consulted for a `defaultRunMode: headless|in-chat` key and that is used; an explicit `mode` wins over it. The ONLY accepted values are `in-chat` and `headless` \u2014 anything else (a typo like `in-chatt`) is REJECTED with `invalid_mode` and nothing runs: a value you passed is never quietly ignored, never coerced, and never falls back to the frontmatter, because that would answer an explicit `in-chat` with an unattended headless run. The response reports `modeSource` (explicit / frontmatter / default) so you can see which one decided.",
124518
124705
  inputs: [
124519
124706
  { name: "task", type: "string", required: true, description: "Slug or id of the task to run (as returned by getTask)." },
124520
- { name: "mode", type: "string", required: false, description: 'Exactly "in-chat" (you run it inline now) or "headless" (run unattended via `ametyst task run`) \u2014 any other value is rejected with `invalid_mode` rather than coerced or ignored. Omit it (or pass empty) to use the task body\'s `defaultRunMode` frontmatter, falling back to "in-chat". An explicit value wins over the frontmatter.' }
124707
+ { name: "mode", type: "string", required: false, description: 'Exactly "in-chat" (you run it inline now) or "headless" (run unattended via `ametyst task run`) \u2014 any other value is rejected with `invalid_mode` rather than coerced or ignored. Omit it (or pass empty) to use the task body\'s `defaultRunMode` frontmatter, falling back to "in-chat". An explicit value wins over the frontmatter.' },
124708
+ { name: "dir", type: "string", required: false, description: "Directory to materialize and run in; defaults to the current project folder, falling back to a writable per-user location when there is none. The response reports the chosen root as `runRoot` and why as `runRootReason` (explicit | cwd | fallback)." }
124521
124709
  ]
124522
124710
  },
124523
124711
  async (params) => runTaskCore(params, {
@@ -124532,12 +124720,13 @@ server.tool(
124532
124720
  headlessCommand: (ref) => `ametyst task run ${ref}`,
124533
124721
  headlessSayToUser: (ref) => `Run \`ametyst task run ${ref}\` in a terminal \u2014 it materializes the task, runs it unattended, and ships back improvements on a clean finish. (\`task run\` is the unattended runner for every task row, whatever the task was originally authored as.) Paid steps go through your on-chain policy.`,
124534
124722
  honorFrontmatterDefault: true,
124535
- materialize: (task, runId) => materializeTask(task, runId),
124536
- buildDirective: ({ dir, slug, files, docKey }) => {
124723
+ materialize: (task, runId, runRoot) => materializeTask(task, runId, runRoot),
124724
+ buildDirective: ({ dir, slug, files, docKey, runRoot }) => {
124537
124725
  const present = Object.entries(files).filter(([label2]) => label2 !== "status").map(([, filename]) => filename);
124726
+ const whereNote = runRoot.reason === "fallback" ? `NOTE: this run's folder lives under the per-user fallback ${runRoot.root}, NOT under the current project, because the current folder was not writable (${(runRoot.rejected ?? []).map((r) => `${r.dir}: ${r.why}`).join("; ")}). Read the files from ${dir} exactly as given \u2014 do not go looking for them in the project. ` : "";
124538
124727
  const readDoc = typeof docKey === "string" ? `taskMemoryGet({ taskSlug: "${slug}", docKey: "${docKey}" }) for the "${docKey}" document (the first one this task declares), then ` : `this task declares NO memory document \u2014 do not read or create one; read `;
124539
124728
  const writeDoc = typeof docKey === "string" ? `, and rewrite the "${docKey}" document with taskMemoryAppend({ taskSlug: "${slug}", docKey: "${docKey}", content: "..." })` : ` \u2014 and NO document upsert, because this task declares none`;
124540
- return `Read the task files in ${dir} \u2014 the ONLY files materialized are: ${present.join(", ")} (plus STATUS.md, this run's own state). SKILL.md drives${files.vision ? "; VISION.md = done-condition" : ""}${files.constraints ? "; CONSTRAINTS.md = hard limits" : ""}. Any definition file NOT listed was empty on the task and was deliberately not written \u2014 do not go looking for it, and do not assume limits you cannot read. If the task has a QUEUE of work items it is EXTERNAL \u2014 NOT one of these files; SKILL.md tells you WHERE to read the queue from and WHERE to write the results. Execute the task here, in this session, until it is done (or, if it is a looping task, until VISION is met / the queue is drained). Pay for any step ONLY via the spend tool (the on-chain policy is the budget). Keep ${dir}/STATUS.md updated. CLEAN UP AFTER YOURSELF: on a CLEAN finish (done / queue drained, no brake), DELETE the ${dir} folder \u2014 it is this run's scratch space, not a record, and every run gets its own, so leaving them behind piles up orphans. On a dirty stop, leave ${dir} in place so the run can be resumed.
124729
+ return `${whereNote}Read the task files in ${dir} \u2014 the ONLY files materialized are: ${present.join(", ")} (plus STATUS.md, this run's own state). SKILL.md drives${files.vision ? "; VISION.md = done-condition" : ""}${files.constraints ? "; CONSTRAINTS.md = hard limits" : ""}. Any definition file NOT listed was empty on the task and was deliberately not written \u2014 do not go looking for it, and do not assume limits you cannot read. If the task has a QUEUE of work items it is EXTERNAL \u2014 NOT one of these files; SKILL.md tells you WHERE to read the queue from and WHERE to write the results. Execute the task here, in this session, until it is done (or, if it is a looping task, until VISION is met / the queue is drained). Pay for any step ONLY via the spend tool (the on-chain policy is the budget). Keep ${dir}/STATUS.md updated. CLEAN UP AFTER YOURSELF: on a CLEAN finish (done / queue drained, no brake), DELETE the ${dir} folder \u2014 it is this run's scratch space, not a record, and every run gets its own, so leaving them behind piles up orphans. On a dirty stop, leave ${dir} in place so the run can be resumed.
124541
124730
 
124542
124731
  Your durable memory is available via the taskMemory* tools with taskSlug "${slug}" \u2014 and it, not ${dir}, is what survives this run. Nothing from it was injected into this run: READ WHAT YOU NEED FIRST with taskMemoryGet \u2014 ${readDoc}one list per record kind you need, taskMemoryGet({ taskSlug: "${slug}", records: true, kind: "<kind>" }) (latest version per key, archived=false by default); empty means this is the first run. WRITE A RUN RECORD BEFORE EXITING, on every path including a brake: taskMemoryAppend({ taskSlug: "${slug}", kind: "run", content: "<what you did, what you learned, what the next run should pick up>" })${writeDoc}.
124543
124732
 
@@ -125336,11 +125525,13 @@ server.tool(
125336
125525
  };
125337
125526
  }
125338
125527
  touchWalletActivity();
125528
+ let missingSignerKey;
125339
125529
  if (!currentCredentials.virtualWalletKernelAccountClient && currentCredentials.authorizationStatus === "approved" && isWalletUnlocked()) {
125340
125530
  try {
125341
125531
  console.error("\u{1F504} [spend] Auto-creating kernel client...");
125342
125532
  await createKernelClientFromVault();
125343
125533
  } catch (kcErr) {
125534
+ if (isMissingGrantKeyError(kcErr)) missingSignerKey = kcErr;
125344
125535
  console.error("\u274C [spend] Auto kernel client creation failed:", kcErr instanceof Error ? kcErr.message : String(kcErr));
125345
125536
  }
125346
125537
  }
@@ -125396,6 +125587,28 @@ server.tool(
125396
125587
  const apiKey = currentCredentials.apiKey;
125397
125588
  if (!kernelClient || !apiKey) {
125398
125589
  console.error("\u26A0\uFE0F [spend] Missing kernel client or API key in state");
125590
+ if (missingSignerKey) {
125591
+ logSpendTelemetryEarlyErr();
125592
+ return {
125593
+ content: [
125594
+ {
125595
+ type: "text",
125596
+ text: JSON.stringify({
125597
+ success: false,
125598
+ ...disclosePayment(),
125599
+ // PRE-PAYMENT
125600
+ error: "signer_key_missing",
125601
+ detail: missingSignerKey.message,
125602
+ guidance: {
125603
+ say_to_user: "This machine can't sign for your approved access any more \u2014 the session key it was issued to isn't here. I need to request access again so a fresh key can be approved.",
125604
+ next_action: "Call getAvailablePolicies(), let the user pick a policy, then call requestAccess with it. Once the admin approves the new request, retry this spend.",
125605
+ stop: true
125606
+ }
125607
+ })
125608
+ }
125609
+ ]
125610
+ };
125611
+ }
125399
125612
  if (currentCredentials.authorizationStatus === "pending") {
125400
125613
  logSpendTelemetryEarlyErr();
125401
125614
  return {
@@ -126590,8 +126803,8 @@ import { join as join19 } from "path";
126590
126803
  // src/compounds/sync-skills.ts
126591
126804
  init_esm_shims();
126592
126805
  init_paths();
126593
- import { existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync5, readFileSync as readFileSync14, rmSync, writeFileSync as writeFileSync10 } from "fs";
126594
- import { join as join18 } from "path";
126806
+ import { accessSync as accessSync3, constants as constants3, existsSync as existsSync14, mkdirSync as mkdirSync9, readdirSync as readdirSync5, readFileSync as readFileSync14, rmSync, writeFileSync as writeFileSync10 } from "fs";
126807
+ import { dirname as dirname8, join as join18, parse as parse4, resolve as resolve2 } from "path";
126595
126808
  var MANAGED_MARKER = "<!-- ametyst-managed: sync-skills -->";
126596
126809
  var GITIGNORE_HEADER = "# ametyst-managed: sync-skills \u2014 pointer skills generated for this account; never commit them.";
126597
126810
  var GITIGNORE_HEADER_2 = "# Maintained by `ametyst serve` on every boot. Real skills without the managed marker are not listed.";
@@ -126671,9 +126884,46 @@ function maintainGitignore(root2) {
126671
126884
  writeFileSync10(file, buildGitignoreContent(managed));
126672
126885
  return "written";
126673
126886
  }
126887
+ function resolveSkillsScope(target, deps = {}) {
126888
+ const exists = deps.existsSync ?? existsSync14;
126889
+ const access = deps.accessSync ?? accessSync3;
126890
+ let cwd;
126891
+ try {
126892
+ cwd = (deps.cwd ?? (() => process.cwd()))();
126893
+ } catch (err) {
126894
+ const why2 = `the current directory cannot be read (${err instanceof Error ? err.message : String(err)})`;
126895
+ return { global: true, root: skillsRoot(target, true), fallback: { from: "<cwd>", why: why2 } };
126896
+ }
126897
+ const local = join18(cwd, SKILLS_DIR_BY_TARGET2[target], "skills");
126898
+ const abs = resolve2(cwd);
126899
+ let why;
126900
+ if (parse4(abs).root === abs) {
126901
+ why = "the current directory is the filesystem root, not a project folder";
126902
+ } else if (!exists(abs)) {
126903
+ why = `the current directory ${abs} does not exist`;
126904
+ } else {
126905
+ let probe = local;
126906
+ while (!exists(probe)) {
126907
+ const parent = dirname8(probe);
126908
+ if (parent === probe) break;
126909
+ probe = parent;
126910
+ }
126911
+ try {
126912
+ access(probe, constants3.W_OK);
126913
+ } catch (err) {
126914
+ const code = err?.code;
126915
+ why = `${probe} is not writable${code ? ` (${code})` : ""}`;
126916
+ }
126917
+ }
126918
+ if (why === void 0) return { global: false, root: local };
126919
+ return { global: true, root: skillsRoot(target, true), fallback: { from: local, why } };
126920
+ }
126921
+ var SKILLS_DIR_BY_TARGET2 = { claude: ".claude", codex: ".codex" };
126674
126922
  async function syncSkills(opts = {}) {
126675
- const global2 = opts.global ?? false;
126676
126923
  const target = opts.target ?? "claude";
126924
+ const scope = opts.global ? { global: true, root: skillsRoot(target, true) } : resolveSkillsScope(target);
126925
+ const global2 = scope.global;
126926
+ const fallback2 = "fallback" in scope ? scope.fallback : void 0;
126677
126927
  const { sdk, apiKey } = await getCliSdk();
126678
126928
  const [compRes, loopRes] = await Promise.all([sdk.compoundedSkills.list(apiKey), sdk.loops.list(apiKey)]);
126679
126929
  if (compRes?.status !== "ok") throw new Error(`failed to list compounds: ${compRes?.error ?? "unknown error"}`);
@@ -126732,7 +126982,7 @@ async function syncSkills(opts = {}) {
126732
126982
  pruned++;
126733
126983
  }
126734
126984
  const gitignore = global2 ? "none" : maintainGitignore(root2);
126735
- return { root: root2, written, pruned, skipped, gitignore };
126985
+ return { root: root2, written, pruned, skipped, gitignore, ...fallback2 ? { fallback: fallback2 } : {} };
126736
126986
  }
126737
126987
 
126738
126988
  // src/commands/autosync-skills.ts
@@ -126775,7 +127025,7 @@ async function autoSyncSkillsOnBoot(deps = {}) {
126775
127025
  try {
126776
127026
  const r = await sync(target);
126777
127027
  log(
126778
- `\u2705 skills autosync [${target}]: ${r.written} written, ${r.pruned} pruned` + (r.skipped.length ? `, ${r.skipped.length} skipped (unmanaged)` : "")
127028
+ `\u2705 skills autosync [${target}]: ${r.written} written, ${r.pruned} pruned` + (r.skipped.length ? `, ${r.skipped.length} skipped (unmanaged)` : "") + ` \u2192 ${r.root}` + (r.fallback ? ` (fallback to the home root: ${r.fallback.why}; project-local ${r.fallback.from} was not used)` : "")
126779
127029
  );
126780
127030
  } catch (err) {
126781
127031
  log(
@@ -127439,8 +127689,8 @@ init_paths();
127439
127689
  import { mkdirSync as mkdirSync10, writeFileSync as writeFileSync11 } from "fs";
127440
127690
  import { join as join20 } from "path";
127441
127691
  var MIRRORED_DEFINITION_FILES = ["SKILL.md", "VISION.md", "README.md"];
127442
- function materialize(loop2, fireId, stateDocs = []) {
127443
- const dir = loopFireDir(loop2.slug, fireId);
127692
+ function materialize(loop2, fireId, stateDocs = [], runRoot) {
127693
+ const dir = loopFireDir(loop2.slug, fireId, runRoot);
127444
127694
  mkdirSync10(dir, { recursive: true, mode: 448 });
127445
127695
  for (const doc of stateDocs) {
127446
127696
  writeFileSync11(join20(dir, doc.filename), doc.body, { mode: 384 });
@@ -127471,12 +127721,12 @@ queue: not started
127471
127721
  `,
127472
127722
  { mode: 384 }
127473
127723
  );
127474
- mirrorDefinitionFiles(loop2.slug, files);
127724
+ mirrorDefinitionFiles(loop2.slug, files, runRoot);
127475
127725
  return dir;
127476
127726
  }
127477
- function mirrorDefinitionFiles(slug, files) {
127727
+ function mirrorDefinitionFiles(slug, files, runRoot) {
127478
127728
  try {
127479
- const root2 = loopDir(slug);
127729
+ const root2 = loopDir(slug, runRoot);
127480
127730
  mkdirSync10(root2, { recursive: true, mode: 448 });
127481
127731
  for (const name of [...MIRRORED_DEFINITION_FILES, "dashboard.html", "dashboard.manifest.json"]) {
127482
127732
  const body = files[name];
@@ -127582,7 +127832,7 @@ When you finish cleanly (VISION met / queue drained), write "status: done" and "
127582
127832
  return {
127583
127833
  cmd: "claude",
127584
127834
  args,
127585
- cwd: process.cwd(),
127835
+ cwd: opts.cwd ?? process.cwd(),
127586
127836
  env: {
127587
127837
  ...deriveGitIdentityEnv(env, deps.readGitConfig ?? readGlobalGitConfig),
127588
127838
  // Loop memory is addressed by SLUG, and the fire context carries no loop
@@ -127761,7 +128011,7 @@ init_esm_shims();
127761
128011
  import { spawn as spawn2 } from "child_process";
127762
128012
  import { randomUUID as randomUUID5 } from "crypto";
127763
128013
  import { existsSync as existsSync16, mkdirSync as mkdirSync11, readFileSync as readFileSync15, rmSync as rmSync2, writeFileSync as writeFileSync12 } from "fs";
127764
- import { dirname as dirname8, join as join24 } from "path";
128014
+ import { dirname as dirname9, join as join24 } from "path";
127765
128015
 
127766
128016
  // src/loops/claude-binary.ts
127767
128017
  init_esm_shims();
@@ -127869,10 +128119,10 @@ function resolveMaxConcurrentFires(opts = {}, env = process.env) {
127869
128119
  // src/loops/run.ts
127870
128120
  init_paths();
127871
128121
  var SHIPBACK_SIGNAL_TIMEOUT_MS = 8e3;
127872
- function preserveRefusedConstraints(slug, fireId, body) {
128122
+ function preserveRefusedConstraints(slug, fireId, body, runRoot) {
127873
128123
  try {
127874
- const path2 = refusedConstraintsPath(slug, fireId);
127875
- mkdirSync11(dirname8(path2), { recursive: true, mode: 448 });
128124
+ const path2 = refusedConstraintsPath(slug, fireId, runRoot);
128125
+ mkdirSync11(dirname9(path2), { recursive: true, mode: 448 });
127876
128126
  writeFileSync12(path2, body, { mode: 384 });
127877
128127
  return { path: path2 };
127878
128128
  } catch (err) {
@@ -127896,7 +128146,12 @@ async function runLoop(loopId, opts = {}) {
127896
128146
  const got = await sdk.loops.get(apiKey, loopId);
127897
128147
  if (got.status !== "ok") throw new Error(`loop not found: ${got.error}`);
127898
128148
  const loop2 = got.loop;
127899
- const loopRoot = loopDir(loop2.slug);
128149
+ const runRoot = resolveRunRoot();
128150
+ if (runRoot.reason === "fallback") {
128151
+ const why = runRoot.rejected?.map((r) => `${r.dir}: ${r.why}`).join("; ") ?? "no usable cwd";
128152
+ console.log(`Loop ${loop2.slug}: running under ${runRoot.root} \u2014 the current folder cannot host a run (${why}).`);
128153
+ }
128154
+ const loopRoot = loopDir(loop2.slug, runRoot.root);
127900
128155
  const maxConcurrent = resolveMaxConcurrentFires(opts, process.env);
127901
128156
  const inFlight = liveFires(loopRoot);
127902
128157
  if (inFlight.length >= maxConcurrent) {
@@ -127939,11 +128194,13 @@ async function runLoop(loopId, opts = {}) {
127939
128194
  `Loop ${loop2.slug}: ${undeclared.length} memory doc(s) not in manifest (${undeclared.map((d) => `${d.key} \u2190 ${d.scope}`).join(", ")}) \u2014 materialized anyway, and shipped back to the namespace each came from. Declare them in the task's stateDocs manifest to make that explicit.`
127940
128195
  );
127941
128196
  }
127942
- const dir = materialize(loop2, sessionId2, stateDocBodies);
128197
+ const dir = materialize(loop2, sessionId2, stateDocBodies, runRoot.root);
127943
128198
  console.log(`Loop ${loop2.slug}: fire ${sessionId2} \u2192 ${dir}`);
127944
128199
  const launch = buildLaunchArgs(
127945
128200
  dir,
127946
- { ...opts, sessionId: sessionId2, memoryManifest: normalizeMemoryManifest(loop2.stateDocs) },
128201
+ // The child runs IN the resolved root: for a project cwd that is the cwd it always was; under
128202
+ // the fallback it is the writable folder rather than the `/` launchd handed us.
128203
+ { ...opts, sessionId: sessionId2, cwd: opts.cwd ?? runRoot.root, memoryManifest: normalizeMemoryManifest(loop2.stateDocs) },
127947
128204
  loop2.slug
127948
128205
  );
127949
128206
  const budget = resolveMaxBudgetUsd(opts);
@@ -128027,7 +128284,7 @@ blast_radius: steps=${est.steps} paid=${est.paidSteps} estEur=${est.estCostEur ?
128027
128284
  const fresh = reread.loop.constraintsMd ?? "";
128028
128285
  const merged = mergeConstraints(boot, materializedConstraints, fresh);
128029
128286
  if (merged.refusal) {
128030
- const kept = preserveRefusedConstraints(loop2.slug, sessionId2, materializedConstraints);
128287
+ const kept = preserveRefusedConstraints(loop2.slug, sessionId2, materializedConstraints, runRoot.root);
128031
128288
  constraintsReport = { outcome: "refused", keptAt: kept.path ?? constraintsPath };
128032
128289
  console.error(
128033
128290
  `Loop ${loop2.slug}: ${merged.refusal} This fire's constraints were NOT discarded: its folder is KEPT at ${dir}` + (kept.path ? `, and the refused document is copied to ${kept.path}.` : ` \u2014 but the durable copy could NOT be written (${kept.error}), so that folder is the only place it survives.`)
@@ -128095,11 +128352,11 @@ blast_radius: steps=${est.steps} paid=${est.paidSteps} estEur=${est.estCostEur ?
128095
128352
  process.on("SIGINT", onSignal);
128096
128353
  process.on("SIGTERM", onSignal);
128097
128354
  let spawnError;
128098
- const exitCode = await new Promise((resolve) => {
128099
- child.on("exit", (code) => resolve(code ?? 1));
128355
+ const exitCode = await new Promise((resolve3) => {
128356
+ child.on("exit", (code) => resolve3(code ?? 1));
128100
128357
  child.on("error", (err) => {
128101
128358
  spawnError = err instanceof Error ? err.message : String(err);
128102
- resolve(1);
128359
+ resolve3(1);
128103
128360
  });
128104
128361
  });
128105
128362
  if (child.pid) killTree(child.pid);
@@ -128161,9 +128418,9 @@ async function showLoop(loopId) {
128161
128418
  // src/loops/schedule.ts
128162
128419
  init_esm_shims();
128163
128420
  init_paths();
128164
- import { writeFileSync as writeFileSync13, mkdirSync as mkdirSync12, rmSync as rmSync3, existsSync as existsSync17, readdirSync as readdirSync6, readFileSync as readFileSync16, accessSync as accessSync2, constants as constants2 } from "fs";
128421
+ import { writeFileSync as writeFileSync13, mkdirSync as mkdirSync12, rmSync as rmSync3, existsSync as existsSync17, readdirSync as readdirSync6, readFileSync as readFileSync16, accessSync as accessSync4, constants as constants4 } from "fs";
128165
128422
  import { execFileSync as execFileSync4 } from "child_process";
128166
- import { join as join25, dirname as dirname9 } from "path";
128423
+ import { join as join25, dirname as dirname10 } from "path";
128167
128424
  import { homedir as homedir14 } from "os";
128168
128425
  var LOOP_KIND = {
128169
128426
  labelPrefix: "xyz.ametyst.loop.",
@@ -128294,7 +128551,7 @@ function validatedExtraEnv(extraEnv) {
128294
128551
  }
128295
128552
  function assertWritable(dir, what) {
128296
128553
  try {
128297
- accessSync2(dir, constants2.W_OK);
128554
+ accessSync4(dir, constants4.W_OK);
128298
128555
  } catch {
128299
128556
  throw new Error(
128300
128557
  `refusing to schedule: the ${what} ${dir} is not writable, so the job would be registered but every fire would die before writing any trace. Schedule from a writable project directory.`
@@ -128387,7 +128644,15 @@ function schedule(kind, slug, opts = {}) {
128387
128644
  const lbl = label(kind, slug);
128388
128645
  const args = kind.buildRunCmd(slug, opts);
128389
128646
  const cadence = cadenceLabel(opts);
128390
- const cwd = opts.cwd ?? process.cwd();
128647
+ const resolved = resolveRunRoot(void 0, {
128648
+ cwd: () => opts.cwd ?? process.cwd(),
128649
+ homedir: () => home
128650
+ });
128651
+ const cwd = resolved.root;
128652
+ if (resolved.reason === "fallback") {
128653
+ const why = (resolved.rejected ?? []).map((r) => `${r.dir}: ${r.why}`).join("; ");
128654
+ console.warn(`\u26A0\uFE0F the job will run in ${cwd} \u2014 the current folder cannot host a run (${why}).`);
128655
+ }
128391
128656
  const procEnv = opts.env ?? process.env;
128392
128657
  const envPath = procEnv.PATH ?? "";
128393
128658
  const model = resolveScheduledModel(opts, home, procEnv);
@@ -128410,8 +128675,7 @@ function schedule(kind, slug, opts = {}) {
128410
128675
  })();
128411
128676
  const path2 = plistPath(kind, home, slug);
128412
128677
  const stateDir2 = kind.stateDir(slug, cwd);
128413
- assertWritable(cwd, "working directory");
128414
- mkdirSync12(dirname9(path2), { recursive: true });
128678
+ mkdirSync12(dirname10(path2), { recursive: true });
128415
128679
  mkdirSync12(stateDir2, { recursive: true });
128416
128680
  assertWritable(stateDir2, "log directory");
128417
128681
  writeFileSync13(path2, plistXml(lbl, args, scheduleBlock, cwd, jobEnv, stateDir2), { mode: 384 });
@@ -128431,10 +128695,9 @@ launchctl said: ${unloaded.output.trim()}` : "")
128431
128695
  launchctl said: ${loaded.output.trim()}` : "")
128432
128696
  );
128433
128697
  }
128434
- return { label: lbl, cadence, workingDirectory: cwd, model: effectiveModel };
128698
+ return { label: lbl, cadence, workingDirectory: cwd, workingDirectoryReason: resolved.reason, model: effectiveModel };
128435
128699
  }
128436
128700
  const stateDir = kind.stateDir(slug, cwd);
128437
- assertWritable(cwd, "working directory");
128438
128701
  mkdirSync12(stateDir, { recursive: true });
128439
128702
  assertWritable(stateDir, "log directory");
128440
128703
  const cronEnv = { PATH: envPath };
@@ -128448,7 +128711,7 @@ launchctl said: ${loaded.output.trim()}` : "")
128448
128711
  const kept = stripLabel(readCrontab(), lbl);
128449
128712
  kept.push(line);
128450
128713
  writeCrontab(kept.join("\n"));
128451
- return { label: lbl, cadence, workingDirectory: cwd, model: effectiveCronModel };
128714
+ return { label: lbl, cadence, workingDirectory: cwd, workingDirectoryReason: resolved.reason, model: effectiveCronModel };
128452
128715
  }
128453
128716
  function unschedule(kind, slug, opts = {}) {
128454
128717
  const platform = opts.platform ?? process.platform;
@@ -128673,9 +128936,9 @@ async function runCompound(compoundId, opts = {}) {
128673
128936
  };
128674
128937
  process.on("SIGINT", onSignal);
128675
128938
  process.on("SIGTERM", onSignal);
128676
- const exitCode = await new Promise((resolve) => {
128677
- child.on("exit", (code) => resolve(code ?? 1));
128678
- child.on("error", () => resolve(1));
128939
+ const exitCode = await new Promise((resolve3) => {
128940
+ child.on("exit", (code) => resolve3(code ?? 1));
128941
+ child.on("error", () => resolve3(1));
128679
128942
  });
128680
128943
  process.off("SIGINT", onSignal);
128681
128944
  process.off("SIGTERM", onSignal);
@@ -128984,7 +129247,7 @@ compoundCommand.command("sync-skills").description(
128984
129247
  for (const target of targets) {
128985
129248
  const r = await syncSkills({ global: opts.global, target });
128986
129249
  console.log(
128987
- `\u2705 sync-skills [${target}]: ${r.written} written, ${r.pruned} pruned${r.skipped.length ? `, ${r.skipped.length} skipped (unmanaged): ${r.skipped.join(", ")}` : ""} \u2192 ${r.root}`
129250
+ `\u2705 sync-skills [${target}]: ${r.written} written, ${r.pruned} pruned${r.skipped.length ? `, ${r.skipped.length} skipped (unmanaged): ${r.skipped.join(", ")}` : ""} \u2192 ${r.root}${r.fallback ? ` (fallback to the home root: ${r.fallback.why}; project-local ${r.fallback.from} was not used)` : ""}`
128988
129251
  );
128989
129252
  }
128990
129253
  } catch (err) {