@indianic/dialout 1.10.0 → 1.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (117) hide show
  1. package/README.md +14 -0
  2. package/dist/ai-adapters/claude.d.ts.map +1 -1
  3. package/dist/ai-adapters/claude.js +18 -1
  4. package/dist/ai-adapters/claude.js.map +1 -1
  5. package/dist/ai-sessions.d.ts +26 -1
  6. package/dist/ai-sessions.d.ts.map +1 -1
  7. package/dist/ai-sessions.js +43 -7
  8. package/dist/ai-sessions.js.map +1 -1
  9. package/dist/cli-client.d.ts +60 -0
  10. package/dist/cli-client.d.ts.map +1 -0
  11. package/dist/cli-client.js +246 -0
  12. package/dist/cli-client.js.map +1 -0
  13. package/dist/cli-terminal.d.ts +101 -0
  14. package/dist/cli-terminal.d.ts.map +1 -0
  15. package/dist/cli-terminal.js +1121 -0
  16. package/dist/cli-terminal.js.map +1 -0
  17. package/dist/cli.js +84 -0
  18. package/dist/cli.js.map +1 -1
  19. package/dist/file-transfer.d.ts +18 -0
  20. package/dist/file-transfer.d.ts.map +1 -0
  21. package/dist/file-transfer.js +266 -0
  22. package/dist/file-transfer.js.map +1 -0
  23. package/dist/fs-browser.d.ts +3 -1
  24. package/dist/fs-browser.d.ts.map +1 -1
  25. package/dist/fs-browser.js +35 -6
  26. package/dist/fs-browser.js.map +1 -1
  27. package/dist/mcp-stdio.d.ts +10 -0
  28. package/dist/mcp-stdio.d.ts.map +1 -0
  29. package/dist/mcp-stdio.js +199 -0
  30. package/dist/mcp-stdio.js.map +1 -0
  31. package/dist/shared-shell.d.ts +77 -0
  32. package/dist/shared-shell.d.ts.map +1 -0
  33. package/dist/shared-shell.js +282 -0
  34. package/dist/shared-shell.js.map +1 -0
  35. package/dist/websocket.d.ts.map +1 -1
  36. package/dist/websocket.js +413 -1
  37. package/dist/websocket.js.map +1 -1
  38. package/node_modules/@indianic/dialout-shared/dist/ai-chat-prefs.test.d.ts +2 -0
  39. package/node_modules/@indianic/dialout-shared/dist/ai-chat-prefs.test.d.ts.map +1 -0
  40. package/node_modules/@indianic/dialout-shared/dist/ai-chat-prefs.test.js +38 -0
  41. package/node_modules/@indianic/dialout-shared/dist/attachments.test.d.ts +2 -0
  42. package/node_modules/@indianic/dialout-shared/dist/attachments.test.d.ts.map +1 -0
  43. package/node_modules/@indianic/dialout-shared/dist/attachments.test.js +31 -0
  44. package/node_modules/@indianic/dialout-shared/dist/captured.d.ts +27 -0
  45. package/node_modules/@indianic/dialout-shared/dist/captured.d.ts.map +1 -0
  46. package/node_modules/@indianic/dialout-shared/dist/captured.js +23 -0
  47. package/node_modules/@indianic/dialout-shared/dist/captured.test.d.ts +2 -0
  48. package/node_modules/@indianic/dialout-shared/dist/captured.test.d.ts.map +1 -0
  49. package/node_modules/@indianic/dialout-shared/dist/captured.test.js +27 -0
  50. package/node_modules/@indianic/dialout-shared/dist/chat-blocks.d.ts +6 -0
  51. package/node_modules/@indianic/dialout-shared/dist/chat-blocks.d.ts.map +1 -1
  52. package/node_modules/@indianic/dialout-shared/dist/chat-blocks.js +15 -4
  53. package/node_modules/@indianic/dialout-shared/dist/chat-blocks.test.d.ts +2 -0
  54. package/node_modules/@indianic/dialout-shared/dist/chat-blocks.test.d.ts.map +1 -0
  55. package/node_modules/@indianic/dialout-shared/dist/chat-blocks.test.js +81 -0
  56. package/node_modules/@indianic/dialout-shared/dist/command-filter.test.d.ts +2 -0
  57. package/node_modules/@indianic/dialout-shared/dist/command-filter.test.d.ts.map +1 -0
  58. package/node_modules/@indianic/dialout-shared/dist/command-filter.test.js +63 -0
  59. package/node_modules/@indianic/dialout-shared/dist/composer-behaviour.test.d.ts +2 -0
  60. package/node_modules/@indianic/dialout-shared/dist/composer-behaviour.test.d.ts.map +1 -0
  61. package/node_modules/@indianic/dialout-shared/dist/composer-behaviour.test.js +27 -0
  62. package/node_modules/@indianic/dialout-shared/dist/event-merge.d.ts +7 -0
  63. package/node_modules/@indianic/dialout-shared/dist/event-merge.d.ts.map +1 -1
  64. package/node_modules/@indianic/dialout-shared/dist/event-merge.test.d.ts +2 -0
  65. package/node_modules/@indianic/dialout-shared/dist/event-merge.test.d.ts.map +1 -0
  66. package/node_modules/@indianic/dialout-shared/dist/event-merge.test.js +66 -0
  67. package/node_modules/@indianic/dialout-shared/dist/events.d.ts +1 -0
  68. package/node_modules/@indianic/dialout-shared/dist/events.d.ts.map +1 -1
  69. package/node_modules/@indianic/dialout-shared/dist/index.d.ts +6 -1
  70. package/node_modules/@indianic/dialout-shared/dist/index.d.ts.map +1 -1
  71. package/node_modules/@indianic/dialout-shared/dist/index.js +15 -1
  72. package/node_modules/@indianic/dialout-shared/dist/notices.d.ts +37 -0
  73. package/node_modules/@indianic/dialout-shared/dist/notices.d.ts.map +1 -0
  74. package/node_modules/@indianic/dialout-shared/dist/notices.js +124 -0
  75. package/node_modules/@indianic/dialout-shared/dist/notices.test.d.ts +2 -0
  76. package/node_modules/@indianic/dialout-shared/dist/notices.test.d.ts.map +1 -0
  77. package/node_modules/@indianic/dialout-shared/dist/notices.test.js +92 -0
  78. package/node_modules/@indianic/dialout-shared/dist/notify.test.d.ts +2 -0
  79. package/node_modules/@indianic/dialout-shared/dist/notify.test.d.ts.map +1 -0
  80. package/node_modules/@indianic/dialout-shared/dist/notify.test.js +51 -0
  81. package/node_modules/@indianic/dialout-shared/dist/pane-prompt.d.ts +17 -0
  82. package/node_modules/@indianic/dialout-shared/dist/pane-prompt.d.ts.map +1 -1
  83. package/node_modules/@indianic/dialout-shared/dist/pane-prompt.js +27 -0
  84. package/node_modules/@indianic/dialout-shared/dist/pane-prompt.test.d.ts +2 -0
  85. package/node_modules/@indianic/dialout-shared/dist/pane-prompt.test.d.ts.map +1 -0
  86. package/node_modules/@indianic/dialout-shared/dist/pane-prompt.test.js +184 -0
  87. package/node_modules/@indianic/dialout-shared/dist/scroll-pin.test.d.ts +2 -0
  88. package/node_modules/@indianic/dialout-shared/dist/scroll-pin.test.d.ts.map +1 -0
  89. package/node_modules/@indianic/dialout-shared/dist/scroll-pin.test.js +21 -0
  90. package/node_modules/@indianic/dialout-shared/dist/thinking.d.ts +9 -0
  91. package/node_modules/@indianic/dialout-shared/dist/thinking.d.ts.map +1 -0
  92. package/node_modules/@indianic/dialout-shared/dist/thinking.js +38 -0
  93. package/node_modules/@indianic/dialout-shared/dist/thinking.test.d.ts +2 -0
  94. package/node_modules/@indianic/dialout-shared/dist/thinking.test.d.ts.map +1 -0
  95. package/node_modules/@indianic/dialout-shared/dist/thinking.test.js +30 -0
  96. package/node_modules/@indianic/dialout-shared/dist/tmux-prefs.test.d.ts +2 -0
  97. package/node_modules/@indianic/dialout-shared/dist/tmux-prefs.test.d.ts.map +1 -0
  98. package/node_modules/@indianic/dialout-shared/dist/tmux-prefs.test.js +95 -0
  99. package/node_modules/@indianic/dialout-shared/dist/tool-appearance.test.d.ts +2 -0
  100. package/node_modules/@indianic/dialout-shared/dist/tool-appearance.test.d.ts.map +1 -0
  101. package/node_modules/@indianic/dialout-shared/dist/tool-appearance.test.js +38 -0
  102. package/node_modules/@indianic/dialout-shared/package.json +2 -2
  103. package/node_modules/@indianic/dialout-shared/src/captured.test.ts +29 -0
  104. package/node_modules/@indianic/dialout-shared/src/captured.ts +46 -0
  105. package/node_modules/@indianic/dialout-shared/src/chat-blocks.test.ts +14 -0
  106. package/node_modules/@indianic/dialout-shared/src/chat-blocks.ts +14 -5
  107. package/node_modules/@indianic/dialout-shared/src/event-merge.test.ts +27 -0
  108. package/node_modules/@indianic/dialout-shared/src/event-merge.ts +11 -0
  109. package/node_modules/@indianic/dialout-shared/src/events.ts +5 -1
  110. package/node_modules/@indianic/dialout-shared/src/index.ts +8 -1
  111. package/node_modules/@indianic/dialout-shared/src/notices.test.ts +102 -0
  112. package/node_modules/@indianic/dialout-shared/src/notices.ts +159 -0
  113. package/node_modules/@indianic/dialout-shared/src/pane-prompt.test.ts +23 -1
  114. package/node_modules/@indianic/dialout-shared/src/pane-prompt.ts +27 -0
  115. package/node_modules/@indianic/dialout-shared/src/thinking.test.ts +32 -0
  116. package/node_modules/@indianic/dialout-shared/src/thinking.ts +32 -0
  117. package/package.json +1 -1
@@ -0,0 +1,266 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.MAX_FILE_BYTES = void 0;
37
+ exports.validateTargetPath = validateTargetPath;
38
+ exports.statPath = statPath;
39
+ exports.readFileForTransfer = readFileForTransfer;
40
+ exports.writeFileFromTransfer = writeFileFromTransfer;
41
+ const crypto_1 = require("crypto");
42
+ const fs = __importStar(require("fs"));
43
+ const os = __importStar(require("os"));
44
+ const path = __importStar(require("path"));
45
+ // Phase 1 cap. Equal to the limit is allowed; only a larger body is refused.
46
+ exports.MAX_FILE_BYTES = 10 * 1024 * 1024;
47
+ const NOT_A_FILE = 'not a file';
48
+ const TOO_BIG = 'file exceeds 10 MB';
49
+ const EXISTS = 'exists (use overwrite)';
50
+ const DENIED = 'permission denied';
51
+ const CHECKSUM = 'checksum mismatch';
52
+ function fsCode(err) {
53
+ if (typeof err === 'object' && err !== null && 'code' in err) {
54
+ const code = err.code;
55
+ if (typeof code === 'string')
56
+ return code;
57
+ }
58
+ return '';
59
+ }
60
+ function coded(message, code) {
61
+ return Object.assign(new Error(message), { code });
62
+ }
63
+ // EACCES/EPERM become the short string the UI shows. Every other code,
64
+ // including ENOENT, is rethrown unchanged so callers can still branch on it.
65
+ function rethrowAccess(err) {
66
+ const code = fsCode(err);
67
+ if (code === 'EACCES' || code === 'EPERM')
68
+ throw coded(DENIED, code);
69
+ throw err;
70
+ }
71
+ function expandLeadingHome(p, homedir) {
72
+ if (p === '~')
73
+ return homedir;
74
+ if (p.startsWith('~/')) {
75
+ // Concatenate. path.join would collapse `..`, so `~/../.ssh` would
76
+ // never reach the segment check below.
77
+ const base = homedir.endsWith('/') ? homedir.slice(0, -1) : homedir;
78
+ return `${base}/${p.slice(2)}`;
79
+ }
80
+ // `~other` is a different user's home. Leaving it unexpanded would make
81
+ // it a relative path, and path.resolve would then anchor it at cwd.
82
+ if (p.startsWith('~'))
83
+ throw new Error('cannot expand ~user');
84
+ return p;
85
+ }
86
+ function validateTargetPath(p, homedir = os.homedir()) {
87
+ const expanded = expandLeadingHome(p, homedir);
88
+ if (!path.isAbsolute(expanded))
89
+ throw new Error('path must be absolute');
90
+ // A `..` segment is rejected before path.resolve, which would fold
91
+ // `/tmp/../etc/passwd` into `/etc/passwd` and hide the traversal.
92
+ if (expanded.split('/').includes('..'))
93
+ throw new Error('path must not contain ..');
94
+ if (expanded.includes('\0') || p.includes('\0'))
95
+ throw new Error('path contains NUL');
96
+ return path.resolve(expanded);
97
+ }
98
+ function toFileStat(resolved, st) {
99
+ if (!st.isDirectory() && !st.isFile())
100
+ throw new Error(NOT_A_FILE);
101
+ return {
102
+ name: path.basename(resolved),
103
+ type: st.isDirectory() ? 'directory' : 'file',
104
+ size: st.size,
105
+ mtimeMs: st.mtimeMs,
106
+ };
107
+ }
108
+ async function statPath(p) {
109
+ const resolved = validateTargetPath(p);
110
+ try {
111
+ // stat, not lstat: a symlink to a directory has to report as a directory.
112
+ // lstat describes the link, which is how a linked folder disappeared
113
+ // from the picker (see fs-browser.ts).
114
+ return toFileStat(resolved, await fs.promises.stat(resolved));
115
+ }
116
+ catch (err) {
117
+ rethrowAccess(err);
118
+ }
119
+ }
120
+ async function readExact(fh, size) {
121
+ const data = Buffer.alloc(size);
122
+ let offset = 0;
123
+ while (offset < data.length) {
124
+ const { bytesRead } = await fh.read(data, offset, data.length - offset, offset);
125
+ if (bytesRead === 0)
126
+ break;
127
+ offset += bytesRead;
128
+ }
129
+ return offset === data.length ? data : data.subarray(0, offset);
130
+ }
131
+ async function readFileForTransfer(p) {
132
+ const resolved = validateTargetPath(p);
133
+ let looked;
134
+ try {
135
+ looked = await fs.promises.lstat(resolved);
136
+ // Follow a symlink with stat(), not open(). open() on a fifo blocks,
137
+ // and lstat would only describe the link, so a link to a fifo or a
138
+ // directory would otherwise get through.
139
+ if (looked.isSymbolicLink())
140
+ looked = await fs.promises.stat(resolved);
141
+ }
142
+ catch (err) {
143
+ rethrowAccess(err);
144
+ }
145
+ if (!looked.isFile())
146
+ throw new Error(NOT_A_FILE);
147
+ if (looked.size > exports.MAX_FILE_BYTES)
148
+ throw new Error(TOO_BIG);
149
+ let opened;
150
+ try {
151
+ opened = await fs.promises.open(resolved, 'r');
152
+ }
153
+ catch (err) {
154
+ if (fsCode(err) === 'EISDIR')
155
+ throw new Error(NOT_A_FILE);
156
+ rethrowAccess(err);
157
+ }
158
+ try {
159
+ // fstat the descriptor just opened and never allocate past the cap, so
160
+ // a path swapped for a larger file between a separate stat and readFile
161
+ // cannot be pulled into memory.
162
+ const st = await opened.stat();
163
+ if (!st.isFile())
164
+ throw new Error(NOT_A_FILE);
165
+ if (st.size > exports.MAX_FILE_BYTES)
166
+ throw new Error(TOO_BIG);
167
+ const data = await readExact(opened, st.size);
168
+ return { data, sha256: (0, crypto_1.createHash)('sha256').update(data).digest('hex') };
169
+ }
170
+ finally {
171
+ await opened.close();
172
+ }
173
+ }
174
+ function assertChecksum(data, expected) {
175
+ if (expected === undefined)
176
+ return;
177
+ const actual = (0, crypto_1.createHash)('sha256').update(data).digest('hex');
178
+ if (actual !== expected.toLowerCase())
179
+ throw new Error(CHECKSUM);
180
+ }
181
+ function tempPath(dir) {
182
+ // Dot-prefixed and unique: listDirectory hides dotfiles, and two writes
183
+ // into the same folder must not share a temp name.
184
+ const suffix = `${process.pid}-${Date.now()}-${(0, crypto_1.randomBytes)(6).toString('hex')}`;
185
+ return path.join(dir, `.dialout-transfer-${suffix}.tmp`);
186
+ }
187
+ async function existingTarget(resolved) {
188
+ let link;
189
+ try {
190
+ // lstat, not stat. A dangling symlink is a real directory entry: stat
191
+ // follows it, gets ENOENT, and would treat the name as free so rename
192
+ // replaces the link even when overwrite is false.
193
+ link = await fs.promises.lstat(resolved);
194
+ }
195
+ catch (err) {
196
+ if (fsCode(err) === 'ENOENT')
197
+ return 'missing';
198
+ rethrowAccess(err);
199
+ }
200
+ if (link.isSymbolicLink()) {
201
+ try {
202
+ const st = await fs.promises.stat(resolved);
203
+ // A link to a directory is not a file we may replace. A link to a
204
+ // regular file is an occupied name: overwrite decides whether rename
205
+ // may swap the link itself out.
206
+ if (st.isDirectory())
207
+ return 'directory';
208
+ if (st.isFile())
209
+ return 'file';
210
+ return 'other';
211
+ }
212
+ catch (err) {
213
+ // ENOENT here means the target is gone, not that the path is free.
214
+ // Classified with files so the overwrite guard still applies.
215
+ if (fsCode(err) === 'ENOENT')
216
+ return 'file';
217
+ rethrowAccess(err);
218
+ }
219
+ }
220
+ if (link.isDirectory())
221
+ return 'directory';
222
+ if (link.isFile())
223
+ return 'file';
224
+ return 'other';
225
+ }
226
+ async function writeFileFromTransfer(p, data, opts) {
227
+ const resolved = validateTargetPath(p);
228
+ if (!Buffer.isBuffer(data))
229
+ throw new TypeError('data must be a Buffer');
230
+ if (data.length > exports.MAX_FILE_BYTES)
231
+ throw new Error(TOO_BIG);
232
+ // A bad checksum is refused before any temp file is created, so a
233
+ // mismatch leaves the directory untouched.
234
+ assertChecksum(data, opts.sha256);
235
+ const kind = await existingTarget(resolved);
236
+ if (kind === 'directory' || kind === 'other')
237
+ throw new Error(NOT_A_FILE);
238
+ if (kind === 'file' && opts.overwrite !== true)
239
+ throw new Error(EXISTS);
240
+ const tmp = tempPath(path.dirname(resolved));
241
+ try {
242
+ // Same directory so rename(2) is an atomic directory-entry swap and
243
+ // not a cross-device copy. 'wx' so a colliding temp name fails closed.
244
+ // The lstat above is what refuses overwrite — rename itself would
245
+ // replace a name that appeared after that check, including a dangling
246
+ // symlink.
247
+ await fs.promises.writeFile(tmp, data, { flag: 'wx' });
248
+ const fh = await fs.promises.open(tmp, 'r+');
249
+ try {
250
+ await fh.sync();
251
+ }
252
+ finally {
253
+ await fh.close();
254
+ }
255
+ await fs.promises.rename(tmp, resolved);
256
+ }
257
+ catch (err) {
258
+ await fs.promises.unlink(tmp).catch(() => { });
259
+ const code = fsCode(err);
260
+ if (code === 'EACCES' || code === 'EPERM')
261
+ throw coded(DENIED, code);
262
+ throw err;
263
+ }
264
+ return statPath(resolved);
265
+ }
266
+ //# sourceMappingURL=file-transfer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-transfer.js","sourceRoot":"","sources":["../src/file-transfer.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuDA,gDAQC;AAYD,4BAUC;AAaD,kDAkCC;AA+CD,sDAsCC;AAzND,mCAAiD;AACjD,uCAAyB;AACzB,uCAAyB;AACzB,2CAA6B;AAS7B,6EAA6E;AAChE,QAAA,cAAc,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAE/C,MAAM,UAAU,GAAG,YAAY,CAAC;AAChC,MAAM,OAAO,GAAG,oBAAoB,CAAC;AACrC,MAAM,MAAM,GAAG,wBAAwB,CAAC;AACxC,MAAM,MAAM,GAAG,mBAAmB,CAAC;AACnC,MAAM,QAAQ,GAAG,mBAAmB,CAAC;AAErC,SAAS,MAAM,CAAC,GAAY;IAC1B,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;QAC7D,MAAM,IAAI,GAAI,GAA0B,CAAC,IAAI,CAAC;QAC9C,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;IAC5C,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,KAAK,CAAC,OAAe,EAAE,IAAY;IAC1C,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AACrD,CAAC;AAED,uEAAuE;AACvE,6EAA6E;AAC7E,SAAS,aAAa,CAAC,GAAY;IACjC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACzB,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO;QAAE,MAAM,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IACrE,MAAM,GAAG,CAAC;AACZ,CAAC;AAED,SAAS,iBAAiB,CAAC,CAAS,EAAE,OAAe;IACnD,IAAI,CAAC,KAAK,GAAG;QAAE,OAAO,OAAO,CAAC;IAC9B,IAAI,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACvB,mEAAmE;QACnE,uCAAuC;QACvC,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;QACpE,OAAO,GAAG,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IACjC,CAAC;IACD,wEAAwE;IACxE,oEAAoE;IACpE,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC9D,OAAO,CAAC,CAAC;AACX,CAAC;AAED,SAAgB,kBAAkB,CAAC,CAAS,EAAE,UAAkB,EAAE,CAAC,OAAO,EAAE;IAC1E,MAAM,QAAQ,GAAG,iBAAiB,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC/C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACzE,mEAAmE;IACnE,kEAAkE;IAClE,IAAI,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IACpF,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACtF,OAAO,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;AAChC,CAAC;AAED,SAAS,UAAU,CAAC,QAAgB,EAAE,EAAY;IAChD,IAAI,CAAC,EAAE,CAAC,WAAW,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;IACnE,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;QAC7B,IAAI,EAAE,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,MAAM;QAC7C,IAAI,EAAE,EAAE,CAAC,IAAI;QACb,OAAO,EAAE,EAAE,CAAC,OAAO;KACpB,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,QAAQ,CAAC,CAAS;IACtC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC;QACH,0EAA0E;QAC1E,qEAAqE;QACrE,uCAAuC;QACvC,OAAO,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC;IAChE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,aAAa,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,EAA0B,EAAE,IAAY;IAC/D,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAChC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,OAAO,MAAM,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC;QAC5B,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC;QAChF,IAAI,SAAS,KAAK,CAAC;YAAE,MAAM;QAC3B,MAAM,IAAI,SAAS,CAAC;IACtB,CAAC;IACD,OAAO,MAAM,KAAK,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;AAClE,CAAC;AAEM,KAAK,UAAU,mBAAmB,CAAC,CAAS;IACjD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACvC,IAAI,MAAgB,CAAC;IACrB,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC3C,qEAAqE;QACrE,mEAAmE;QACnE,yCAAyC;QACzC,IAAI,MAAM,CAAC,cAAc,EAAE;YAAE,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACzE,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,aAAa,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,MAAM,CAAC,IAAI,GAAG,sBAAc;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAE3D,IAAI,MAA8B,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;QAC1D,aAAa,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,CAAC;QACH,uEAAuE;QACvE,wEAAwE;QACxE,gCAAgC;QAChC,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;QAC9C,IAAI,EAAE,CAAC,IAAI,GAAG,sBAAc;YAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;QACvD,MAAM,IAAI,GAAG,MAAM,SAAS,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;IAC3E,CAAC;YAAS,CAAC;QACT,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,IAAY,EAAE,QAA4B;IAChE,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO;IACnC,MAAM,MAAM,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/D,IAAI,MAAM,KAAK,QAAQ,CAAC,WAAW,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,CAAC,CAAC;AACnE,CAAC;AAED,SAAS,QAAQ,CAAC,GAAW;IAC3B,wEAAwE;IACxE,mDAAmD;IACnD,MAAM,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAA,oBAAW,EAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;IAChF,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,qBAAqB,MAAM,MAAM,CAAC,CAAC;AAC3D,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,QAAgB;IAC5C,IAAI,IAAc,CAAC;IACnB,IAAI,CAAC;QACH,sEAAsE;QACtE,sEAAsE;QACtE,kDAAkD;QAClD,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ;YAAE,OAAO,SAAS,CAAC;QAC/C,aAAa,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC5C,kEAAkE;YAClE,qEAAqE;YACrE,gCAAgC;YAChC,IAAI,EAAE,CAAC,WAAW,EAAE;gBAAE,OAAO,WAAW,CAAC;YACzC,IAAI,EAAE,CAAC,MAAM,EAAE;gBAAE,OAAO,MAAM,CAAC;YAC/B,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,mEAAmE;YACnE,8DAA8D;YAC9D,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ;gBAAE,OAAO,MAAM,CAAC;YAC5C,aAAa,CAAC,GAAG,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IACD,IAAI,IAAI,CAAC,WAAW,EAAE;QAAE,OAAO,WAAW,CAAC;IAC3C,IAAI,IAAI,CAAC,MAAM,EAAE;QAAE,OAAO,MAAM,CAAC;IACjC,OAAO,OAAO,CAAC;AACjB,CAAC;AAEM,KAAK,UAAU,qBAAqB,CACzC,CAAS,EACT,IAAY,EACZ,IAA6C;IAE7C,MAAM,QAAQ,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,MAAM,IAAI,SAAS,CAAC,uBAAuB,CAAC,CAAC;IACzE,IAAI,IAAI,CAAC,MAAM,GAAG,sBAAc;QAAE,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;IAC3D,kEAAkE;IAClE,2CAA2C;IAC3C,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAElC,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC5C,IAAI,IAAI,KAAK,WAAW,IAAI,IAAI,KAAK,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,UAAU,CAAC,CAAC;IAC1E,IAAI,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI;QAAE,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC;IAExE,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7C,IAAI,CAAC;QACH,oEAAoE;QACpE,uEAAuE;QACvE,kEAAkE;QAClE,sEAAsE;QACtE,WAAW;QACX,MAAM,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACvD,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC7C,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;QAClB,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;QACnB,CAAC;QACD,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC9C,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QACzB,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,OAAO;YAAE,MAAM,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACrE,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,OAAO,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC5B,CAAC"}
@@ -1,6 +1,8 @@
1
1
  export interface DirEntry {
2
2
  name: string;
3
3
  type: 'directory' | 'file';
4
+ size?: number;
5
+ mtimeMs?: number;
4
6
  }
5
- export declare function listDirectory(dirPath: string): DirEntry[];
7
+ export declare function listDirectory(dirPath: string, homedir?: string): DirEntry[];
6
8
  //# sourceMappingURL=fs-browser.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fs-browser.d.ts","sourceRoot":"","sources":["../src/fs-browser.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;CAC5B;AA0BD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,EAAE,CAwBzD"}
1
+ {"version":3,"file":"fs-browser.d.ts","sourceRoot":"","sources":["../src/fs-browser.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;IAG3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAwCD,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,MAAqB,GAAG,QAAQ,EAAE,CAqCzF"}
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.listDirectory = listDirectory;
37
37
  const fs = __importStar(require("fs"));
38
+ const os = __importStar(require("os"));
38
39
  const path = __importStar(require("path"));
39
40
  /**
40
41
  * Is this entry a directory, following symlinks?
@@ -62,8 +63,22 @@ function isDirectory(entry, parent) {
62
63
  return false;
63
64
  }
64
65
  }
65
- function listDirectory(dirPath) {
66
- const resolvedPath = path.resolve(dirPath);
66
+ // `path.resolve('~')` is `<cwd>/~`. Node does not treat `~` as home, so a
67
+ // browse of the file manager's entry path listed an empty folder while
68
+ // upload wrote the real one. Concatenate onto homedir, then resolve.
69
+ // path.join would fold `..` before that resolve. `~other` is left alone:
70
+ // expanding it would throw, and a miss has to stay [].
71
+ function expandBrowseHome(dirPath, homedir) {
72
+ if (dirPath === '~')
73
+ return homedir;
74
+ if (dirPath.startsWith('~/')) {
75
+ const base = homedir.endsWith('/') ? homedir.slice(0, -1) : homedir;
76
+ return `${base}/${dirPath.slice(2)}`;
77
+ }
78
+ return dirPath;
79
+ }
80
+ function listDirectory(dirPath, homedir = os.homedir()) {
81
+ const resolvedPath = path.resolve(expandBrowseHome(dirPath, homedir));
67
82
  if (!fs.existsSync(resolvedPath)) {
68
83
  return [];
69
84
  }
@@ -74,10 +89,24 @@ function listDirectory(dirPath) {
74
89
  const entries = fs.readdirSync(resolvedPath, { withFileTypes: true });
75
90
  return entries
76
91
  .filter((entry) => !entry.name.startsWith('.'))
77
- .map((entry) => ({
78
- name: entry.name,
79
- type: isDirectory(entry, resolvedPath) ? 'directory' : 'file',
80
- }))
92
+ .map((entry) => {
93
+ const listed = {
94
+ name: entry.name,
95
+ type: isDirectory(entry, resolvedPath) ? 'directory' : 'file',
96
+ };
97
+ // stat follows the link, so a symlink reports the target's size and
98
+ // mtime. One broken or unreadable entry must not take the listing
99
+ // down with it — the same reason isDirectory catches.
100
+ try {
101
+ const st = fs.statSync(path.join(resolvedPath, entry.name));
102
+ listed.size = st.size;
103
+ listed.mtimeMs = st.mtimeMs;
104
+ }
105
+ catch {
106
+ // leave size and mtimeMs unset
107
+ }
108
+ return listed;
109
+ })
81
110
  .sort((a, b) => {
82
111
  if (a.type === b.type)
83
112
  return a.name.localeCompare(b.name);
@@ -1 +1 @@
1
- {"version":3,"file":"fs-browser.js","sourceRoot":"","sources":["../src/fs-browser.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,sCAwBC;AAxDD,uCAAyB;AACzB,2CAA6B;AAO7B;;;;;;;;;;;;;GAaG;AACH,SAAS,WAAW,CAAC,KAAgB,EAAE,MAAc;IACnD,IAAI,KAAK,CAAC,WAAW,EAAE;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE;QAAE,OAAO,KAAK,CAAC;IAC1C,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAClE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAgB,aAAa,CAAC,OAAe;IAC3C,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAE3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,YAAY,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAEtE,OAAO,OAAO;SACX,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;SAC9C,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACf,IAAI,EAAE,KAAK,CAAC,IAAI;QAChB,IAAI,EAAE,WAAW,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,CAAC,WAAoB,CAAC,CAAC,CAAC,MAAe;KAChF,CAAC,CAAC;SACF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACb,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI;YAAE,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC3D,OAAO,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"fs-browser.js","sourceRoot":"","sources":["../src/fs-browser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ export interface McpDeps {
2
+ listMachines(): Promise<unknown>;
3
+ exec(args: Record<string, unknown>): Promise<unknown>;
4
+ readScreen(args: Record<string, unknown>): Promise<unknown>;
5
+ writeKeys(args: Record<string, unknown>): Promise<unknown>;
6
+ copyFile(args: Record<string, unknown>): Promise<unknown>;
7
+ }
8
+ export declare function handleMcpMessage(line: string, deps: McpDeps): Promise<string | null>;
9
+ export declare function runMcpStdio(deps: McpDeps, input?: NodeJS.ReadableStream, output?: NodeJS.WritableStream): Promise<void>;
10
+ //# sourceMappingURL=mcp-stdio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-stdio.d.ts","sourceRoot":"","sources":["../src/mcp-stdio.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,OAAO;IACtB,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACtD,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAC3D;AA4HD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAwC1F;AAED,wBAAsB,WAAW,CAC/B,IAAI,EAAE,OAAO,EACb,KAAK,GAAE,MAAM,CAAC,cAA8B,EAC5C,MAAM,GAAE,MAAM,CAAC,cAA+B,GAC7C,OAAO,CAAC,IAAI,CAAC,CAMf"}
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ // Newline-delimited JSON-RPC 2.0 for the shared shell. Tool failures stay
3
+ // inside the result (`isError`) so a client can keep the session; only a
4
+ // broken request is a JSON-RPC error. No other protocol is written to stdout.
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleMcpMessage = handleMcpMessage;
7
+ exports.runMcpStdio = runMcpStdio;
8
+ const fs_1 = require("fs");
9
+ const path_1 = require("path");
10
+ const readline_1 = require("readline");
11
+ const PROTOCOL_VERSION = '2024-11-05';
12
+ const LOGIN_EXPIRED = 'dialout: login expired, run dialout login';
13
+ const NOT_DEPLOYED = 'file transfer is not on this server yet';
14
+ const serverVersion = readServerVersion();
15
+ function readServerVersion() {
16
+ try {
17
+ const pkg = JSON.parse((0, fs_1.readFileSync)((0, path_1.resolve)(__dirname, '../package.json'), 'utf8'));
18
+ return typeof pkg.version === 'string' ? pkg.version : '0.0.0';
19
+ }
20
+ catch {
21
+ return '0.0.0';
22
+ }
23
+ }
24
+ const TOOLS = [
25
+ {
26
+ name: 'list_machines',
27
+ description: 'List machines for this login: name, id, and whether each is online.',
28
+ inputSchema: {
29
+ type: 'object',
30
+ properties: {},
31
+ },
32
+ },
33
+ {
34
+ name: 'exec',
35
+ description: 'Run a command in the shared shell on a machine. An attached terminal sees it.',
36
+ inputSchema: {
37
+ type: 'object',
38
+ properties: {
39
+ machine: { type: 'string' },
40
+ command: { type: 'string' },
41
+ cwd: { type: 'string', description: 'Absolute path. A relative cwd is refused.' },
42
+ timeoutMs: { type: 'number' },
43
+ },
44
+ required: ['machine', 'command'],
45
+ },
46
+ },
47
+ {
48
+ name: 'read_screen',
49
+ description: 'Read the last lines of the shared shell on a machine.',
50
+ inputSchema: {
51
+ type: 'object',
52
+ properties: {
53
+ machine: { type: 'string' },
54
+ lines: { type: 'number' },
55
+ },
56
+ required: ['machine'],
57
+ },
58
+ },
59
+ {
60
+ name: 'write_keys',
61
+ description: 'Type literal text and named keys into the shared shell.',
62
+ inputSchema: {
63
+ type: 'object',
64
+ properties: {
65
+ machine: { type: 'string' },
66
+ text: { type: 'string' },
67
+ keys: { type: 'array', items: { type: 'string' } },
68
+ },
69
+ required: ['machine'],
70
+ },
71
+ },
72
+ {
73
+ name: 'copy_file',
74
+ description: 'Copy one file to or from a machine, using the same source and dest syntax as dialout cp.',
75
+ inputSchema: {
76
+ type: 'object',
77
+ properties: {
78
+ source: { type: 'string' },
79
+ dest: { type: 'string' },
80
+ },
81
+ required: ['source', 'dest'],
82
+ },
83
+ },
84
+ ];
85
+ function rpcResult(id, result) {
86
+ return JSON.stringify({ jsonrpc: '2.0', id, result });
87
+ }
88
+ function rpcError(id, code, message) {
89
+ return JSON.stringify({ jsonrpc: '2.0', id, error: { code, message } });
90
+ }
91
+ function asText(value) {
92
+ if (typeof value === 'string')
93
+ return value;
94
+ try {
95
+ const text = JSON.stringify(value);
96
+ return typeof text === 'string' ? text : '';
97
+ }
98
+ catch (err) {
99
+ return err instanceof Error ? err.message : 'unserializable result';
100
+ }
101
+ }
102
+ function thrownCode(err) {
103
+ if (typeof err !== 'object' || err === null || !('code' in err))
104
+ return undefined;
105
+ const code = err.code;
106
+ return typeof code === 'string' ? code : undefined;
107
+ }
108
+ function thrownText(err) {
109
+ const code = thrownCode(err);
110
+ if (code === 'NO_SESSION')
111
+ return LOGIN_EXPIRED;
112
+ if (code === 'NOT_DEPLOYED')
113
+ return NOT_DEPLOYED;
114
+ if (err instanceof Error)
115
+ return err.message;
116
+ if (typeof err === 'object' && err !== null && typeof err.message === 'string') {
117
+ return err.message;
118
+ }
119
+ return 'request failed';
120
+ }
121
+ function callArgs(params) {
122
+ if (typeof params !== 'object' || params === null || Array.isArray(params))
123
+ return {};
124
+ const args = params.arguments;
125
+ if (typeof args !== 'object' || args === null || Array.isArray(args))
126
+ return {};
127
+ return args;
128
+ }
129
+ async function callTool(name, args, deps) {
130
+ try {
131
+ if (name === 'list_machines')
132
+ return { text: asText(await deps.listMachines()), isError: false };
133
+ if (name === 'exec')
134
+ return { text: asText(await deps.exec(args)), isError: false };
135
+ if (name === 'read_screen')
136
+ return { text: asText(await deps.readScreen(args)), isError: false };
137
+ if (name === 'write_keys')
138
+ return { text: asText(await deps.writeKeys(args)), isError: false };
139
+ if (name === 'copy_file')
140
+ return { text: asText(await deps.copyFile(args)), isError: false };
141
+ const label = typeof name === 'string' && name.length > 0 ? name : 'unknown';
142
+ return { text: `unknown tool: ${label}`, isError: true };
143
+ }
144
+ catch (err) {
145
+ return { text: thrownText(err), isError: true };
146
+ }
147
+ }
148
+ function toolResult(text, isError) {
149
+ return { content: [{ type: 'text', text }], isError };
150
+ }
151
+ async function handleMcpMessage(line, deps) {
152
+ const trimmed = line.trim();
153
+ if (trimmed === '')
154
+ return null;
155
+ let parsed;
156
+ try {
157
+ parsed = JSON.parse(trimmed);
158
+ }
159
+ catch {
160
+ return rpcError(null, -32700, 'Parse error');
161
+ }
162
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
163
+ return rpcError(null, -32600, 'Invalid Request');
164
+ }
165
+ const msg = parsed;
166
+ const method = msg.method;
167
+ if (typeof method === 'string' && method.startsWith('notifications/'))
168
+ return null;
169
+ const idPresent = Object.prototype.hasOwnProperty.call(msg, 'id') && msg.id !== undefined;
170
+ if (!idPresent)
171
+ return null;
172
+ if (typeof method !== 'string')
173
+ return rpcError(msg.id, -32600, 'Invalid Request');
174
+ if (method === 'ping')
175
+ return rpcResult(msg.id, {});
176
+ if (method === 'initialize') {
177
+ return rpcResult(msg.id, {
178
+ protocolVersion: PROTOCOL_VERSION,
179
+ capabilities: { tools: {} },
180
+ serverInfo: { name: 'dialout', version: serverVersion },
181
+ });
182
+ }
183
+ if (method === 'tools/list')
184
+ return rpcResult(msg.id, { tools: TOOLS });
185
+ if (method === 'tools/call') {
186
+ const called = await callTool(typeof msg.params === 'object' && msg.params !== null ? msg.params.name : undefined, callArgs(msg.params), deps);
187
+ return rpcResult(msg.id, toolResult(called.text, called.isError));
188
+ }
189
+ return rpcError(msg.id, -32601, 'Method not found');
190
+ }
191
+ async function runMcpStdio(deps, input = process.stdin, output = process.stdout) {
192
+ const rl = (0, readline_1.createInterface)({ input, crlfDelay: Infinity });
193
+ for await (const line of rl) {
194
+ const out = await handleMcpMessage(line, deps);
195
+ if (out !== null)
196
+ output.write(`${out}\n`);
197
+ }
198
+ }
199
+ //# sourceMappingURL=mcp-stdio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-stdio.js","sourceRoot":"","sources":["../src/mcp-stdio.ts"],"names":[],"mappings":"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"}