@myagentroam/node 0.12.0 → 0.12.1

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 (132) hide show
  1. package/dist/code-navigation/index.js +2 -0
  2. package/dist/code-navigation/languages/c-family.js +9 -0
  3. package/dist/code-navigation/languages/c-preprocessor.js +30 -0
  4. package/dist/code-navigation/languages/c.js +8 -0
  5. package/dist/code-navigation/languages/cpp.js +10 -0
  6. package/dist/code-navigation/languages/csharp.js +18 -0
  7. package/dist/code-navigation/languages/css.js +7 -0
  8. package/dist/code-navigation/languages/ecmascript.js +44 -0
  9. package/dist/code-navigation/languages/file-target.js +9 -0
  10. package/dist/code-navigation/languages/go.js +32 -0
  11. package/dist/code-navigation/languages/html.js +7 -0
  12. package/dist/code-navigation/languages/jvm.js +17 -0
  13. package/dist/code-navigation/languages/less.js +7 -0
  14. package/dist/code-navigation/languages/markdown.js +113 -0
  15. package/dist/code-navigation/languages/markup-reference.js +27 -0
  16. package/dist/code-navigation/languages/objective-c.js +11 -0
  17. package/dist/code-navigation/languages/objective-cpp.js +10 -0
  18. package/dist/code-navigation/languages/python.js +17 -0
  19. package/dist/code-navigation/languages/rust.js +18 -0
  20. package/dist/code-navigation/languages/sass.js +7 -0
  21. package/dist/code-navigation/languages/scss.js +7 -0
  22. package/dist/code-navigation/languages/stylesheet-reference.js +37 -0
  23. package/dist/code-navigation/languages/vue.js +75 -0
  24. package/dist/code-navigation/registry.js +72 -0
  25. package/dist/code-navigation/source-ranges.js +17 -0
  26. package/dist/code-navigation/symbol-maps.js +257 -0
  27. package/dist/code-navigation/symbol-matcher.js +48 -0
  28. package/dist/code-navigation/symbol-navigation.js +1 -0
  29. package/dist/code-navigation/types.js +1 -0
  30. package/dist/ctags-binary.js +3 -3
  31. package/dist/marctl/bin/marctl.mjs +6 -0
  32. package/dist/marctl/bin/marnodes.mjs +6 -0
  33. package/dist/marctl/bin/marscp.mjs +6 -0
  34. package/dist/marctl/bin/marssh.mjs +6 -0
  35. package/dist/marctl/package.json +1 -0
  36. package/dist/marctl/src/cli.mjs +271 -0
  37. package/dist/marctl/src/client.mjs +291 -0
  38. package/dist/marctl/src/config.mjs +46 -0
  39. package/dist/marctl/src/direct-control.mjs +225 -0
  40. package/dist/marctl/src/direct-errors.mjs +48 -0
  41. package/dist/marctl/src/direct-process.mjs +374 -0
  42. package/dist/marctl/src/direct-transport.mjs +235 -0
  43. package/dist/marctl/src/direct.mjs +421 -0
  44. package/dist/marctl/src/errors.mjs +11 -0
  45. package/dist/marctl/src/i18n/en-US.mjs +285 -0
  46. package/dist/marctl/src/i18n/index.mjs +20 -0
  47. package/dist/marctl/src/i18n/zh-CN.mjs +269 -0
  48. package/dist/marctl/src/scp-channel.mjs +99 -0
  49. package/dist/marctl/src/scp-copy.mjs +46 -0
  50. package/dist/marctl/src/scp-endpoint.mjs +29 -0
  51. package/dist/marctl/src/scp-protocol.mjs +2 -0
  52. package/dist/marctl/src/scp-worker.cjs +266 -0
  53. package/dist/marctl/src/scp-workers.mjs +179 -0
  54. package/dist/marctl/src/scp.mjs +64 -0
  55. package/dist/marctl/src/session-args.mjs +233 -0
  56. package/dist/marctl/src/session-input.mjs +43 -0
  57. package/dist/marctl/src/session-prepare.mjs +87 -0
  58. package/dist/marctl/src/session-target.mjs +26 -0
  59. package/dist/marctl/src/session-wait.mjs +232 -0
  60. package/dist/marctl/src/sessions.mjs +93 -0
  61. package/dist/marctl/src/terminal-frame.mjs +48 -0
  62. package/dist/marctl/src/terminal-interaction.mjs +177 -0
  63. package/dist/marctl/src/terminal-race.mjs +117 -0
  64. package/dist/marctl/src/terminal-relay-sender.mjs +129 -0
  65. package/dist/marctl/src/terminal-relay.mjs +305 -0
  66. package/dist/marctl/src/terminal.mjs +152 -0
  67. package/dist/marctl.js +1 -1
  68. package/dist/marnodes.js +1 -1
  69. package/dist/marscp.js +1 -1
  70. package/dist/marssh.js +1 -1
  71. package/dist/ripgrep-binary.js +3 -3
  72. package/dist/runner/mar-agent/agent-operation-presentation.js +22 -10
  73. package/dist/service/code-navigation/file-reference-parser.js +1 -1
  74. package/dist/service/node-terminal-channel.js +1 -1
  75. package/dist/session/session-catalog-service.js +4 -1
  76. package/dist/workspace/workspace-code-navigation-service.js +2 -2
  77. package/package.json +11 -9
  78. package/vendor/ctags/NOTICE +0 -22
  79. package/vendor/ctags/darwin-arm64/ctags +0 -0
  80. package/vendor/ctags/darwin-x64/ctags +0 -0
  81. package/vendor/ctags/licenses/COPYING +0 -340
  82. package/vendor/ctags/licenses/COPYING.MinGW-w64-runtime.txt +0 -240
  83. package/vendor/ctags/licenses/LICENSE.janssen +0 -19
  84. package/vendor/ctags/licenses/LICENSE.libyaml +0 -19
  85. package/vendor/ctags/licenses/official-snapshot/darwin-arm64/COPYING +0 -340
  86. package/vendor/ctags/licenses/official-snapshot/darwin-arm64/RECEIPT.yml +0 -27
  87. package/vendor/ctags/licenses/official-snapshot/darwin-arm64/dependencies/libiconv.yml +0 -24
  88. package/vendor/ctags/licenses/official-snapshot/darwin-arm64/dependencies/libjansson.yml +0 -19
  89. package/vendor/ctags/licenses/official-snapshot/darwin-arm64/dependencies/libxml2.yml +0 -20
  90. package/vendor/ctags/licenses/official-snapshot/darwin-arm64/dependencies/libyaml.yml +0 -7
  91. package/vendor/ctags/licenses/official-snapshot/darwin-arm64/dependencies/libz.yml +0 -13
  92. package/vendor/ctags/licenses/official-snapshot/darwin-x64/COPYING +0 -340
  93. package/vendor/ctags/licenses/official-snapshot/darwin-x64/RECEIPT.yml +0 -27
  94. package/vendor/ctags/licenses/official-snapshot/darwin-x64/dependencies/libiconv.yml +0 -24
  95. package/vendor/ctags/licenses/official-snapshot/darwin-x64/dependencies/libjansson.yml +0 -19
  96. package/vendor/ctags/licenses/official-snapshot/darwin-x64/dependencies/libxml2.yml +0 -20
  97. package/vendor/ctags/licenses/official-snapshot/darwin-x64/dependencies/libyaml.yml +0 -7
  98. package/vendor/ctags/licenses/official-snapshot/darwin-x64/dependencies/libz.yml +0 -13
  99. package/vendor/ctags/licenses/official-snapshot/linux-arm64/COPYING +0 -340
  100. package/vendor/ctags/licenses/official-snapshot/linux-arm64/RECEIPT.yml +0 -27
  101. package/vendor/ctags/licenses/official-snapshot/linux-arm64/dependencies/libiconv.yml +0 -24
  102. package/vendor/ctags/licenses/official-snapshot/linux-arm64/dependencies/libjansson.yml +0 -19
  103. package/vendor/ctags/licenses/official-snapshot/linux-arm64/dependencies/libxml2.yml +0 -20
  104. package/vendor/ctags/licenses/official-snapshot/linux-arm64/dependencies/libyaml.yml +0 -7
  105. package/vendor/ctags/licenses/official-snapshot/linux-arm64/dependencies/libz.yml +0 -13
  106. package/vendor/ctags/licenses/official-snapshot/linux-x64/COPYING +0 -340
  107. package/vendor/ctags/licenses/official-snapshot/linux-x64/RECEIPT.yml +0 -27
  108. package/vendor/ctags/licenses/official-snapshot/linux-x64/dependencies/libiconv.yml +0 -24
  109. package/vendor/ctags/licenses/official-snapshot/linux-x64/dependencies/libjansson.yml +0 -19
  110. package/vendor/ctags/licenses/official-snapshot/linux-x64/dependencies/libxml2.yml +0 -20
  111. package/vendor/ctags/licenses/official-snapshot/linux-x64/dependencies/libyaml.yml +0 -7
  112. package/vendor/ctags/licenses/official-snapshot/linux-x64/dependencies/libz.yml +0 -13
  113. package/vendor/ctags/licenses/win32-x64/COPYING +0 -340
  114. package/vendor/ctags/licenses/win32-x64/COPYING.MinGW-w64-runtime.txt +0 -240
  115. package/vendor/ctags/licenses/win32-x64/Copyright.libxml2 +0 -23
  116. package/vendor/ctags/licenses/win32-x64/LICENCE.pcre2 +0 -94
  117. package/vendor/ctags/licenses/win32-x64/LICENSE.janssen +0 -19
  118. package/vendor/ctags/licenses/win32-x64/LICENSE.libyaml +0 -19
  119. package/vendor/ctags/linux-arm64/ctags +0 -0
  120. package/vendor/ctags/linux-x64/ctags +0 -0
  121. package/vendor/ctags/manifest.json +0 -42
  122. package/vendor/ctags/source/universal-ctags-ab95af198f8eaeb6d50dc96e3adf52e769d3e5f0.tar.gz +0 -0
  123. package/vendor/ctags/win32-x64/ctags.exe +0 -0
  124. package/vendor/ripgrep/LICENSE-MIT +0 -21
  125. package/vendor/ripgrep/UNLICENSE +0 -24
  126. package/vendor/ripgrep/darwin-arm64/rg +0 -0
  127. package/vendor/ripgrep/darwin-x64/rg +0 -0
  128. package/vendor/ripgrep/linux-arm64/rg +0 -0
  129. package/vendor/ripgrep/linux-x64/rg +0 -0
  130. package/vendor/ripgrep/manifest.json +0 -42
  131. package/vendor/ripgrep/win32-arm64/rg.exe +0 -0
  132. package/vendor/ripgrep/win32-x64/rg.exe +0 -0
@@ -0,0 +1,305 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { MarctlError } from './errors.mjs';
3
+ import { TerminalRelaySender } from './terminal-relay-sender.mjs';
4
+ import { parseFrame } from './terminal-frame.mjs';
5
+ import { DirectFallbackError } from './direct-errors.mjs';
6
+
7
+ export async function openRelayTransport({
8
+ client,
9
+ WebSocketClass,
10
+ nodeId,
11
+ terminalId,
12
+ translate,
13
+ connectionTimeoutMs,
14
+ signal
15
+ }) {
16
+ const ticket = await client.createAttachTicket({ nodeId, terminalId });
17
+ if (signal?.aborted) throw new DirectFallbackError('DIRECT_RACE_CANCELLED');
18
+ const socket = client.openTerminalWebSocket(WebSocketClass, { terminalId, ticket });
19
+ const transport = new BufferedRelayTransport({
20
+ socket,
21
+ terminalId,
22
+ translate,
23
+ connectionTimeoutMs
24
+ });
25
+ try {
26
+ await waitForAttachment(transport, signal);
27
+ return transport;
28
+ } catch (error) {
29
+ transport.close();
30
+ throw error;
31
+ }
32
+ }
33
+
34
+ export async function prepareRelayTransport({
35
+ client,
36
+ WebSocketClass,
37
+ nodeId,
38
+ terminalId,
39
+ translate,
40
+ connectionTimeoutMs,
41
+ signal,
42
+ onPrepared
43
+ }) {
44
+ const ticket = await client.createAttachTicket({ nodeId, terminalId });
45
+ if (onPrepared) await onPrepared();
46
+ if (signal?.aborted) throw new MarctlError(translate('errors.terminalAttachConnection'));
47
+ const socket = client.openTerminalWebSocket(WebSocketClass, {
48
+ terminalId,
49
+ ticket,
50
+ deferred: true
51
+ });
52
+ // Keep an error listener after readiness until the socket is discarded.
53
+ socket.on('error', () => {});
54
+ let activated = false;
55
+ const ready = new Promise((resolve, reject) => {
56
+ const timer = setTimeout(() => fail(), connectionTimeoutMs);
57
+ const cleanup = () => {
58
+ clearTimeout(timer);
59
+ socket.removeListener?.('message', onMessage);
60
+ socket.removeListener?.('error', fail);
61
+ socket.removeListener?.('close', fail);
62
+ signal?.removeEventListener('abort', fail);
63
+ };
64
+ const fail = () => {
65
+ cleanup();
66
+ try {
67
+ socket.close();
68
+ } catch {
69
+ /* Connection not yet established. */
70
+ }
71
+ reject(new MarctlError(translate('errors.terminalAttachConnection')));
72
+ };
73
+ const onMessage = (raw) => {
74
+ let frame;
75
+ try {
76
+ frame = JSON.parse(String(raw));
77
+ } catch {
78
+ return fail();
79
+ }
80
+ if (frame?.type !== 'ready' || frame.terminalId !== terminalId) return fail();
81
+ cleanup();
82
+ resolve();
83
+ };
84
+ socket.on('message', onMessage);
85
+ socket.on('error', fail);
86
+ socket.on('close', fail);
87
+ signal?.addEventListener('abort', fail, { once: true });
88
+ if (signal?.aborted) fail();
89
+ });
90
+ await ready;
91
+ return {
92
+ async activate(signal) {
93
+ if (signal?.aborted) {
94
+ socket.close();
95
+ throw new DirectFallbackError('DIRECT_RACE_CANCELLED');
96
+ }
97
+ if (activated || socket.readyState !== 1)
98
+ throw new MarctlError(translate('errors.terminalAttachConnection'));
99
+ activated = true;
100
+ const transport = new BufferedRelayTransport({
101
+ socket,
102
+ terminalId,
103
+ translate,
104
+ connectionTimeoutMs
105
+ });
106
+ try {
107
+ socket.send(JSON.stringify({ type: 'activate', terminalId }));
108
+ await waitForAttachment(transport, signal);
109
+ return transport;
110
+ } catch (error) {
111
+ transport.close();
112
+ throw error;
113
+ }
114
+ },
115
+ close() {
116
+ socket.close();
117
+ }
118
+ };
119
+ }
120
+
121
+ async function waitForAttachment(transport, signal) {
122
+ if (!signal) return transport.waitForAttachment();
123
+ if (signal.aborted) throw new DirectFallbackError('DIRECT_RACE_CANCELLED');
124
+ let cancel;
125
+ const cancelled = new Promise((_, reject) => {
126
+ cancel = () => {
127
+ transport.close();
128
+ reject(new DirectFallbackError('DIRECT_RACE_CANCELLED'));
129
+ };
130
+ signal.addEventListener('abort', cancel, { once: true });
131
+ });
132
+ try {
133
+ return await Promise.race([transport.waitForAttachment(), cancelled]);
134
+ } finally {
135
+ signal.removeEventListener('abort', cancel);
136
+ }
137
+ }
138
+
139
+ class BufferedRelayTransport extends EventEmitter {
140
+ #socket;
141
+ #sender;
142
+ #terminalId;
143
+ #translate;
144
+ #attached = false;
145
+ #active = false;
146
+ #pendingEvents = [];
147
+ #attachmentResolve;
148
+ #attachmentReject;
149
+ #openTimer;
150
+ #attachTimer;
151
+ #closed = false;
152
+ #onOpen;
153
+ #onMessage;
154
+ #onError;
155
+ #onClose;
156
+
157
+ constructor({ socket, terminalId, translate, connectionTimeoutMs }) {
158
+ super();
159
+ this.#socket = socket;
160
+ this.#sender = new TerminalRelaySender(socket);
161
+ this.#terminalId = terminalId;
162
+ this.#translate = translate;
163
+ this.#onOpen = () => {
164
+ clearTimeout(this.#openTimer);
165
+ this.#armAttachTimer(connectionTimeoutMs);
166
+ };
167
+ this.#onMessage = (raw, isBinary) => {
168
+ try {
169
+ const frame = parseFrame(raw, isBinary, this.#terminalId, this.#translate);
170
+ if (!this.#attached) {
171
+ if (frame.type === 'attach') {
172
+ this.#attached = true;
173
+ clearTimeout(this.#attachTimer);
174
+ this.#attachmentResolve?.();
175
+ this.#attachmentResolve = undefined;
176
+ this.#attachmentReject = undefined;
177
+ return;
178
+ }
179
+ if (frame.type === 'error')
180
+ throw new MarctlError(this.#translate('errors.terminalRemoteError'));
181
+ this.#queueOrEmit('message', raw, isBinary);
182
+ return;
183
+ }
184
+ this.#queueOrEmit('message', raw, isBinary);
185
+ } catch (error) {
186
+ this.#fail(
187
+ error instanceof MarctlError
188
+ ? error
189
+ : new MarctlError(this.#translate('errors.terminalFrameInvalid'))
190
+ );
191
+ }
192
+ };
193
+ this.#onError = () => {
194
+ const error = new MarctlError(
195
+ this.#translate(
196
+ this.#attached ? 'errors.terminalConnectionFailed' : 'errors.terminalAttachConnection'
197
+ )
198
+ );
199
+ if (this.#attached) this.#queueOrEmit('error', error);
200
+ else this.#fail(error);
201
+ };
202
+ this.#onClose = () => {
203
+ this.#sender.close();
204
+ const error = new MarctlError(
205
+ this.#translate(
206
+ this.#attached ? 'errors.terminalConnectionLost' : 'errors.terminalAttachLost'
207
+ )
208
+ );
209
+ if (this.#attached) this.#queueOrEmit('close');
210
+ else this.#fail(error);
211
+ };
212
+
213
+ socket.on?.('open', this.#onOpen);
214
+ socket.on?.('message', this.#onMessage);
215
+ socket.on?.('error', this.#onError);
216
+ socket.on?.('close', this.#onClose);
217
+ if (socket.readyState === 1) this.#onOpen();
218
+ else
219
+ this.#openTimer = setTimeout(
220
+ () => this.#fail(new MarctlError(this.#translate('errors.terminalConnectionOpen'))),
221
+ connectionTimeoutMs
222
+ );
223
+ }
224
+
225
+ waitForAttachment() {
226
+ return new Promise((resolve, reject) => {
227
+ if (this.#closed) {
228
+ reject(new MarctlError(this.#translate('errors.terminalAttachLost')));
229
+ return;
230
+ }
231
+ this.#attachmentResolve = resolve;
232
+ this.#attachmentReject = reject;
233
+ if (this.#attached) {
234
+ this.#attachmentResolve = undefined;
235
+ this.#attachmentReject = undefined;
236
+ resolve();
237
+ }
238
+ });
239
+ }
240
+
241
+ activate() {
242
+ if (this.#active) return;
243
+ this.#active = true;
244
+ const pendingEvents = this.#pendingEvents;
245
+ this.#pendingEvents = [];
246
+ for (const { type, args } of pendingEvents) this.emit(type, ...args);
247
+ }
248
+
249
+ get readyState() {
250
+ return this.#socket.readyState;
251
+ }
252
+
253
+ send(value) {
254
+ if (this.#closed) throw new Error('TERMINAL_CONNECTION_LOST');
255
+ if (JSON.parse(value).type === 'input') return this.#sender.send(value);
256
+ this.#socket.send(value);
257
+ }
258
+
259
+ close() {
260
+ if (this.#closed) return;
261
+ this.#closed = true;
262
+ this.#attachmentReject?.(new MarctlError(this.#translate('errors.terminalAttachLost')));
263
+ this.#attachmentReject = undefined;
264
+ this.#attachmentResolve = undefined;
265
+ this.#sender.close();
266
+ clearTimeout(this.#openTimer);
267
+ clearTimeout(this.#attachTimer);
268
+ this.#socket.removeListener?.('open', this.#onOpen);
269
+ this.#socket.removeListener?.('message', this.#onMessage);
270
+ this.#socket.removeListener?.('error', this.#onError);
271
+ this.#socket.removeListener?.('close', this.#onClose);
272
+ try {
273
+ this.#socket.close();
274
+ } catch {
275
+ // The connection is already unavailable.
276
+ }
277
+ }
278
+
279
+ #armAttachTimer(connectionTimeoutMs) {
280
+ if (this.#attached) return;
281
+ this.#attachTimer = setTimeout(
282
+ () => this.#fail(new MarctlError(this.#translate('errors.terminalAttachTimeout'))),
283
+ connectionTimeoutMs
284
+ );
285
+ }
286
+
287
+ #fail(error) {
288
+ if (this.#closed) return;
289
+ clearTimeout(this.#openTimer);
290
+ clearTimeout(this.#attachTimer);
291
+ this.#attachmentResolve = undefined;
292
+ const reject = this.#attachmentReject;
293
+ this.#attachmentReject = undefined;
294
+ if (!this.#attached) reject?.(error);
295
+ else this.#queueOrEmit('error', error);
296
+ }
297
+
298
+ #queueOrEmit(type, ...args) {
299
+ if (this.#active) {
300
+ if (type !== 'error' || this.listenerCount('error') > 0) this.emit(type, ...args);
301
+ return;
302
+ }
303
+ this.#pendingEvents.push({ type, args });
304
+ }
305
+ }
@@ -0,0 +1,152 @@
1
+ import { MarctlError } from './errors.mjs';
2
+ import { DirectRejectedError } from './direct-errors.mjs';
3
+ import { createTranslator } from './i18n/index.mjs';
4
+ import { raceTerminalConnections } from './terminal-race.mjs';
5
+ import { openRelayTransport } from './terminal-relay.mjs';
6
+ import { getDimensions, runAttachedTerminal } from './terminal-interaction.mjs';
7
+
8
+ const DEFAULT_CONNECTION_TIMEOUT_MS = 15000;
9
+
10
+ export async function runTerminalSession({
11
+ client,
12
+ WebSocketClass,
13
+ nodeId,
14
+ command,
15
+ binary = false,
16
+ attached,
17
+ stdin = process.stdin,
18
+ stdout = process.stdout,
19
+ signal,
20
+ translate = createTranslator(),
21
+ connectionTimeoutMs = DEFAULT_CONNECTION_TIMEOUT_MS,
22
+ openDirectTerminal: openDirectTerminalImpl,
23
+ raceConnections = false
24
+ }) {
25
+ const dimensions = getDimensions(stdout);
26
+ let terminalId;
27
+ let transport;
28
+ let result;
29
+ let primaryError;
30
+ let manifest;
31
+
32
+ try {
33
+ if (signal?.aborted) return signal.reason === 'SIGTERM' ? 143 : 130;
34
+ if (binary) {
35
+ if (command === undefined)
36
+ throw new MarctlError(translate('errors.terminalBinaryUnavailable'));
37
+ manifest = await client.getTerminalManifest(nodeId);
38
+ if (signal?.aborted) return signal.reason === 'SIGTERM' ? 143 : 130;
39
+ if (manifest?.binaryTerminal !== true)
40
+ throw new MarctlError(translate('errors.terminalBinaryUnavailable'));
41
+ }
42
+ const created = await client.createTerminal({
43
+ nodeId,
44
+ ...dimensions,
45
+ ...(command === undefined ? {} : { command }),
46
+ ...(binary ? { binary: true } : {})
47
+ });
48
+ terminalId = binary ? created?.terminalId : created;
49
+ if (binary && created?.binary !== true)
50
+ throw new MarctlError(translate('errors.terminalBinaryUnavailable'));
51
+ if (signal?.aborted) return signal.reason === 'SIGTERM' ? 143 : 130;
52
+ try {
53
+ const openDirectTerminal =
54
+ openDirectTerminalImpl ?? (await import('./direct.mjs')).openDirectTerminal;
55
+ if (raceConnections && manifest === undefined)
56
+ manifest = await client.getTerminalManifest(nodeId).catch(() => undefined);
57
+ const directOptions = {
58
+ client,
59
+ WebSocketClass,
60
+ nodeId,
61
+ terminalId,
62
+ manifest,
63
+ afterSequence: 0,
64
+ timeoutMs: connectionTimeoutMs,
65
+ signal
66
+ };
67
+ const canRace = raceConnections && manifest?.deferredRelay === true;
68
+ transport = canRace
69
+ ? await raceTerminalConnections({
70
+ openDirectTerminal,
71
+ directOptions,
72
+ client,
73
+ WebSocketClass,
74
+ nodeId,
75
+ terminalId,
76
+ translate,
77
+ connectionTimeoutMs,
78
+ signal
79
+ })
80
+ : await openDirectTerminal(directOptions);
81
+ if (signal?.aborted) return signal.reason === 'SIGTERM' ? 143 : 130;
82
+ result =
83
+ attached === undefined
84
+ ? await runAttachedTerminal({
85
+ transport,
86
+ terminalId,
87
+ commandMode: command !== undefined,
88
+ stdin,
89
+ stdout,
90
+ signal,
91
+ translate
92
+ })
93
+ : await attached({ transport, terminalId, translate });
94
+ } catch (error) {
95
+ if (signal?.aborted) {
96
+ result = signal.reason === 'SIGTERM' ? 143 : 130;
97
+ } else {
98
+ if (error?.name === 'DirectUnsafeError')
99
+ throw new MarctlError(translate('errors.terminalDirectUnsafeFallback'));
100
+ if (error?.name !== 'DirectFallbackError') throw error;
101
+ transport = await openRelayTransport({
102
+ client,
103
+ WebSocketClass,
104
+ nodeId,
105
+ terminalId,
106
+ translate,
107
+ connectionTimeoutMs,
108
+ signal
109
+ });
110
+ if (signal?.aborted) return signal.reason === 'SIGTERM' ? 143 : 130;
111
+ result =
112
+ attached === undefined
113
+ ? await runAttachedTerminal({
114
+ transport,
115
+ terminalId,
116
+ commandMode: command !== undefined,
117
+ stdin,
118
+ stdout,
119
+ signal,
120
+ translate
121
+ })
122
+ : await attached({ transport, terminalId, translate });
123
+ }
124
+ }
125
+ } catch (error) {
126
+ if (signal?.aborted) result = signal.reason === 'SIGTERM' ? 143 : 130;
127
+ else primaryError = toMarctlError(error, translate);
128
+ } finally {
129
+ transport?.close?.();
130
+ if (terminalId !== undefined) {
131
+ try {
132
+ await client.deleteTerminal({ nodeId, terminalId });
133
+ } catch {
134
+ if (primaryError === undefined && result === undefined)
135
+ primaryError = new MarctlError(translate('errors.terminalCloseFailed'));
136
+ }
137
+ }
138
+ }
139
+
140
+ if (primaryError !== undefined) throw primaryError;
141
+ return result;
142
+ }
143
+
144
+ function toMarctlError(error, translate) {
145
+ if (error instanceof DirectRejectedError)
146
+ return new MarctlError(`${translate('errors.terminalSessionFailed')} [${error.code}]`, {
147
+ code: error.code
148
+ });
149
+ return error instanceof MarctlError
150
+ ? error
151
+ : new MarctlError(translate('errors.terminalSessionFailed'));
152
+ }
package/dist/marctl.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
2
  // Keep the CLI implementation in its own package; the Node install exposes the same entrypoint.
3
- const entrypoint = '@myagentroam/marctl/bin/marctl.mjs';
3
+ const entrypoint = './marctl/bin/marctl.mjs';
4
4
  await import(entrypoint);
5
5
  export {};
package/dist/marnodes.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- const entrypoint = '@myagentroam/marctl/bin/marnodes.mjs';
2
+ const entrypoint = './marctl/bin/marnodes.mjs';
3
3
  await import(entrypoint);
4
4
  export {};
package/dist/marscp.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- const entrypoint = '@myagentroam/marctl/bin/marscp.mjs';
2
+ const entrypoint = './marctl/bin/marscp.mjs';
3
3
  await import(entrypoint);
4
4
  export {};
package/dist/marssh.js CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- const entrypoint = '@myagentroam/marctl/bin/marssh.mjs';
2
+ const entrypoint = './marctl/bin/marssh.mjs';
3
3
  await import(entrypoint);
4
4
  export {};
@@ -1,5 +1,5 @@
1
1
  import { dirname, resolve } from 'node:path';
2
- import { fileURLToPath } from 'node:url';
2
+ import { createRequire } from 'node:module';
3
3
  export const BUNDLED_RIPGREP_VERSION = '15.1.0';
4
4
  const TARGETS = {
5
5
  'linux-x64': ['linux-x64', 'rg'],
@@ -11,8 +11,8 @@ const TARGETS = {
11
11
  };
12
12
  export function bundledRipgrepDirectory(packageRoot) {
13
13
  return packageRoot === undefined
14
- ? resolve(dirname(fileURLToPath(import.meta.url)), '..', 'vendor/ripgrep')
15
- : resolve(packageRoot, 'mar-node/vendor/ripgrep');
14
+ ? resolve(dirname(createRequire(import.meta.url).resolve('@myagentroam/binaries/package.json')), 'vendor/ripgrep')
15
+ : resolve(packageRoot, 'packages/binaries/vendor/ripgrep');
16
16
  }
17
17
  export function bundledRipgrepPath(platform = process.platform, architecture = process.arch, packageRoot) {
18
18
  const target = TARGETS[`${platform}-${architecture}`];
@@ -39,22 +39,34 @@ export function agentOperationPresentation(toolName, input, data) {
39
39
  if (!action)
40
40
  return undefined;
41
41
  const parsed = agentOperationPresentationSchema.safeParse(isPlainRecord(data) ? data.agentOperation : undefined);
42
- if (parsed.success && parsed.data.action === action)
43
- return parsed.data;
44
42
  const value = isPlainRecord(input) ? input : {};
45
43
  const ids = typeof value.agentId === 'string'
46
44
  ? [value.agentId]
47
45
  : Array.isArray(value.agentIds)
48
46
  ? value.agentIds
49
47
  : [];
50
- return {
51
- action,
52
- targets: ids
53
- .filter((id) => typeof id === 'string' && id.length > 0 && id.length <= 128)
54
- .slice(0, 8)
55
- .map((agentId) => ({ agentId })),
56
- ...(text(value.scope, 32) ? { scope: text(value.scope, 32) } : {})
57
- };
48
+ const operation = parsed.success && parsed.data.action === action
49
+ ? parsed.data
50
+ : {
51
+ action,
52
+ targets: ids
53
+ .filter((id) => typeof id === 'string' && id.length > 0 && id.length <= 128)
54
+ .slice(0, 8)
55
+ .map((agentId) => ({ agentId })),
56
+ ...(text(value.scope, 32) ? { scope: text(value.scope, 32) } : {})
57
+ };
58
+ const goal = isPlainRecord(value.goal) ? value.goal : undefined;
59
+ const objective = action === 'SEND' && !operation.detail?.message && !text(value.content) && goal?.clear !== true
60
+ ? text(goal?.objective, 2000)
61
+ : undefined;
62
+ if (objective)
63
+ operation.detail = {
64
+ ...operation.detail,
65
+ message: objective,
66
+ messageIsGoal: true,
67
+ ...(objective !== goal?.objective ? { messageTruncated: true } : {})
68
+ };
69
+ return operation;
58
70
  }
59
71
  /** Whitelist public receipts; never serialize configuration, credentials or full history. */
60
72
  export function agentOperationEvent(action, input, result) {
@@ -1,4 +1,4 @@
1
- import { fileSpecifierParser } from '@myagentroam/code-navigation';
1
+ import { fileSpecifierParser } from '../../code-navigation/index.js';
2
2
  const MAX_REFERENCE_REPARSE_POSITIONS = 8;
3
3
  export function reparseFileReference(path, requested) {
4
4
  const parser = fileSpecifierParser(path, requested.sourceContext.text);
@@ -3,7 +3,7 @@ import { terminalDataFrameSchema } from '@myagentroam/protocol';
3
3
  import { nodeTerminalConnectEndpoint } from '../connection/endpoints.js';
4
4
  import { isPlainRecord } from '../util/records.js';
5
5
  import { TerminalRelayState } from './terminal-relay-state.js';
6
- import { TerminalRelaySender } from '@myagentroam/marctl/src/terminal-relay-sender.mjs';
6
+ import { TerminalRelaySender } from '../marctl/src/terminal-relay-sender.mjs';
7
7
  export class NodeTerminalChannel {
8
8
  options;
9
9
  socket;
@@ -187,13 +187,16 @@ export class SessionCatalogService {
187
187
  for (const record of candidates) {
188
188
  if (selected.size >= query.limit)
189
189
  break;
190
+ const remaining = query.limit - selected.size;
190
191
  const path = [];
191
192
  let current = record;
192
193
  while (current !== undefined && !selected.has(current.id)) {
193
194
  path.push(current);
195
+ if (path.length > remaining)
196
+ break;
194
197
  current = byId.get(current.metadata.parentSessionId ?? '');
195
198
  }
196
- if (path.length > query.limit - selected.size)
199
+ if (path.length > remaining)
197
200
  continue;
198
201
  for (const ancestor of path.reverse())
199
202
  selected.set(ancestor.id, ancestor);
@@ -3,8 +3,8 @@ import { constants } from 'node:fs';
3
3
  import { access, open, realpath, rename, rm, stat, writeFile } from 'node:fs/promises';
4
4
  import { homedir } from 'node:os';
5
5
  import { relative, resolve, sep } from 'node:path';
6
- import { isNavigationSymbol } from '@myagentroam/code-navigation';
7
- import { supportsSymbolNavigationPath } from '@myagentroam/code-navigation/symbol-navigation';
6
+ import { isNavigationSymbol } from '../code-navigation/index.js';
7
+ import { supportsSymbolNavigationPath } from '../code-navigation/symbol-navigation.js';
8
8
  import { workspaceFileReferenceSchema } from '@myagentroam/protocol';
9
9
  import { bundledCtagsPath, BUNDLED_CTAGS_VERSION, repairBundledCtagsExecutable } from '../ctags-binary.js';
10
10
  import { nodeLog } from '../operational.js';
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "@myagentroam/node",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "MyAgentRoam Node runtime CLI.",
5
5
  "license": "Apache-2.0 AND GPL-2.0-or-later",
6
6
  "type": "module",
7
7
  "files": [
8
8
  "dist/**/*.js",
9
+ "dist/marctl/**/*.mjs",
10
+ "dist/marctl/**/*.cjs",
11
+ "dist/marctl/package.json",
9
12
  "scripts/install-web-browser.mjs",
10
- "vendor/ripgrep/**/*",
11
- "vendor/ctags/**/*",
12
13
  "dist/config.d.ts",
13
14
  "LICENSE",
14
15
  "NOTICE"
@@ -29,6 +30,7 @@
29
30
  "dependencies": {
30
31
  "@anthropic-ai/claude-agent-sdk": "0.3.233",
31
32
  "@modelcontextprotocol/sdk": "1.32.0",
33
+ "@myagentroam/binaries": "0.10.1",
32
34
  "@opencode-ai/sdk": "1.18.20",
33
35
  "minimatch": "^10.2.6",
34
36
  "node-datachannel": "0.33.4",
@@ -40,14 +42,14 @@
40
42
  "turndown-plugin-gfm": "^1.0.2",
41
43
  "ws": "^8.21.3",
42
44
  "zod": "4.4.3",
43
- "@myagentroam/agent": "0.12.0",
44
- "@myagentroam/marctl": "0.12.0",
45
- "@myagentroam/code-navigation": "0.11.1",
46
- "@myagentroam/protocol": "0.12.0"
45
+ "@myagentroam/protocol": "0.12.1",
46
+ "@myagentroam/agent": "0.12.1"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@types/turndown": "^5.0.6",
50
- "@types/ws": "^8.18.1"
50
+ "@types/ws": "^8.18.1",
51
+ "@myagentroam/code-navigation": "0.11.1",
52
+ "@myagentroam/marctl": "0.12.1"
51
53
  },
52
54
  "exports": {
53
55
  "./config": {
@@ -59,7 +61,7 @@
59
61
  },
60
62
  "scripts": {
61
63
  "postinstall": "node scripts/install-web-browser.mjs",
62
- "build": "node ../scripts/clean-build-output.mjs dist && tsc -p tsconfig.json",
64
+ "build": "node ../scripts/clean-build-output.mjs dist && tsc -p tsconfig.json && node ../scripts/stage-node-internals.mjs",
63
65
  "stage:computer-use-runtime": "node ../scripts/stage-computer-use-runtime.mjs",
64
66
  "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.tests.json --noEmit",
65
67
  "dev": "tsx watch src/main.ts",
@@ -1,22 +0,0 @@
1
- This directory distributes Universal Ctags binaries as a separate executable
2
- work. All bundled binaries are official upstream artifacts built from commit
3
- ab95af198f8eaeb6d50dc96e3adf52e769d3e5f0.
4
-
5
- Universal Ctags is licensed under GPL-2.0-or-later. Its complete corresponding
6
- source is included at:
7
-
8
- source/universal-ctags-ab95af198f8eaeb6d50dc96e3adf52e769d3e5f0.tar.gz
9
-
10
- The official source URL, per-platform release URLs, archive SHA-256 values and
11
- executable SHA-256 values are recorded in manifest.json.
12
-
13
- Linux x64/ARM64 and macOS x64/ARM64 come from the official
14
- universal-ctags/ctags-nightly-build 2026.09.16 release. Their upstream package
15
- metadata and dependency notices are preserved under
16
- licenses/official-snapshot/<target>/.
17
-
18
- Windows x64 comes from the official universal-ctags/ctags-win32
19
- 2026-09-16/p6.2.20260913.0-2-gab95af1 release. Its distributed license texts
20
- are preserved under licenses/win32-x64/.
21
-
22
- No bundled Ctags executable is built by this project.
Binary file
Binary file