@memoraone/mcp 0.1.46 → 0.1.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.cjs CHANGED
@@ -231,7 +231,7 @@ var require_package = __commonJS({
231
231
  "package.json"(exports2, module2) {
232
232
  module2.exports = {
233
233
  name: "@memoraone/mcp",
234
- version: "0.1.46",
234
+ version: "0.1.48",
235
235
  type: "module",
236
236
  main: "dist/index.cjs",
237
237
  exports: {
@@ -531,7 +531,7 @@ async function acquireLocalLock(lockName, options = {}) {
531
531
  `[memoraone-mcp] Failed to acquire lock ${lockName} after ${maxRetries} retries`
532
532
  );
533
533
  }
534
- await new Promise((resolve43) => setTimeout(resolve43, retryDelayMs));
534
+ await new Promise((resolve44) => setTimeout(resolve44, retryDelayMs));
535
535
  continue;
536
536
  }
537
537
  throw err;
@@ -1092,9 +1092,9 @@ var init_memoraClient = __esm({
1092
1092
  });
1093
1093
 
1094
1094
  // src/localState/localConnectClient.ts
1095
- async function requestJson(baseUrl, method, path47, options = {}) {
1095
+ async function requestJson(baseUrl, method, path48, options = {}) {
1096
1096
  const fetchImpl = options.fetchImpl ?? fetch;
1097
- const url = `${baseUrl.replace(/\/+$/, "")}${path47.startsWith("/") ? path47 : `/${path47}`}`;
1097
+ const url = `${baseUrl.replace(/\/+$/, "")}${path48.startsWith("/") ? path48 : `/${path48}`}`;
1098
1098
  const res = await fetchImpl(url, {
1099
1099
  method,
1100
1100
  headers: {
@@ -3950,7 +3950,7 @@ function formatOptionalJetBrainsHandshakeUnavailableDetail(detail) {
3950
3950
  async function verifyJetBrainsMcpHandshake(options) {
3951
3951
  const timeoutMs = options.timeoutMs ?? 15e3;
3952
3952
  const { server } = options;
3953
- return new Promise((resolve43) => {
3953
+ return new Promise((resolve44) => {
3954
3954
  let settled = false;
3955
3955
  const finish = (ok, detail, optionalUnavailable) => {
3956
3956
  if (settled) return;
@@ -3960,7 +3960,7 @@ async function verifyJetBrainsMcpHandshake(options) {
3960
3960
  child.kill();
3961
3961
  } catch {
3962
3962
  }
3963
- resolve43({ ok, detail, optionalUnavailable });
3963
+ resolve44({ ok, detail, optionalUnavailable });
3964
3964
  };
3965
3965
  const child = (0, import_node_child_process4.spawn)(server.command, [...server.args], {
3966
3966
  env: { ...process.env, ...server.env },
@@ -12854,7 +12854,7 @@ var init_pluginPairing = __esm({
12854
12854
  ideType: this.source,
12855
12855
  fetchImpl: this.connectOptions.fetchImpl ?? this.fetchImpl,
12856
12856
  // Plugin pairing configures only the IDE that initiated the pairing.
12857
- configureIdes: true,
12857
+ configureIdes: this.source !== "cursor",
12858
12858
  setupIdeOptions: {
12859
12859
  ...this.connectOptions.setupIdeOptions,
12860
12860
  targets: {
@@ -12993,13 +12993,13 @@ function writeEvent(event, stdoutWrite) {
12993
12993
  }
12994
12994
  function delay(ms, signal) {
12995
12995
  if (ms <= 0 || signal?.aborted) return Promise.resolve();
12996
- return new Promise((resolve43) => {
12996
+ return new Promise((resolve44) => {
12997
12997
  const timer = setTimeout(finish, ms);
12998
12998
  const onAbort = () => finish();
12999
12999
  function finish() {
13000
13000
  clearTimeout(timer);
13001
13001
  signal?.removeEventListener("abort", onAbort);
13002
- resolve43();
13002
+ resolve44();
13003
13003
  }
13004
13004
  signal?.addEventListener("abort", onAbort, { once: true });
13005
13005
  });
@@ -13442,8 +13442,8 @@ var init_bridgeClientRoots = __esm({
13442
13442
  if (this.closed) {
13443
13443
  return null;
13444
13444
  }
13445
- return new Promise((resolve43) => {
13446
- this.waiters.push(resolve43);
13445
+ return new Promise((resolve44) => {
13446
+ this.waiters.push(resolve44);
13447
13447
  });
13448
13448
  }
13449
13449
  /** Re-queue lines read during an intermediate protocol step (e.g. roots/list) for the main bridge loop. */
@@ -13463,6 +13463,153 @@ var init_bridgeClientRoots = __esm({
13463
13463
  }
13464
13464
  });
13465
13465
 
13466
+ // src/pluginStartupBindingWait.ts
13467
+ function errorMessage(err) {
13468
+ return err instanceof Error ? err.message : String(err);
13469
+ }
13470
+ function isUnboundPluginStartupBindingMessage(message) {
13471
+ return UNBOUND_MESSAGE_MARKERS.some((marker) => message.includes(marker));
13472
+ }
13473
+ function isCredentialsMissingMessage(message) {
13474
+ return message.includes(CREDENTIALS_MISSING_MARKER);
13475
+ }
13476
+ async function pendingBindingWindowOpen(isPendingBinding) {
13477
+ if (!isPendingBinding) {
13478
+ return false;
13479
+ }
13480
+ try {
13481
+ return Boolean(await isPendingBinding());
13482
+ } catch {
13483
+ return false;
13484
+ }
13485
+ }
13486
+ function shouldWaitForPluginStartupBinding(options = {}) {
13487
+ const env2 = options.env ?? process.env;
13488
+ if (env2[MEMORAONE_PLUGIN_ENV] !== MEMORAONE_CURSOR_PLUGIN) {
13489
+ return false;
13490
+ }
13491
+ if (options.daemonBindingHint) {
13492
+ return false;
13493
+ }
13494
+ return true;
13495
+ }
13496
+ function collectPluginStartupBindingRoots(options) {
13497
+ const seen = /* @__PURE__ */ new Set();
13498
+ const roots = [];
13499
+ const add = (raw) => {
13500
+ if (raw === void 0 || raw === null || raw.trim() === "") {
13501
+ return;
13502
+ }
13503
+ const resolved = path47.resolve(raw);
13504
+ if (seen.has(resolved)) {
13505
+ return;
13506
+ }
13507
+ seen.add(resolved);
13508
+ roots.push(resolved);
13509
+ };
13510
+ for (const root of options.initializeRoots ?? []) {
13511
+ add(root);
13512
+ }
13513
+ for (const uri of options.rootsListUris ?? []) {
13514
+ add(uriToPath(uri));
13515
+ }
13516
+ add(getRepoScopedWorkspaceHint(options.env));
13517
+ return roots;
13518
+ }
13519
+ async function hasPendingPluginStartupBinding(workspaceRoots, options = {}) {
13520
+ for (const root of workspaceRoots) {
13521
+ try {
13522
+ const identity = await lookupLocalBindingIdentity(root, {
13523
+ homeDir: options.homeDir
13524
+ });
13525
+ if (identity.status !== "resolved") {
13526
+ continue;
13527
+ }
13528
+ const record = await readBindingRecord(
13529
+ identity.repositoryBindingId,
13530
+ options.homeDir
13531
+ );
13532
+ if (record?.status === "pending") {
13533
+ return true;
13534
+ }
13535
+ } catch {
13536
+ continue;
13537
+ }
13538
+ }
13539
+ return false;
13540
+ }
13541
+ async function isRetryablePluginStartupBindingError(err, options = {}) {
13542
+ const message = errorMessage(err);
13543
+ if (isUnboundPluginStartupBindingMessage(message)) {
13544
+ return true;
13545
+ }
13546
+ if (isCredentialsMissingMessage(message) && await pendingBindingWindowOpen(options.isPendingBinding)) {
13547
+ return true;
13548
+ }
13549
+ return false;
13550
+ }
13551
+ function defaultSleep(ms) {
13552
+ return new Promise((resolve44) => {
13553
+ setTimeout(resolve44, ms);
13554
+ });
13555
+ }
13556
+ async function waitForPluginStartupBinding(resolve44, options = {}) {
13557
+ const now = options.now ?? Date.now;
13558
+ const sleep = options.sleep ?? defaultSleep;
13559
+ const timeoutMs = options.timeoutMs ?? PLUGIN_STARTUP_BINDING_WAIT_TIMEOUT_MS;
13560
+ const intervalMs = options.intervalMs ?? PLUGIN_STARTUP_BINDING_WAIT_INTERVAL_MS;
13561
+ const startedAt = now();
13562
+ let waitingLogged = false;
13563
+ let lastError;
13564
+ while (true) {
13565
+ try {
13566
+ const binding = await resolve44();
13567
+ if (waitingLogged) {
13568
+ options.log?.(
13569
+ `local MemoraOne binding available after Cursor plugin pairing (${now() - startedAt}ms)`
13570
+ );
13571
+ }
13572
+ return binding;
13573
+ } catch (err) {
13574
+ lastError = err;
13575
+ const retryable = await isRetryablePluginStartupBindingError(err, {
13576
+ isPendingBinding: options.isPendingBinding
13577
+ });
13578
+ if (!retryable) {
13579
+ throw err;
13580
+ }
13581
+ if (now() - startedAt >= timeoutMs) {
13582
+ throw lastError;
13583
+ }
13584
+ if (!waitingLogged) {
13585
+ options.log?.(
13586
+ "waiting for local MemoraOne binding after Cursor plugin pairing"
13587
+ );
13588
+ waitingLogged = true;
13589
+ }
13590
+ await sleep(intervalMs);
13591
+ }
13592
+ }
13593
+ }
13594
+ var path47, MEMORAONE_PLUGIN_ENV, MEMORAONE_CURSOR_PLUGIN, PLUGIN_STARTUP_BINDING_WAIT_TIMEOUT_MS, PLUGIN_STARTUP_BINDING_WAIT_INTERVAL_MS, UNBOUND_MESSAGE_MARKERS, CREDENTIALS_MISSING_MARKER;
13595
+ var init_pluginStartupBindingWait = __esm({
13596
+ "src/pluginStartupBindingWait.ts"() {
13597
+ path47 = __toESM(require("path"), 1);
13598
+ init_initializeBinding();
13599
+ init_bindingStore();
13600
+ init_resolveLocalBinding();
13601
+ MEMORAONE_PLUGIN_ENV = "MEMORAONE_PLUGIN";
13602
+ MEMORAONE_CURSOR_PLUGIN = "cursor";
13603
+ PLUGIN_STARTUP_BINDING_WAIT_TIMEOUT_MS = 5 * 60 * 1e3;
13604
+ PLUGIN_STARTUP_BINDING_WAIT_INTERVAL_MS = 250;
13605
+ UNBOUND_MESSAGE_MARKERS = [
13606
+ "No local MemoraOne binding for this workspace",
13607
+ "No local binding for workspace"
13608
+ ];
13609
+ CREDENTIALS_MISSING_MARKER = "Installation credentials missing";
13610
+ }
13611
+ });
13612
+
13466
13613
  // src/ideType.ts
13467
13614
  function mapReliableClientInfoName(name) {
13468
13615
  if (typeof name !== "string") {
@@ -13670,9 +13817,9 @@ function extractJsonRpcId(line) {
13670
13817
  }
13671
13818
  }
13672
13819
  function connectWithRetry(socketPath, log, maxRetries, retryDelayMs, connect2) {
13673
- return new Promise((resolve43, reject) => {
13820
+ return new Promise((resolve44, reject) => {
13674
13821
  const tryConnect = (attempt) => {
13675
- connect2(socketPath).then(resolve43).catch((err) => {
13822
+ connect2(socketPath).then(resolve44).catch((err) => {
13676
13823
  if (attempt >= maxRetries) {
13677
13824
  reject(err);
13678
13825
  return;
@@ -13841,6 +13988,7 @@ var init_bridgeProxy = __esm({
13841
13988
  init_bridgeClientRoots();
13842
13989
  init_cleanup();
13843
13990
  init_initializeBinding();
13991
+ init_pluginStartupBindingWait();
13844
13992
  init_projectBinding();
13845
13993
  init_ideType();
13846
13994
  init_socketPaths();
@@ -13868,8 +14016,8 @@ var init_bridgeProxy = __esm({
13868
14016
  this.maxRetries = options.maxRetries ?? 5;
13869
14017
  this.retryDelayMs = options.retryDelayMs ?? 200;
13870
14018
  this.lineReader = options.lineReader ?? null;
13871
- this.connectImpl = options.connect ?? ((socketPath) => new Promise((resolve43, reject) => {
13872
- const socket = net.connect(socketPath, () => resolve43(socket));
14019
+ this.connectImpl = options.connect ?? ((socketPath) => new Promise((resolve44, reject) => {
14020
+ const socket = net.connect(socketPath, () => resolve44(socket));
13873
14021
  socket.on("error", reject);
13874
14022
  }));
13875
14023
  this.spawnDaemonImpl = options.spawnDaemon ?? (async (binding) => {
@@ -13953,10 +14101,20 @@ var init_bridgeProxy = __esm({
13953
14101
  );
13954
14102
  }
13955
14103
  }
13956
- const binding = await resolveBridgeSessionBinding(params, this.env, {
14104
+ const resolveBinding = () => resolveBridgeSessionBinding(params, this.env, {
13957
14105
  rootsListUris,
13958
14106
  rootsListAttempted
13959
14107
  });
14108
+ const binding = shouldWaitForPluginStartupBinding({ env: this.env }) ? await waitForPluginStartupBinding(resolveBinding, {
14109
+ isPendingBinding: () => hasPendingPluginStartupBinding(
14110
+ collectPluginStartupBindingRoots({
14111
+ initializeRoots,
14112
+ rootsListUris,
14113
+ env: this.env
14114
+ })
14115
+ ),
14116
+ log: this.log
14117
+ }) : await resolveBinding();
13960
14118
  const environmentLog = binding.environment !== void 0 ? ` environment=${binding.environment}` : "";
13961
14119
  this.log(
13962
14120
  `session binding binding=${binding.repositoryBindingId} project=${binding.projectId} workspace=${binding.workspaceRoot} source=${binding.bindingSource}${environmentLog}`
@@ -14001,7 +14159,7 @@ var init_bridgeProxy = __esm({
14001
14159
  }
14002
14160
  waitForDaemonJsonRpcResponse(id, timeoutMs = 3e4) {
14003
14161
  const key = this.waiterKey(id);
14004
- return new Promise((resolve43, reject) => {
14162
+ return new Promise((resolve44, reject) => {
14005
14163
  const timer = setTimeout(() => {
14006
14164
  this.pendingDaemonResponseWaiters.delete(key);
14007
14165
  reject(
@@ -14010,7 +14168,7 @@ var init_bridgeProxy = __esm({
14010
14168
  )
14011
14169
  );
14012
14170
  }, timeoutMs);
14013
- this.pendingDaemonResponseWaiters.set(key, { resolve: resolve43, reject, timer });
14171
+ this.pendingDaemonResponseWaiters.set(key, { resolve: resolve44, reject, timer });
14014
14172
  });
14015
14173
  }
14016
14174
  notifyDaemonResponseWaiters(line) {
package/dist/daemon.cjs CHANGED
@@ -416,7 +416,7 @@ async function acquireLocalLock(lockName, options = {}) {
416
416
  `[memoraone-mcp] Failed to acquire lock ${lockName} after ${maxRetries} retries`
417
417
  );
418
418
  }
419
- await new Promise((resolve10) => setTimeout(resolve10, retryDelayMs));
419
+ await new Promise((resolve11) => setTimeout(resolve11, retryDelayMs));
420
420
  continue;
421
421
  }
422
422
  throw err;
@@ -980,9 +980,9 @@ var MemoraClient = class {
980
980
  ...options?.headers ?? {}
981
981
  };
982
982
  }
983
- async perform(method, path15, body, options, retried = false) {
983
+ async perform(method, path16, body, options, retried = false) {
984
984
  const nonce = crypto2.randomBytes(8).toString("hex");
985
- const url = `${this.baseUrl}${path15.startsWith("/") ? path15 : `/${path15}`}`;
985
+ const url = `${this.baseUrl}${path16.startsWith("/") ? path16 : `/${path16}`}`;
986
986
  this.resolveProjectId();
987
987
  console.error(
988
988
  `[memoraone-mcp][info] requestJson nonce=${nonce} stage=before_fetch method=${method} url=${url}`
@@ -1009,7 +1009,7 @@ var MemoraClient = class {
1009
1009
  if (res.status === 401 && !options?.skipAuthRefresh && !retried) {
1010
1010
  try {
1011
1011
  await this.refreshAccessToken();
1012
- return this.perform(method, path15, body, options, true);
1012
+ return this.perform(method, path16, body, options, true);
1013
1013
  } catch (err) {
1014
1014
  if (err instanceof ReconnectRequiredError) {
1015
1015
  await this.markReconnectRequired();
@@ -1029,22 +1029,22 @@ var MemoraClient = class {
1029
1029
  }
1030
1030
  return res.text ? JSON.parse(res.text) : null;
1031
1031
  }
1032
- async post(path15, body, options) {
1033
- console.error(`[memoraone-mcp][info] MemoraClient.post ENTER path=${path15}`);
1034
- const result = await this.perform("POST", path15, body, options);
1035
- console.error(`[memoraone-mcp][info] MemoraClient.post EXIT path=${path15}`);
1032
+ async post(path16, body, options) {
1033
+ console.error(`[memoraone-mcp][info] MemoraClient.post ENTER path=${path16}`);
1034
+ const result = await this.perform("POST", path16, body, options);
1035
+ console.error(`[memoraone-mcp][info] MemoraClient.post EXIT path=${path16}`);
1036
1036
  return result;
1037
1037
  }
1038
- async get(path15, options) {
1039
- return this.perform("GET", path15, void 0, options);
1038
+ async get(path16, options) {
1039
+ return this.perform("GET", path16, void 0, options);
1040
1040
  }
1041
1041
  };
1042
1042
  var memoraClient_default = MemoraClient;
1043
1043
 
1044
1044
  // src/localState/localConnectClient.ts
1045
- async function requestJson2(baseUrl, method, path15, options = {}) {
1045
+ async function requestJson2(baseUrl, method, path16, options = {}) {
1046
1046
  const fetchImpl = options.fetchImpl ?? fetch;
1047
- const url = `${baseUrl.replace(/\/+$/, "")}${path15.startsWith("/") ? path15 : `/${path15}`}`;
1047
+ const url = `${baseUrl.replace(/\/+$/, "")}${path16.startsWith("/") ? path16 : `/${path16}`}`;
1048
1048
  const res = await fetchImpl(url, {
1049
1049
  method,
1050
1050
  headers: {
@@ -1228,6 +1228,30 @@ async function ensureRepositoryBindingForRoot(workspaceRoot, options = {}) {
1228
1228
  legacyM1WarningPath
1229
1229
  };
1230
1230
  }
1231
+ async function lookupLocalBindingIdentity(workspaceRoot, options = {}) {
1232
+ const resolved = path9.resolve(workspaceRoot);
1233
+ const identity = await captureRootFilesystemIdentity(resolved, options.identityDeps);
1234
+ const index = await loadPathIndex(options.homeDir);
1235
+ const lookup = lookupPathIndex(index, resolved, identity);
1236
+ if (lookup.kind !== "path") {
1237
+ return { status: "unbound", workspaceRoot: resolved };
1238
+ }
1239
+ const record = await readBindingRecord(lookup.repositoryBindingId, options.homeDir);
1240
+ if (!record) {
1241
+ return { status: "unbound", workspaceRoot: resolved };
1242
+ }
1243
+ if (path9.resolve(record.workspaceRoot) !== resolved) {
1244
+ return { status: "unbound", workspaceRoot: resolved };
1245
+ }
1246
+ if (!identityMatchesStored(record.filesystemIdentity, identity)) {
1247
+ return { status: "unbound", workspaceRoot: resolved };
1248
+ }
1249
+ return {
1250
+ status: "resolved",
1251
+ workspaceRoot: resolved,
1252
+ repositoryBindingId: record.repositoryBindingId
1253
+ };
1254
+ }
1231
1255
  async function resolveLocalBinding(workspaceRoot, options = {}) {
1232
1256
  const resolved = path9.resolve(workspaceRoot);
1233
1257
  const { repositoryBindingId, legacyM1WarningPath } = await ensureRepositoryBindingForRoot(
@@ -1793,6 +1817,145 @@ async function resolveBindingFromInitializeParams(params, options = {}) {
1793
1817
  });
1794
1818
  }
1795
1819
 
1820
+ // src/pluginStartupBindingWait.ts
1821
+ var path14 = __toESM(require("path"), 1);
1822
+ var MEMORAONE_PLUGIN_ENV = "MEMORAONE_PLUGIN";
1823
+ var MEMORAONE_CURSOR_PLUGIN = "cursor";
1824
+ var PLUGIN_STARTUP_BINDING_WAIT_TIMEOUT_MS = 5 * 60 * 1e3;
1825
+ var PLUGIN_STARTUP_BINDING_WAIT_INTERVAL_MS = 250;
1826
+ var UNBOUND_MESSAGE_MARKERS = [
1827
+ "No local MemoraOne binding for this workspace",
1828
+ "No local binding for workspace"
1829
+ ];
1830
+ var CREDENTIALS_MISSING_MARKER = "Installation credentials missing";
1831
+ function errorMessage(err) {
1832
+ return err instanceof Error ? err.message : String(err);
1833
+ }
1834
+ function isUnboundPluginStartupBindingMessage(message) {
1835
+ return UNBOUND_MESSAGE_MARKERS.some((marker) => message.includes(marker));
1836
+ }
1837
+ function isCredentialsMissingMessage(message) {
1838
+ return message.includes(CREDENTIALS_MISSING_MARKER);
1839
+ }
1840
+ async function pendingBindingWindowOpen(isPendingBinding) {
1841
+ if (!isPendingBinding) {
1842
+ return false;
1843
+ }
1844
+ try {
1845
+ return Boolean(await isPendingBinding());
1846
+ } catch {
1847
+ return false;
1848
+ }
1849
+ }
1850
+ function shouldWaitForPluginStartupBinding(options = {}) {
1851
+ const env2 = options.env ?? process.env;
1852
+ if (env2[MEMORAONE_PLUGIN_ENV] !== MEMORAONE_CURSOR_PLUGIN) {
1853
+ return false;
1854
+ }
1855
+ if (options.daemonBindingHint) {
1856
+ return false;
1857
+ }
1858
+ return true;
1859
+ }
1860
+ function collectPluginStartupBindingRoots(options) {
1861
+ const seen = /* @__PURE__ */ new Set();
1862
+ const roots = [];
1863
+ const add = (raw) => {
1864
+ if (raw === void 0 || raw === null || raw.trim() === "") {
1865
+ return;
1866
+ }
1867
+ const resolved = path14.resolve(raw);
1868
+ if (seen.has(resolved)) {
1869
+ return;
1870
+ }
1871
+ seen.add(resolved);
1872
+ roots.push(resolved);
1873
+ };
1874
+ for (const root of options.initializeRoots ?? []) {
1875
+ add(root);
1876
+ }
1877
+ for (const uri of options.rootsListUris ?? []) {
1878
+ add(uriToPath(uri));
1879
+ }
1880
+ add(getRepoScopedWorkspaceHint(options.env));
1881
+ return roots;
1882
+ }
1883
+ async function hasPendingPluginStartupBinding(workspaceRoots, options = {}) {
1884
+ for (const root of workspaceRoots) {
1885
+ try {
1886
+ const identity = await lookupLocalBindingIdentity(root, {
1887
+ homeDir: options.homeDir
1888
+ });
1889
+ if (identity.status !== "resolved") {
1890
+ continue;
1891
+ }
1892
+ const record = await readBindingRecord(
1893
+ identity.repositoryBindingId,
1894
+ options.homeDir
1895
+ );
1896
+ if (record?.status === "pending") {
1897
+ return true;
1898
+ }
1899
+ } catch {
1900
+ continue;
1901
+ }
1902
+ }
1903
+ return false;
1904
+ }
1905
+ async function isRetryablePluginStartupBindingError(err, options = {}) {
1906
+ const message = errorMessage(err);
1907
+ if (isUnboundPluginStartupBindingMessage(message)) {
1908
+ return true;
1909
+ }
1910
+ if (isCredentialsMissingMessage(message) && await pendingBindingWindowOpen(options.isPendingBinding)) {
1911
+ return true;
1912
+ }
1913
+ return false;
1914
+ }
1915
+ function defaultSleep(ms) {
1916
+ return new Promise((resolve11) => {
1917
+ setTimeout(resolve11, ms);
1918
+ });
1919
+ }
1920
+ async function waitForPluginStartupBinding(resolve11, options = {}) {
1921
+ const now = options.now ?? Date.now;
1922
+ const sleep = options.sleep ?? defaultSleep;
1923
+ const timeoutMs = options.timeoutMs ?? PLUGIN_STARTUP_BINDING_WAIT_TIMEOUT_MS;
1924
+ const intervalMs = options.intervalMs ?? PLUGIN_STARTUP_BINDING_WAIT_INTERVAL_MS;
1925
+ const startedAt = now();
1926
+ let waitingLogged = false;
1927
+ let lastError;
1928
+ while (true) {
1929
+ try {
1930
+ const binding = await resolve11();
1931
+ if (waitingLogged) {
1932
+ options.log?.(
1933
+ `local MemoraOne binding available after Cursor plugin pairing (${now() - startedAt}ms)`
1934
+ );
1935
+ }
1936
+ return binding;
1937
+ } catch (err) {
1938
+ lastError = err;
1939
+ const retryable = await isRetryablePluginStartupBindingError(err, {
1940
+ isPendingBinding: options.isPendingBinding
1941
+ });
1942
+ if (!retryable) {
1943
+ throw err;
1944
+ }
1945
+ if (now() - startedAt >= timeoutMs) {
1946
+ throw lastError;
1947
+ }
1948
+ if (!waitingLogged) {
1949
+ options.log?.(
1950
+ "waiting for local MemoraOne binding after Cursor plugin pairing"
1951
+ );
1952
+ waitingLogged = true;
1953
+ }
1954
+ await sleep(intervalMs);
1955
+ }
1956
+ }
1957
+ }
1958
+
1796
1959
  // src/bridgeClientRoots.ts
1797
1960
  var readline = __toESM(require("readline"), 1);
1798
1961
  var TRUTHY = /* @__PURE__ */ new Set(["1", "true", "yes", "on"]);
@@ -2227,9 +2390,9 @@ function buildPersonalContextPath(parsed2) {
2227
2390
  }
2228
2391
  async function handleGetPersonalContext(client, args) {
2229
2392
  const parsed2 = getPersonalContextInputSchema.parse(args ?? {});
2230
- const path15 = buildPersonalContextPath(parsed2);
2393
+ const path16 = buildPersonalContextPath(parsed2);
2231
2394
  try {
2232
- const result = await client.get(path15);
2395
+ const result = await client.get(path16);
2233
2396
  return { ok: true, result };
2234
2397
  } catch (err) {
2235
2398
  if (err instanceof MemoraOneHttpError) {
@@ -2701,8 +2864,8 @@ async function handleCreateConceptVersion(client, args) {
2701
2864
  if (input.tags !== void 0) body.tags = input.tags;
2702
2865
  if (input.parent_id !== void 0) body.parent_id = input.parent_id;
2703
2866
  try {
2704
- const path15 = `/concepts/${encodeURIComponent(input.id)}/versions`;
2705
- return projectCreatedConceptVersionResponse(await client.post(path15, body));
2867
+ const path16 = `/concepts/${encodeURIComponent(input.id)}/versions`;
2868
+ return projectCreatedConceptVersionResponse(await client.post(path16, body));
2706
2869
  } catch (error) {
2707
2870
  rethrowToolRequestError("memora_create_concept_version", error);
2708
2871
  }
@@ -2737,7 +2900,7 @@ function handleBindingStatus(binding, options = {}) {
2737
2900
  // src/heartbeat.ts
2738
2901
  var crypto5 = __toESM(require("crypto"), 1);
2739
2902
  var fs10 = __toESM(require("fs"), 1);
2740
- var path14 = __toESM(require("path"), 1);
2903
+ var path15 = __toESM(require("path"), 1);
2741
2904
 
2742
2905
  // src/localState/mcpSessionId.ts
2743
2906
  var import_node_crypto4 = require("crypto");
@@ -2770,9 +2933,9 @@ function resolvePackageVersion() {
2770
2933
  if (fromEnv) return fromEnv;
2771
2934
  const moduleDir = typeof __dirname !== "undefined" ? __dirname : void 0;
2772
2935
  const candidates = [
2773
- ...moduleDir ? [path14.join(moduleDir, "..", "package.json"), path14.join(moduleDir, "package.json")] : [],
2774
- path14.join(process.cwd(), "package.json"),
2775
- path14.join(process.cwd(), "packages", "mcp", "package.json")
2936
+ ...moduleDir ? [path15.join(moduleDir, "..", "package.json"), path15.join(moduleDir, "package.json")] : [],
2937
+ path15.join(process.cwd(), "package.json"),
2938
+ path15.join(process.cwd(), "packages", "mcp", "package.json")
2776
2939
  ];
2777
2940
  for (const candidate of candidates) {
2778
2941
  try {
@@ -3291,8 +3454,8 @@ function registerToolWithWorklog(server, runtime, sessionContext, toolName, desc
3291
3454
  async function main(opts = {}) {
3292
3455
  let bindingReadyResolve = null;
3293
3456
  let bindingReadyReject = null;
3294
- const bindingReady = new Promise((resolve10, reject) => {
3295
- bindingReadyResolve = resolve10;
3457
+ const bindingReady = new Promise((resolve11, reject) => {
3458
+ bindingReadyResolve = resolve11;
3296
3459
  bindingReadyReject = reject;
3297
3460
  });
3298
3461
  const devMode = Boolean(config2.devMode);
@@ -3373,12 +3536,25 @@ async function main(opts = {}) {
3373
3536
  console.error("[memoraone-mcp][init-debug] Workspace resolution strategy: initialize.rootUri");
3374
3537
  }
3375
3538
  }
3376
- const binding = await resolveBindingFromInitializeParams(params, {
3539
+ const resolveBinding = () => resolveBindingFromInitializeParams(params, {
3377
3540
  fallbackWorkspaceRoots: getEnvWorkspaceRootCandidates(),
3378
3541
  rootsListUris,
3379
3542
  rootsListAttempted,
3380
3543
  ...getBridgeBindingResolveOptions()
3381
3544
  });
3545
+ const binding = shouldWaitForPluginStartupBinding({
3546
+ env: process.env,
3547
+ daemonBindingHint: opts.daemonBindingHint
3548
+ }) ? await waitForPluginStartupBinding(resolveBinding, {
3549
+ isPendingBinding: () => hasPendingPluginStartupBinding(
3550
+ collectPluginStartupBindingRoots({
3551
+ initializeRoots,
3552
+ rootsListUris,
3553
+ env: process.env
3554
+ })
3555
+ ),
3556
+ log: (msg) => console.error(`[memoraone-mcp] ${msg}`)
3557
+ }) : await resolveBinding();
3382
3558
  workspaceRoot = binding.workspaceRoot;
3383
3559
  return binding;
3384
3560
  };
@@ -3765,10 +3941,10 @@ async function main(opts = {}) {
3765
3941
  console.error("[memoraone-mcp] MCP server ready");
3766
3942
  }
3767
3943
  if (opts.sessionSocket) {
3768
- await new Promise((resolve10) => {
3944
+ await new Promise((resolve11) => {
3769
3945
  opts.sessionSocket.once("close", () => {
3770
3946
  shutdown("session closed", false);
3771
- resolve10();
3947
+ resolve11();
3772
3948
  });
3773
3949
  });
3774
3950
  }
@@ -3812,7 +3988,7 @@ async function ensureSocketClean(socketPath) {
3812
3988
  } catch {
3813
3989
  return;
3814
3990
  }
3815
- return new Promise((resolve10) => {
3991
+ return new Promise((resolve11) => {
3816
3992
  const client = net.createConnection({ path: socketPath }, () => {
3817
3993
  client.destroy();
3818
3994
  log("daemon already running, exiting");
@@ -3824,7 +4000,7 @@ async function ensureSocketClean(socketPath) {
3824
4000
  log("stale socket removed");
3825
4001
  } catch {
3826
4002
  }
3827
- resolve10();
4003
+ resolve11();
3828
4004
  });
3829
4005
  });
3830
4006
  }
@@ -3915,14 +4091,14 @@ async function runDaemon() {
3915
4091
  process.on("SIGINT", () => shutdownNow("SIGINT"));
3916
4092
  process.on("SIGTERM", () => shutdownNow("SIGTERM"));
3917
4093
  process.on("exit", cleanupSocketFile);
3918
- return new Promise((resolve10) => {
4094
+ return new Promise((resolve11) => {
3919
4095
  server.listen(socketPath, () => {
3920
4096
  writeBindingSidecar(socketPath, binding, ideType ?? "");
3921
4097
  log(`daemon started, listening on ${socketPath}`);
3922
4098
  void daemonHeartbeat.start().catch((err) => {
3923
4099
  log(`daemon heartbeat start error: ${String(err)}`);
3924
4100
  });
3925
- resolve10();
4101
+ resolve11();
3926
4102
  });
3927
4103
  });
3928
4104
  }
package/dist/index.cjs CHANGED
@@ -593,7 +593,7 @@ async function acquireLocalLock(lockName, options = {}) {
593
593
  `[memoraone-mcp] Failed to acquire lock ${lockName} after ${maxRetries} retries`
594
594
  );
595
595
  }
596
- await new Promise((resolve10) => setTimeout(resolve10, retryDelayMs));
596
+ await new Promise((resolve11) => setTimeout(resolve11, retryDelayMs));
597
597
  continue;
598
598
  }
599
599
  throw err;
@@ -612,9 +612,9 @@ async function withLocalLock(lockName, fn, options = {}) {
612
612
 
613
613
  // src/localState/localConnectClient.ts
614
614
  var path6 = __toESM(require("path"), 1);
615
- async function requestJson(baseUrl, method, path15, options = {}) {
615
+ async function requestJson(baseUrl, method, path16, options = {}) {
616
616
  const fetchImpl = options.fetchImpl ?? fetch;
617
- const url = `${baseUrl.replace(/\/+$/, "")}${path15.startsWith("/") ? path15 : `/${path15}`}`;
617
+ const url = `${baseUrl.replace(/\/+$/, "")}${path16.startsWith("/") ? path16 : `/${path16}`}`;
618
618
  const res = await fetchImpl(url, {
619
619
  method,
620
620
  headers: {
@@ -950,9 +950,9 @@ var MemoraClient = class {
950
950
  ...options?.headers ?? {}
951
951
  };
952
952
  }
953
- async perform(method, path15, body, options, retried = false) {
953
+ async perform(method, path16, body, options, retried = false) {
954
954
  const nonce = crypto2.randomBytes(8).toString("hex");
955
- const url = `${this.baseUrl}${path15.startsWith("/") ? path15 : `/${path15}`}`;
955
+ const url = `${this.baseUrl}${path16.startsWith("/") ? path16 : `/${path16}`}`;
956
956
  this.resolveProjectId();
957
957
  console.error(
958
958
  `[memoraone-mcp][info] requestJson nonce=${nonce} stage=before_fetch method=${method} url=${url}`
@@ -979,7 +979,7 @@ var MemoraClient = class {
979
979
  if (res.status === 401 && !options?.skipAuthRefresh && !retried) {
980
980
  try {
981
981
  await this.refreshAccessToken();
982
- return this.perform(method, path15, body, options, true);
982
+ return this.perform(method, path16, body, options, true);
983
983
  } catch (err) {
984
984
  if (err instanceof ReconnectRequiredError) {
985
985
  await this.markReconnectRequired();
@@ -999,14 +999,14 @@ var MemoraClient = class {
999
999
  }
1000
1000
  return res.text ? JSON.parse(res.text) : null;
1001
1001
  }
1002
- async post(path15, body, options) {
1003
- console.error(`[memoraone-mcp][info] MemoraClient.post ENTER path=${path15}`);
1004
- const result = await this.perform("POST", path15, body, options);
1005
- console.error(`[memoraone-mcp][info] MemoraClient.post EXIT path=${path15}`);
1002
+ async post(path16, body, options) {
1003
+ console.error(`[memoraone-mcp][info] MemoraClient.post ENTER path=${path16}`);
1004
+ const result = await this.perform("POST", path16, body, options);
1005
+ console.error(`[memoraone-mcp][info] MemoraClient.post EXIT path=${path16}`);
1006
1006
  return result;
1007
1007
  }
1008
- async get(path15, options) {
1009
- return this.perform("GET", path15, void 0, options);
1008
+ async get(path16, options) {
1009
+ return this.perform("GET", path16, void 0, options);
1010
1010
  }
1011
1011
  };
1012
1012
  var memoraClient_default = MemoraClient;
@@ -1313,6 +1313,30 @@ async function ensureRepositoryBindingForRoot(workspaceRoot, options = {}) {
1313
1313
  legacyM1WarningPath
1314
1314
  };
1315
1315
  }
1316
+ async function lookupLocalBindingIdentity(workspaceRoot, options = {}) {
1317
+ const resolved = path10.resolve(workspaceRoot);
1318
+ const identity = await captureRootFilesystemIdentity(resolved, options.identityDeps);
1319
+ const index = await loadPathIndex(options.homeDir);
1320
+ const lookup = lookupPathIndex(index, resolved, identity);
1321
+ if (lookup.kind !== "path") {
1322
+ return { status: "unbound", workspaceRoot: resolved };
1323
+ }
1324
+ const record = await readBindingRecord(lookup.repositoryBindingId, options.homeDir);
1325
+ if (!record) {
1326
+ return { status: "unbound", workspaceRoot: resolved };
1327
+ }
1328
+ if (path10.resolve(record.workspaceRoot) !== resolved) {
1329
+ return { status: "unbound", workspaceRoot: resolved };
1330
+ }
1331
+ if (!identityMatchesStored(record.filesystemIdentity, identity)) {
1332
+ return { status: "unbound", workspaceRoot: resolved };
1333
+ }
1334
+ return {
1335
+ status: "resolved",
1336
+ workspaceRoot: resolved,
1337
+ repositoryBindingId: record.repositoryBindingId
1338
+ };
1339
+ }
1316
1340
  async function resolveLocalBinding(workspaceRoot, options = {}) {
1317
1341
  const resolved = path10.resolve(workspaceRoot);
1318
1342
  const { repositoryBindingId, legacyM1WarningPath } = await ensureRepositoryBindingForRoot(
@@ -1690,9 +1714,148 @@ async function resolveBindingFromInitializeParams(params, options = {}) {
1690
1714
  });
1691
1715
  }
1692
1716
 
1717
+ // src/pluginStartupBindingWait.ts
1718
+ var path13 = __toESM(require("path"), 1);
1719
+ var MEMORAONE_PLUGIN_ENV = "MEMORAONE_PLUGIN";
1720
+ var MEMORAONE_CURSOR_PLUGIN = "cursor";
1721
+ var PLUGIN_STARTUP_BINDING_WAIT_TIMEOUT_MS = 5 * 60 * 1e3;
1722
+ var PLUGIN_STARTUP_BINDING_WAIT_INTERVAL_MS = 250;
1723
+ var UNBOUND_MESSAGE_MARKERS = [
1724
+ "No local MemoraOne binding for this workspace",
1725
+ "No local binding for workspace"
1726
+ ];
1727
+ var CREDENTIALS_MISSING_MARKER = "Installation credentials missing";
1728
+ function errorMessage(err) {
1729
+ return err instanceof Error ? err.message : String(err);
1730
+ }
1731
+ function isUnboundPluginStartupBindingMessage(message) {
1732
+ return UNBOUND_MESSAGE_MARKERS.some((marker) => message.includes(marker));
1733
+ }
1734
+ function isCredentialsMissingMessage(message) {
1735
+ return message.includes(CREDENTIALS_MISSING_MARKER);
1736
+ }
1737
+ async function pendingBindingWindowOpen(isPendingBinding) {
1738
+ if (!isPendingBinding) {
1739
+ return false;
1740
+ }
1741
+ try {
1742
+ return Boolean(await isPendingBinding());
1743
+ } catch {
1744
+ return false;
1745
+ }
1746
+ }
1747
+ function shouldWaitForPluginStartupBinding(options = {}) {
1748
+ const env2 = options.env ?? process.env;
1749
+ if (env2[MEMORAONE_PLUGIN_ENV] !== MEMORAONE_CURSOR_PLUGIN) {
1750
+ return false;
1751
+ }
1752
+ if (options.daemonBindingHint) {
1753
+ return false;
1754
+ }
1755
+ return true;
1756
+ }
1757
+ function collectPluginStartupBindingRoots(options) {
1758
+ const seen = /* @__PURE__ */ new Set();
1759
+ const roots = [];
1760
+ const add = (raw) => {
1761
+ if (raw === void 0 || raw === null || raw.trim() === "") {
1762
+ return;
1763
+ }
1764
+ const resolved = path13.resolve(raw);
1765
+ if (seen.has(resolved)) {
1766
+ return;
1767
+ }
1768
+ seen.add(resolved);
1769
+ roots.push(resolved);
1770
+ };
1771
+ for (const root of options.initializeRoots ?? []) {
1772
+ add(root);
1773
+ }
1774
+ for (const uri of options.rootsListUris ?? []) {
1775
+ add(uriToPath(uri));
1776
+ }
1777
+ add(getRepoScopedWorkspaceHint(options.env));
1778
+ return roots;
1779
+ }
1780
+ async function hasPendingPluginStartupBinding(workspaceRoots, options = {}) {
1781
+ for (const root of workspaceRoots) {
1782
+ try {
1783
+ const identity = await lookupLocalBindingIdentity(root, {
1784
+ homeDir: options.homeDir
1785
+ });
1786
+ if (identity.status !== "resolved") {
1787
+ continue;
1788
+ }
1789
+ const record = await readBindingRecord(
1790
+ identity.repositoryBindingId,
1791
+ options.homeDir
1792
+ );
1793
+ if (record?.status === "pending") {
1794
+ return true;
1795
+ }
1796
+ } catch {
1797
+ continue;
1798
+ }
1799
+ }
1800
+ return false;
1801
+ }
1802
+ async function isRetryablePluginStartupBindingError(err, options = {}) {
1803
+ const message = errorMessage(err);
1804
+ if (isUnboundPluginStartupBindingMessage(message)) {
1805
+ return true;
1806
+ }
1807
+ if (isCredentialsMissingMessage(message) && await pendingBindingWindowOpen(options.isPendingBinding)) {
1808
+ return true;
1809
+ }
1810
+ return false;
1811
+ }
1812
+ function defaultSleep(ms) {
1813
+ return new Promise((resolve11) => {
1814
+ setTimeout(resolve11, ms);
1815
+ });
1816
+ }
1817
+ async function waitForPluginStartupBinding(resolve11, options = {}) {
1818
+ const now = options.now ?? Date.now;
1819
+ const sleep = options.sleep ?? defaultSleep;
1820
+ const timeoutMs = options.timeoutMs ?? PLUGIN_STARTUP_BINDING_WAIT_TIMEOUT_MS;
1821
+ const intervalMs = options.intervalMs ?? PLUGIN_STARTUP_BINDING_WAIT_INTERVAL_MS;
1822
+ const startedAt = now();
1823
+ let waitingLogged = false;
1824
+ let lastError;
1825
+ while (true) {
1826
+ try {
1827
+ const binding = await resolve11();
1828
+ if (waitingLogged) {
1829
+ options.log?.(
1830
+ `local MemoraOne binding available after Cursor plugin pairing (${now() - startedAt}ms)`
1831
+ );
1832
+ }
1833
+ return binding;
1834
+ } catch (err) {
1835
+ lastError = err;
1836
+ const retryable = await isRetryablePluginStartupBindingError(err, {
1837
+ isPendingBinding: options.isPendingBinding
1838
+ });
1839
+ if (!retryable) {
1840
+ throw err;
1841
+ }
1842
+ if (now() - startedAt >= timeoutMs) {
1843
+ throw lastError;
1844
+ }
1845
+ if (!waitingLogged) {
1846
+ options.log?.(
1847
+ "waiting for local MemoraOne binding after Cursor plugin pairing"
1848
+ );
1849
+ waitingLogged = true;
1850
+ }
1851
+ await sleep(intervalMs);
1852
+ }
1853
+ }
1854
+ }
1855
+
1693
1856
  // src/bindingSidecar.ts
1694
1857
  var fs9 = __toESM(require("fs"), 1);
1695
- var path13 = __toESM(require("path"), 1);
1858
+ var path14 = __toESM(require("path"), 1);
1696
1859
  function bindingSidecarPath(socketPath) {
1697
1860
  if (socketPath.endsWith(".sock")) {
1698
1861
  return `${socketPath.slice(0, -".sock".length)}.binding.json`;
@@ -2153,9 +2316,9 @@ function buildPersonalContextPath(parsed2) {
2153
2316
  }
2154
2317
  async function handleGetPersonalContext(client, args) {
2155
2318
  const parsed2 = getPersonalContextInputSchema.parse(args ?? {});
2156
- const path15 = buildPersonalContextPath(parsed2);
2319
+ const path16 = buildPersonalContextPath(parsed2);
2157
2320
  try {
2158
- const result = await client.get(path15);
2321
+ const result = await client.get(path16);
2159
2322
  return { ok: true, result };
2160
2323
  } catch (err) {
2161
2324
  if (err instanceof MemoraOneHttpError) {
@@ -2627,8 +2790,8 @@ async function handleCreateConceptVersion(client, args) {
2627
2790
  if (input.tags !== void 0) body.tags = input.tags;
2628
2791
  if (input.parent_id !== void 0) body.parent_id = input.parent_id;
2629
2792
  try {
2630
- const path15 = `/concepts/${encodeURIComponent(input.id)}/versions`;
2631
- return projectCreatedConceptVersionResponse(await client.post(path15, body));
2793
+ const path16 = `/concepts/${encodeURIComponent(input.id)}/versions`;
2794
+ return projectCreatedConceptVersionResponse(await client.post(path16, body));
2632
2795
  } catch (error) {
2633
2796
  rethrowToolRequestError("memora_create_concept_version", error);
2634
2797
  }
@@ -2663,7 +2826,7 @@ function handleBindingStatus(binding, options = {}) {
2663
2826
  // src/heartbeat.ts
2664
2827
  var crypto5 = __toESM(require("crypto"), 1);
2665
2828
  var fs10 = __toESM(require("fs"), 1);
2666
- var path14 = __toESM(require("path"), 1);
2829
+ var path15 = __toESM(require("path"), 1);
2667
2830
 
2668
2831
  // src/localState/mcpSessionId.ts
2669
2832
  var import_node_crypto4 = require("crypto");
@@ -2696,9 +2859,9 @@ function resolvePackageVersion() {
2696
2859
  if (fromEnv) return fromEnv;
2697
2860
  const moduleDir = typeof __dirname !== "undefined" ? __dirname : void 0;
2698
2861
  const candidates = [
2699
- ...moduleDir ? [path14.join(moduleDir, "..", "package.json"), path14.join(moduleDir, "package.json")] : [],
2700
- path14.join(process.cwd(), "package.json"),
2701
- path14.join(process.cwd(), "packages", "mcp", "package.json")
2862
+ ...moduleDir ? [path15.join(moduleDir, "..", "package.json"), path15.join(moduleDir, "package.json")] : [],
2863
+ path15.join(process.cwd(), "package.json"),
2864
+ path15.join(process.cwd(), "packages", "mcp", "package.json")
2702
2865
  ];
2703
2866
  for (const candidate of candidates) {
2704
2867
  try {
@@ -3217,8 +3380,8 @@ function registerToolWithWorklog(server, runtime, sessionContext, toolName, desc
3217
3380
  async function main(opts = {}) {
3218
3381
  let bindingReadyResolve = null;
3219
3382
  let bindingReadyReject = null;
3220
- const bindingReady = new Promise((resolve10, reject) => {
3221
- bindingReadyResolve = resolve10;
3383
+ const bindingReady = new Promise((resolve11, reject) => {
3384
+ bindingReadyResolve = resolve11;
3222
3385
  bindingReadyReject = reject;
3223
3386
  });
3224
3387
  const devMode = Boolean(config2.devMode);
@@ -3299,12 +3462,25 @@ async function main(opts = {}) {
3299
3462
  console.error("[memoraone-mcp][init-debug] Workspace resolution strategy: initialize.rootUri");
3300
3463
  }
3301
3464
  }
3302
- const binding = await resolveBindingFromInitializeParams(params, {
3465
+ const resolveBinding = () => resolveBindingFromInitializeParams(params, {
3303
3466
  fallbackWorkspaceRoots: getEnvWorkspaceRootCandidates(),
3304
3467
  rootsListUris,
3305
3468
  rootsListAttempted,
3306
3469
  ...getBridgeBindingResolveOptions()
3307
3470
  });
3471
+ const binding = shouldWaitForPluginStartupBinding({
3472
+ env: process.env,
3473
+ daemonBindingHint: opts.daemonBindingHint
3474
+ }) ? await waitForPluginStartupBinding(resolveBinding, {
3475
+ isPendingBinding: () => hasPendingPluginStartupBinding(
3476
+ collectPluginStartupBindingRoots({
3477
+ initializeRoots,
3478
+ rootsListUris,
3479
+ env: process.env
3480
+ })
3481
+ ),
3482
+ log: (msg) => console.error(`[memoraone-mcp] ${msg}`)
3483
+ }) : await resolveBinding();
3308
3484
  workspaceRoot = binding.workspaceRoot;
3309
3485
  return binding;
3310
3486
  };
@@ -3691,10 +3867,10 @@ async function main(opts = {}) {
3691
3867
  console.error("[memoraone-mcp] MCP server ready");
3692
3868
  }
3693
3869
  if (opts.sessionSocket) {
3694
- await new Promise((resolve10) => {
3870
+ await new Promise((resolve11) => {
3695
3871
  opts.sessionSocket.once("close", () => {
3696
3872
  shutdown("session closed", false);
3697
- resolve10();
3873
+ resolve11();
3698
3874
  });
3699
3875
  });
3700
3876
  }
@@ -9982,7 +9982,7 @@ var PluginRepositoryPairingSession = class {
9982
9982
  ideType: this.source,
9983
9983
  fetchImpl: this.connectOptions.fetchImpl ?? this.fetchImpl,
9984
9984
  // Plugin pairing configures only the IDE that initiated the pairing.
9985
- configureIdes: true,
9985
+ configureIdes: this.source !== "cursor",
9986
9986
  setupIdeOptions: {
9987
9987
  ...this.connectOptions.setupIdeOptions,
9988
9988
  targets: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memoraone/mcp",
3
- "version": "0.1.46",
3
+ "version": "0.1.48",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "exports": {