libp2p-mesh 2026.6.6 → 2026.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -81,10 +81,44 @@ function interactiveSelect(prompt, choices) {
81
81
  renderChoices(choices, selectedIdx);
82
82
  return new Promise((resolve) => {
83
83
  const wasRaw = process.stdin.isRaw;
84
- process.stdin.setRawMode(true);
85
- readline.emitKeypressEvents(process.stdin);
84
+ const wasPaused = process.stdin.isPaused();
85
+ let resolved = false;
86
+ const cleanup = () => {
87
+ if (resolved)
88
+ return;
89
+ try {
90
+ process.stdin.setRawMode(wasRaw ?? false);
91
+ }
92
+ catch {
93
+ // best-effort restore
94
+ }
95
+ if (wasPaused)
96
+ process.stdin.pause();
97
+ process.stdin.removeListener("keypress", onKeypress);
98
+ };
99
+ // Pause before reconfiguring stdin to avoid data race
100
+ process.stdin.pause();
101
+ // Must call emitKeypressEvents BEFORE setRawMode per Node.js docs
102
+ try {
103
+ readline.emitKeypressEvents(process.stdin);
104
+ }
105
+ catch {
106
+ cleanup();
107
+ fallbackNumberedSelect(prompt, choices).then(resolve);
108
+ return;
109
+ }
110
+ try {
111
+ process.stdin.setRawMode(true);
112
+ }
113
+ catch {
114
+ // setRawMode may fail on some terminals; clean up and fall back
115
+ cleanup();
116
+ fallbackNumberedSelect(prompt, choices).then(resolve);
117
+ return;
118
+ }
119
+ process.stdin.resume();
86
120
  const onKeypress = (_str, key) => {
87
- if (!key)
121
+ if (!key || !key.name)
88
122
  return;
89
123
  if (key.name === "up" || key.name === "k") {
90
124
  selectedIdx =
@@ -96,6 +130,7 @@ function interactiveSelect(prompt, choices) {
96
130
  reRenderChoices(choices, selectedIdx);
97
131
  }
98
132
  else if (key.name === "return" || key.name === "space") {
133
+ resolved = true;
99
134
  const chosen = choices[selectedIdx];
100
135
  cleanup();
101
136
  clearChoices(choices.length);
@@ -108,10 +143,6 @@ function interactiveSelect(prompt, choices) {
108
143
  process.exit(0);
109
144
  }
110
145
  };
111
- const cleanup = () => {
112
- process.stdin.setRawMode(wasRaw ?? false);
113
- process.stdin.removeListener("keypress", onKeypress);
114
- };
115
146
  process.stdin.on("keypress", onKeypress);
116
147
  });
117
148
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "libp2p-mesh",
3
- "version": "2026.6.6",
3
+ "version": "2026.6.7",
4
4
  "description": "OpenClaw libp2p P2P mesh network plugin for cross-instance agent communication",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/wizard.ts CHANGED
@@ -133,15 +133,46 @@ function interactiveSelect(
133
133
 
134
134
  return new Promise((resolve) => {
135
135
  const wasRaw = process.stdin.isRaw;
136
+ const wasPaused = process.stdin.isPaused();
136
137
 
137
- process.stdin.setRawMode(true);
138
- readline.emitKeypressEvents(process.stdin);
138
+ let resolved = false;
139
+
140
+ const cleanup = () => {
141
+ if (resolved) return;
142
+ try {
143
+ process.stdin.setRawMode(wasRaw ?? false);
144
+ } catch {
145
+ // best-effort restore
146
+ }
147
+ if (wasPaused) process.stdin.pause();
148
+ process.stdin.removeListener("keypress", onKeypress);
149
+ };
150
+
151
+ // Pause before reconfiguring stdin to avoid data race
152
+ process.stdin.pause();
153
+ // Must call emitKeypressEvents BEFORE setRawMode per Node.js docs
154
+ try {
155
+ readline.emitKeypressEvents(process.stdin);
156
+ } catch {
157
+ cleanup();
158
+ fallbackNumberedSelect(prompt, choices).then(resolve);
159
+ return;
160
+ }
161
+ try {
162
+ process.stdin.setRawMode(true);
163
+ } catch {
164
+ // setRawMode may fail on some terminals; clean up and fall back
165
+ cleanup();
166
+ fallbackNumberedSelect(prompt, choices).then(resolve);
167
+ return;
168
+ }
169
+ process.stdin.resume();
139
170
 
140
171
  const onKeypress = (
141
172
  _str: string | undefined,
142
173
  key: { name?: string; ctrl?: boolean },
143
174
  ) => {
144
- if (!key) return;
175
+ if (!key || !key.name) return;
145
176
 
146
177
  if (key.name === "up" || key.name === "k") {
147
178
  selectedIdx =
@@ -151,6 +182,7 @@ function interactiveSelect(
151
182
  selectedIdx = (selectedIdx + 1) % choices.length;
152
183
  reRenderChoices(choices, selectedIdx);
153
184
  } else if (key.name === "return" || key.name === "space") {
185
+ resolved = true;
154
186
  const chosen = choices[selectedIdx]!;
155
187
  cleanup();
156
188
  clearChoices(choices.length);
@@ -163,11 +195,6 @@ function interactiveSelect(
163
195
  }
164
196
  };
165
197
 
166
- const cleanup = () => {
167
- process.stdin.setRawMode(wasRaw ?? false);
168
- process.stdin.removeListener("keypress", onKeypress);
169
- };
170
-
171
198
  process.stdin.on("keypress", onKeypress);
172
199
  });
173
200
  }