nterminal 1.2.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 (197) hide show
  1. package/.env.example +12 -0
  2. package/LICENSE +674 -0
  3. package/README.md +181 -0
  4. package/assets/brand/app-icon-1024.png +0 -0
  5. package/assets/brand/app-icon-384.png +0 -0
  6. package/assets/brand/apple-touch-icon-360.png +0 -0
  7. package/assets/brand/favicon-32.png +0 -0
  8. package/assets/brand/favicon-64.png +0 -0
  9. package/assets/brand/favicon-96.png +0 -0
  10. package/assets/brand/favicon.svg +4 -0
  11. package/assets/brand/nterminal-mark-64.png +0 -0
  12. package/assets/brand/nterminal-mark.svg +4 -0
  13. package/assets/brand/nterminal-wordmark-486x68.png +0 -0
  14. package/assets/brand/nterminal-wordmark.svg +3 -0
  15. package/assets/screenshot/scr.png +0 -0
  16. package/bin/nterminal.js +114 -0
  17. package/dist/client/apple-touch-icon.png +0 -0
  18. package/dist/client/assets/MarkdownPreview-BeDi-V7k.js +29 -0
  19. package/dist/client/assets/MesloLGS-NF-Bold-Italic-DwFsXcwX.ttf +0 -0
  20. package/dist/client/assets/MesloLGS-NF-Bold-kN-HYz-g.ttf +0 -0
  21. package/dist/client/assets/MesloLGS-NF-Italic-CMg1T6-G.ttf +0 -0
  22. package/dist/client/assets/MesloLGS-NF-Regular-Cxr8pvCI.ttf +0 -0
  23. package/dist/client/assets/index-BQkKYjXb.js +33 -0
  24. package/dist/client/assets/index-WqeS39wU.css +1 -0
  25. package/dist/client/assets/notifications/character-2258.mp4 +0 -0
  26. package/dist/client/assets/notifications/character-2260.mp4 +0 -0
  27. package/dist/client/assets/notifications/character-2272.mp4 +0 -0
  28. package/dist/client/brand/nterminal-mark-64.png +0 -0
  29. package/dist/client/brand/nterminal-mark.svg +4 -0
  30. package/dist/client/brand/nterminal-wordmark-486x68.png +0 -0
  31. package/dist/client/brand/nterminal-wordmark.svg +3 -0
  32. package/dist/client/icons/app-icon-1024.png +0 -0
  33. package/dist/client/icons/app-icon-384.png +0 -0
  34. package/dist/client/icons/favicon-32.png +0 -0
  35. package/dist/client/icons/favicon-64.png +0 -0
  36. package/dist/client/icons/favicon-96.png +0 -0
  37. package/dist/client/icons/favicon.svg +4 -0
  38. package/dist/client/index.html +21 -0
  39. package/dist/client/manifest.webmanifest +24 -0
  40. package/dist/scripts/generate-secrets.js +3 -0
  41. package/dist/scripts/generate-secrets.js.map +1 -0
  42. package/dist/scripts/onboarding.js +814 -0
  43. package/dist/scripts/onboarding.js.map +1 -0
  44. package/dist/scripts/proxySetup.js +1007 -0
  45. package/dist/scripts/proxySetup.js.map +1 -0
  46. package/dist/server/agent/agentAuth.d.ts +6 -0
  47. package/dist/server/agent/agentAuth.js +35 -0
  48. package/dist/server/agent/agentAuth.js.map +1 -0
  49. package/dist/server/agent/agentProxy.d.ts +5 -0
  50. package/dist/server/agent/agentProxy.js +63 -0
  51. package/dist/server/agent/agentProxy.js.map +1 -0
  52. package/dist/server/agent/agentRoutes.d.ts +9 -0
  53. package/dist/server/agent/agentRoutes.js +327 -0
  54. package/dist/server/agent/agentRoutes.js.map +1 -0
  55. package/dist/server/agent/agentWebSocketProxy.d.ts +3 -0
  56. package/dist/server/agent/agentWebSocketProxy.js +65 -0
  57. package/dist/server/agent/agentWebSocketProxy.js.map +1 -0
  58. package/dist/server/auth/authService.d.ts +100 -0
  59. package/dist/server/auth/authService.js +415 -0
  60. package/dist/server/auth/authService.js.map +1 -0
  61. package/dist/server/auth/cookies.d.ts +11 -0
  62. package/dist/server/auth/cookies.js +39 -0
  63. package/dist/server/auth/cookies.js.map +1 -0
  64. package/dist/server/auth/ipMatch.d.ts +14 -0
  65. package/dist/server/auth/ipMatch.js +103 -0
  66. package/dist/server/auth/ipMatch.js.map +1 -0
  67. package/dist/server/auth/rateLimit.d.ts +17 -0
  68. package/dist/server/auth/rateLimit.js +25 -0
  69. package/dist/server/auth/rateLimit.js.map +1 -0
  70. package/dist/server/auth/totpService.d.ts +10 -0
  71. package/dist/server/auth/totpService.js +37 -0
  72. package/dist/server/auth/totpService.js.map +1 -0
  73. package/dist/server/config.d.ts +27 -0
  74. package/dist/server/config.js +138 -0
  75. package/dist/server/config.js.map +1 -0
  76. package/dist/server/files/fileExplorerService.d.ts +38 -0
  77. package/dist/server/files/fileExplorerService.js +551 -0
  78. package/dist/server/files/fileExplorerService.js.map +1 -0
  79. package/dist/server/files/rootToken.d.ts +51 -0
  80. package/dist/server/files/rootToken.js +139 -0
  81. package/dist/server/files/rootToken.js.map +1 -0
  82. package/dist/server/http.d.ts +13 -0
  83. package/dist/server/http.js +69 -0
  84. package/dist/server/http.js.map +1 -0
  85. package/dist/server/index.d.ts +1 -0
  86. package/dist/server/index.js +45 -0
  87. package/dist/server/index.js.map +1 -0
  88. package/dist/server/routes/agentManagementRoutes.d.ts +9 -0
  89. package/dist/server/routes/agentManagementRoutes.js +304 -0
  90. package/dist/server/routes/agentManagementRoutes.js.map +1 -0
  91. package/dist/server/routes/authRoutes.d.ts +10 -0
  92. package/dist/server/routes/authRoutes.js +95 -0
  93. package/dist/server/routes/authRoutes.js.map +1 -0
  94. package/dist/server/routes/fileRoutes.d.ts +11 -0
  95. package/dist/server/routes/fileRoutes.js +185 -0
  96. package/dist/server/routes/fileRoutes.js.map +1 -0
  97. package/dist/server/routes/notificationAssetRoutes.d.ts +9 -0
  98. package/dist/server/routes/notificationAssetRoutes.js +280 -0
  99. package/dist/server/routes/notificationAssetRoutes.js.map +1 -0
  100. package/dist/server/routes/securityRoutes.d.ts +7 -0
  101. package/dist/server/routes/securityRoutes.js +53 -0
  102. package/dist/server/routes/securityRoutes.js.map +1 -0
  103. package/dist/server/routes/socketBackpressure.d.ts +26 -0
  104. package/dist/server/routes/socketBackpressure.js +63 -0
  105. package/dist/server/routes/socketBackpressure.js.map +1 -0
  106. package/dist/server/routes/terminalLayoutRoutes.d.ts +9 -0
  107. package/dist/server/routes/terminalLayoutRoutes.js +108 -0
  108. package/dist/server/routes/terminalLayoutRoutes.js.map +1 -0
  109. package/dist/server/routes/terminalRoutes.d.ts +14 -0
  110. package/dist/server/routes/terminalRoutes.js +177 -0
  111. package/dist/server/routes/terminalRoutes.js.map +1 -0
  112. package/dist/server/routes/terminalWebSocket.d.ts +9 -0
  113. package/dist/server/routes/terminalWebSocket.js +129 -0
  114. package/dist/server/routes/terminalWebSocket.js.map +1 -0
  115. package/dist/server/routes/totpRoutes.d.ts +7 -0
  116. package/dist/server/routes/totpRoutes.js +46 -0
  117. package/dist/server/routes/totpRoutes.js.map +1 -0
  118. package/dist/server/routes/updateRoutes.d.ts +7 -0
  119. package/dist/server/routes/updateRoutes.js +24 -0
  120. package/dist/server/routes/updateRoutes.js.map +1 -0
  121. package/dist/server/routes/uploadRoutes.d.ts +9 -0
  122. package/dist/server/routes/uploadRoutes.js +95 -0
  123. package/dist/server/routes/uploadRoutes.js.map +1 -0
  124. package/dist/server/storage/fileStore.d.ts +90 -0
  125. package/dist/server/storage/fileStore.js +275 -0
  126. package/dist/server/storage/fileStore.js.map +1 -0
  127. package/dist/server/system/stats.d.ts +2 -0
  128. package/dist/server/system/stats.js +37 -0
  129. package/dist/server/system/stats.js.map +1 -0
  130. package/dist/server/terminal/NodePtyAdapter.d.ts +4 -0
  131. package/dist/server/terminal/NodePtyAdapter.js +14 -0
  132. package/dist/server/terminal/NodePtyAdapter.js.map +1 -0
  133. package/dist/server/terminal/PtyAdapter.d.ts +57 -0
  134. package/dist/server/terminal/PtyAdapter.js +2 -0
  135. package/dist/server/terminal/PtyAdapter.js.map +1 -0
  136. package/dist/server/terminal/TerminalManager.d.ts +74 -0
  137. package/dist/server/terminal/TerminalManager.js +561 -0
  138. package/dist/server/terminal/TerminalManager.js.map +1 -0
  139. package/dist/server/terminal/TmuxPtyAdapter.d.ts +25 -0
  140. package/dist/server/terminal/TmuxPtyAdapter.js +543 -0
  141. package/dist/server/terminal/TmuxPtyAdapter.js.map +1 -0
  142. package/dist/server/terminal/codexTranscriptSource.d.ts +9 -0
  143. package/dist/server/terminal/codexTranscriptSource.js +144 -0
  144. package/dist/server/terminal/codexTranscriptSource.js.map +1 -0
  145. package/dist/server/terminal/cwdResolver.d.ts +8 -0
  146. package/dist/server/terminal/cwdResolver.js +37 -0
  147. package/dist/server/terminal/cwdResolver.js.map +1 -0
  148. package/dist/server/terminal/outputBuffer.d.ts +7 -0
  149. package/dist/server/terminal/outputBuffer.js +17 -0
  150. package/dist/server/terminal/outputBuffer.js.map +1 -0
  151. package/dist/server/terminal/transcriptHistory.d.ts +7 -0
  152. package/dist/server/terminal/transcriptHistory.js +315 -0
  153. package/dist/server/terminal/transcriptHistory.js.map +1 -0
  154. package/dist/server/update/gitUpdate.d.ts +27 -0
  155. package/dist/server/update/gitUpdate.js +241 -0
  156. package/dist/server/update/gitUpdate.js.map +1 -0
  157. package/dist/server/uploads/uploadPaths.d.ts +18 -0
  158. package/dist/server/uploads/uploadPaths.js +116 -0
  159. package/dist/server/uploads/uploadPaths.js.map +1 -0
  160. package/dist/server/uploads/uploadService.d.ts +21 -0
  161. package/dist/server/uploads/uploadService.js +230 -0
  162. package/dist/server/uploads/uploadService.js.map +1 -0
  163. package/dist/shared/layoutState.d.ts +6 -0
  164. package/dist/shared/layoutState.js +115 -0
  165. package/dist/shared/layoutState.js.map +1 -0
  166. package/dist/shared/notificationAssets.d.ts +9 -0
  167. package/dist/shared/notificationAssets.js +27 -0
  168. package/dist/shared/notificationAssets.js.map +1 -0
  169. package/dist/shared/protocol.d.ts +308 -0
  170. package/dist/shared/protocol.js +29 -0
  171. package/dist/shared/protocol.js.map +1 -0
  172. package/dist/shared/types.d.ts +56 -0
  173. package/dist/shared/types.js +2 -0
  174. package/dist/shared/types.js.map +1 -0
  175. package/docs/assets/nterminal-workspace.png +0 -0
  176. package/docs/configuration.md +97 -0
  177. package/docs/features.md +126 -0
  178. package/docs/onboarding.md +122 -0
  179. package/docs/operations.md +112 -0
  180. package/docs/terminal-history.md +54 -0
  181. package/package.json +85 -0
  182. package/public/apple-touch-icon.png +0 -0
  183. package/public/assets/notifications/character-2258.mp4 +0 -0
  184. package/public/assets/notifications/character-2260.mp4 +0 -0
  185. package/public/assets/notifications/character-2272.mp4 +0 -0
  186. package/public/brand/nterminal-mark-64.png +0 -0
  187. package/public/brand/nterminal-mark.svg +4 -0
  188. package/public/brand/nterminal-wordmark-486x68.png +0 -0
  189. package/public/brand/nterminal-wordmark.svg +3 -0
  190. package/public/icons/app-icon-1024.png +0 -0
  191. package/public/icons/app-icon-384.png +0 -0
  192. package/public/icons/favicon-32.png +0 -0
  193. package/public/icons/favicon-64.png +0 -0
  194. package/public/icons/favicon-96.png +0 -0
  195. package/public/icons/favicon.svg +4 -0
  196. package/public/manifest.webmanifest +24 -0
  197. package/scripts/nterminalctl +588 -0
@@ -0,0 +1,551 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { constants } from 'node:fs';
3
+ import { copyFile, lstat, mkdir, open, readdir, realpath, rename, rm, unlink } from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { TextDecoder } from 'node:util';
6
+ import { FileDeletePreviewTokenError, signFileDeletePreviewToken, verifyFileDeletePreviewToken } from './rootToken.js';
7
+ export class FileExplorerError extends Error {
8
+ statusCode;
9
+ code;
10
+ constructor(statusCode, code) {
11
+ super(code);
12
+ this.statusCode = statusCode;
13
+ this.code = code;
14
+ }
15
+ }
16
+ export class FileExplorerService {
17
+ config;
18
+ constructor(config) {
19
+ this.config = config;
20
+ }
21
+ async resolveRootPath(rootPath) {
22
+ try {
23
+ const resolved = await realpath(rootPath);
24
+ const stat = await lstat(resolved);
25
+ if (!stat.isDirectory()) {
26
+ throw new FileExplorerError(409, 'root_unavailable');
27
+ }
28
+ return resolved;
29
+ }
30
+ catch (error) {
31
+ if (error instanceof FileExplorerError) {
32
+ throw error;
33
+ }
34
+ throw new FileExplorerError(409, 'root_unavailable');
35
+ }
36
+ }
37
+ async list(rootPath, requestPath) {
38
+ const resolved = await this.resolveExistingPath(rootPath, requestPath);
39
+ if (!resolved.stat.isDirectory()) {
40
+ throw new FileExplorerError(400, 'not_a_directory');
41
+ }
42
+ await assertStablePath(resolved.absolutePath, resolved.stat);
43
+ const names = await readdir(resolved.absolutePath);
44
+ await assertStablePath(resolved.absolutePath, resolved.stat);
45
+ if (names.length > this.config.fileListMaxEntries) {
46
+ throw new FileExplorerError(413, 'too_many_entries');
47
+ }
48
+ const entries = await Promise.all(names.map((name) => this.entryForPath(joinRelativePath(resolved.relativePath, name), path.join(resolved.absolutePath, name))));
49
+ entries.sort((left, right) => left.name.localeCompare(right.name));
50
+ return {
51
+ rootPath: resolved.rootPath,
52
+ path: resolved.relativePath,
53
+ entries
54
+ };
55
+ }
56
+ async readText(rootPath, requestPath) {
57
+ const resolved = await this.resolveExistingPath(rootPath, requestPath);
58
+ const handle = await this.openNoFollow(resolved.absolutePath, constants.O_RDONLY, 'path_not_found');
59
+ try {
60
+ const stat = await handle.stat();
61
+ assertSameVersion(stat, resolved.stat);
62
+ if (!stat.isFile()) {
63
+ throw new FileExplorerError(400, 'not_a_file');
64
+ }
65
+ if (stat.size > this.config.fileTextMaxBytes) {
66
+ throw new FileExplorerError(413, 'file_too_large');
67
+ }
68
+ const content = decodeTextFile(await handle.readFile());
69
+ return {
70
+ path: resolved.relativePath,
71
+ content,
72
+ language: languageForPath(resolved.relativePath),
73
+ version: versionFromStats(stat)
74
+ };
75
+ }
76
+ finally {
77
+ await handle.close().catch(() => undefined);
78
+ }
79
+ }
80
+ async resolveFileForTerminalOpen(rootPath, requestPath) {
81
+ const resolved = await this.resolveExistingPath(rootPath, requestPath);
82
+ const handle = await this.openNoFollow(resolved.absolutePath, constants.O_RDONLY, 'path_not_found');
83
+ try {
84
+ const stat = await handle.stat();
85
+ assertSameVersion(stat, resolved.stat);
86
+ if (!stat.isFile()) {
87
+ throw new FileExplorerError(400, 'not_a_file');
88
+ }
89
+ return {
90
+ path: resolved.relativePath,
91
+ absolutePath: resolved.absolutePath
92
+ };
93
+ }
94
+ finally {
95
+ await handle.close().catch(() => undefined);
96
+ }
97
+ }
98
+ async writeText(rootPath, requestPath, content, expectedVersion) {
99
+ if (Buffer.byteLength(content, 'utf8') > this.config.fileTextMaxBytes) {
100
+ throw new FileExplorerError(413, 'file_too_large');
101
+ }
102
+ const resolved = await this.resolveExistingPath(rootPath, requestPath);
103
+ const handle = await this.openNoFollow(resolved.absolutePath, constants.O_WRONLY, 'path_not_found');
104
+ let tempPath = null;
105
+ try {
106
+ const current = await handle.stat();
107
+ assertSameVersion(current, resolved.stat);
108
+ if (!current.isFile()) {
109
+ throw new FileExplorerError(400, 'not_a_file');
110
+ }
111
+ if (!sameVersion(versionFromStats(current), expectedVersion)) {
112
+ throw new FileExplorerError(409, 'file_version_conflict');
113
+ }
114
+ tempPath = path.join(path.dirname(resolved.absolutePath), `.${path.basename(resolved.absolutePath)}.nterminal-${randomUUID()}.tmp`);
115
+ const tempHandle = await open(tempPath, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | noFollowFlag());
116
+ try {
117
+ await tempHandle.writeFile(content, 'utf8');
118
+ }
119
+ finally {
120
+ await tempHandle.close().catch(() => undefined);
121
+ }
122
+ const latest = await handle.stat();
123
+ if (!sameVersion(versionFromStats(latest), expectedVersion)) {
124
+ throw new FileExplorerError(409, 'file_version_conflict');
125
+ }
126
+ await rename(tempPath, resolved.absolutePath);
127
+ tempPath = null;
128
+ }
129
+ finally {
130
+ await handle.close().catch(() => undefined);
131
+ if (tempPath) {
132
+ await unlink(tempPath).catch(() => undefined);
133
+ }
134
+ }
135
+ const next = await lstat(resolved.absolutePath);
136
+ return {
137
+ path: resolved.relativePath,
138
+ version: versionFromStats(next)
139
+ };
140
+ }
141
+ async createEntry(rootPath, requestPath, kind) {
142
+ const resolved = await this.resolveNewPath(rootPath, requestPath);
143
+ if (kind === 'directory') {
144
+ try {
145
+ await mkdir(resolved.absolutePath);
146
+ }
147
+ catch (error) {
148
+ if (isNodeErrorWithCode(error, 'EEXIST')) {
149
+ throw new FileExplorerError(409, 'target_exists');
150
+ }
151
+ throw error;
152
+ }
153
+ }
154
+ else {
155
+ let handle = null;
156
+ try {
157
+ handle = await open(resolved.absolutePath, constants.O_CREAT | constants.O_EXCL | constants.O_WRONLY | noFollowFlag());
158
+ }
159
+ catch (error) {
160
+ if (isNodeErrorWithCode(error, 'EEXIST')) {
161
+ throw new FileExplorerError(409, 'target_exists');
162
+ }
163
+ throw error;
164
+ }
165
+ finally {
166
+ await handle?.close().catch(() => undefined);
167
+ }
168
+ }
169
+ return this.entryForPath(resolved.relativePath, resolved.absolutePath);
170
+ }
171
+ async moveEntry(rootPath, sourcePath, destinationPath) {
172
+ const source = await this.resolveExistingPath(rootPath, sourcePath);
173
+ const destination = await this.resolveNewPath(rootPath, destinationPath);
174
+ const sourceStat = source.stat;
175
+ await assertStablePath(source.absolutePath, sourceStat);
176
+ try {
177
+ if (sourceStat.isFile()) {
178
+ await copyFile(source.absolutePath, destination.absolutePath, constants.COPYFILE_EXCL);
179
+ const latestSourceStat = await lstat(source.absolutePath);
180
+ if (!sameVersion(versionFromStats(latestSourceStat), versionFromStats(sourceStat))) {
181
+ await unlink(destination.absolutePath).catch(() => undefined);
182
+ throw new FileExplorerError(409, 'file_version_conflict');
183
+ }
184
+ await unlink(source.absolutePath);
185
+ }
186
+ else {
187
+ if (sourceStat.isDirectory()) {
188
+ await this.countDescendants(source.absolutePath);
189
+ }
190
+ await rename(source.absolutePath, destination.absolutePath);
191
+ }
192
+ }
193
+ catch (error) {
194
+ if (isNodeErrorWithCode(error, 'EEXIST')) {
195
+ throw new FileExplorerError(409, 'target_exists');
196
+ }
197
+ throw error;
198
+ }
199
+ return this.entryForPath(destination.relativePath, destination.absolutePath);
200
+ }
201
+ async previewDelete(rootPath, requestPath, rootToken) {
202
+ const target = await this.inspectDeleteTarget(rootPath, requestPath);
203
+ const previewToken = signFileDeletePreviewToken(this.config, {
204
+ rootToken,
205
+ path: target.path,
206
+ kind: target.kind,
207
+ descendantCount: target.descendantCount,
208
+ entryVersion: target.entryVersion
209
+ });
210
+ return {
211
+ path: target.path,
212
+ kind: target.kind,
213
+ descendantCount: target.descendantCount,
214
+ previewToken
215
+ };
216
+ }
217
+ async deleteEntry(rootPath, requestPath, previewToken, rootToken) {
218
+ const target = await this.inspectDeleteTarget(rootPath, requestPath);
219
+ try {
220
+ verifyFileDeletePreviewToken(this.config, previewToken, rootToken, {
221
+ path: target.path,
222
+ kind: target.kind,
223
+ descendantCount: target.descendantCount,
224
+ entryVersion: target.entryVersion
225
+ });
226
+ }
227
+ catch (error) {
228
+ if (error instanceof FileDeletePreviewTokenError) {
229
+ throw new FileExplorerError(409, error.code);
230
+ }
231
+ throw error;
232
+ }
233
+ await rm(target.absolutePath, { recursive: target.kind === 'directory' });
234
+ return { path: target.path, deleted: true };
235
+ }
236
+ async previewFile(rootPath, requestPath) {
237
+ const resolved = await this.resolveExistingPath(rootPath, requestPath);
238
+ const handle = await this.openNoFollow(resolved.absolutePath, constants.O_RDONLY, 'path_not_found');
239
+ try {
240
+ const stat = await handle.stat();
241
+ assertSameVersion(stat, resolved.stat);
242
+ if (!stat.isFile()) {
243
+ throw new FileExplorerError(400, 'not_a_file');
244
+ }
245
+ if (stat.size > this.config.filePreviewMaxBytes) {
246
+ throw new FileExplorerError(413, 'file_too_large');
247
+ }
248
+ const contentType = contentTypeForPath(resolved.relativePath);
249
+ if (!contentType) {
250
+ throw new FileExplorerError(415, 'unsupported_preview');
251
+ }
252
+ const stream = handle.createReadStream();
253
+ return {
254
+ absolutePath: resolved.absolutePath,
255
+ contentType,
256
+ size: stat.size,
257
+ stream
258
+ };
259
+ }
260
+ catch (error) {
261
+ await handle.close().catch(() => undefined);
262
+ throw error;
263
+ }
264
+ }
265
+ async resolveExistingPath(rootPath, requestPath) {
266
+ const root = await this.resolveRootPath(rootPath);
267
+ const relativePath = normalizeRelativePath(requestPath);
268
+ const segments = relativePath ? relativePath.split('/') : [];
269
+ const absolutePath = path.resolve(root, ...segments);
270
+ assertContained(root, absolutePath);
271
+ await this.assertNoSymlinkSegments(root, segments, false);
272
+ const stat = await lstat(absolutePath);
273
+ if (stat.isSymbolicLink()) {
274
+ throw new FileExplorerError(400, 'symlink_not_allowed');
275
+ }
276
+ assertContained(root, await realpath(absolutePath));
277
+ return { rootPath: root, relativePath, absolutePath, segments, stat };
278
+ }
279
+ async resolveNewPath(rootPath, requestPath) {
280
+ const root = await this.resolveRootPath(rootPath);
281
+ const relativePath = normalizeRelativePath(requestPath);
282
+ if (!relativePath) {
283
+ throw new FileExplorerError(400, 'invalid_file_path');
284
+ }
285
+ const segments = relativePath.split('/');
286
+ const absolutePath = path.resolve(root, ...segments);
287
+ assertContained(root, absolutePath);
288
+ await this.assertNoSymlinkSegments(root, segments, true);
289
+ assertContained(root, await realpath(path.dirname(absolutePath)));
290
+ return { rootPath: root, relativePath, absolutePath, segments };
291
+ }
292
+ async assertNoSymlinkSegments(root, segments, allowMissingFinal) {
293
+ let current = root;
294
+ for (let index = 0; index < segments.length; index += 1) {
295
+ current = path.join(current, segments[index]);
296
+ let stat;
297
+ try {
298
+ stat = await lstat(current);
299
+ }
300
+ catch (error) {
301
+ if (allowMissingFinal && index === segments.length - 1 && isNodeErrorWithCode(error, 'ENOENT')) {
302
+ return;
303
+ }
304
+ throw new FileExplorerError(404, 'path_not_found');
305
+ }
306
+ if (stat.isSymbolicLink()) {
307
+ throw new FileExplorerError(400, 'symlink_not_allowed');
308
+ }
309
+ if (index < segments.length - 1 && !stat.isDirectory()) {
310
+ throw new FileExplorerError(400, 'not_a_directory');
311
+ }
312
+ if (allowMissingFinal && index === segments.length - 1) {
313
+ throw new FileExplorerError(409, 'target_exists');
314
+ }
315
+ }
316
+ }
317
+ async entryForPath(relativePath, absolutePath) {
318
+ const stat = await lstat(absolutePath);
319
+ const kind = kindFromStats(stat);
320
+ return {
321
+ name: path.basename(absolutePath),
322
+ path: relativePath,
323
+ kind,
324
+ size: stat.isFile() ? stat.size : null,
325
+ mtime: stat.mtime.toISOString(),
326
+ editable: stat.isFile() && stat.size <= this.config.fileTextMaxBytes && isLikelyTextPath(relativePath),
327
+ previewKind: stat.isFile() ? previewKindForPath(relativePath) : 'none'
328
+ };
329
+ }
330
+ async inspectDeleteTarget(rootPath, requestPath) {
331
+ const resolved = await this.resolveExistingPath(rootPath, requestPath);
332
+ const stat = resolved.stat;
333
+ await assertStablePath(resolved.absolutePath, stat);
334
+ const kind = kindFromStats(stat);
335
+ const descendantCount = stat.isDirectory() ? await this.countDescendants(resolved.absolutePath) : 0;
336
+ return {
337
+ absolutePath: resolved.absolutePath,
338
+ path: resolved.relativePath,
339
+ kind,
340
+ descendantCount,
341
+ entryVersion: versionFromStats(stat)
342
+ };
343
+ }
344
+ async countDescendants(absolutePath) {
345
+ const names = await readdir(absolutePath);
346
+ let count = 0;
347
+ for (const name of names) {
348
+ const childPath = path.join(absolutePath, name);
349
+ const stat = await lstat(childPath);
350
+ if (stat.isSymbolicLink()) {
351
+ throw new FileExplorerError(400, 'symlink_not_allowed');
352
+ }
353
+ count += 1;
354
+ if (stat.isDirectory()) {
355
+ count += await this.countDescendants(childPath);
356
+ }
357
+ }
358
+ return count;
359
+ }
360
+ async openNoFollow(absolutePath, flags, missingCode) {
361
+ try {
362
+ return await open(absolutePath, flags | noFollowFlag());
363
+ }
364
+ catch (error) {
365
+ if (isNodeErrorWithCode(error, 'ELOOP')) {
366
+ throw new FileExplorerError(400, 'symlink_not_allowed');
367
+ }
368
+ if (isNodeErrorWithCode(error, 'ENOENT')) {
369
+ throw new FileExplorerError(404, missingCode);
370
+ }
371
+ throw error;
372
+ }
373
+ }
374
+ }
375
+ function normalizeRelativePath(requestPath) {
376
+ if (typeof requestPath !== 'string') {
377
+ throw new FileExplorerError(400, 'invalid_file_path');
378
+ }
379
+ if (requestPath === '' || requestPath === '.') {
380
+ return '';
381
+ }
382
+ if (requestPath.includes('\0') || requestPath.includes('\\') || path.posix.isAbsolute(requestPath) || /^[A-Za-z]:/.test(requestPath)) {
383
+ throw new FileExplorerError(400, 'invalid_file_path');
384
+ }
385
+ const segments = requestPath.split('/');
386
+ if (segments.some((segment) => segment === '' || segment === '.' || segment === '..')) {
387
+ throw new FileExplorerError(400, 'invalid_file_path');
388
+ }
389
+ return segments.join('/');
390
+ }
391
+ function assertContained(rootPath, absolutePath) {
392
+ const relative = path.relative(rootPath, absolutePath);
393
+ if (relative.startsWith('..') || path.isAbsolute(relative)) {
394
+ throw new FileExplorerError(400, 'invalid_file_path');
395
+ }
396
+ }
397
+ function joinRelativePath(parent, name) {
398
+ return parent ? `${parent}/${name}` : name;
399
+ }
400
+ function kindFromStats(stat) {
401
+ if (stat.isSymbolicLink()) {
402
+ return 'symlink';
403
+ }
404
+ if (stat.isDirectory()) {
405
+ return 'directory';
406
+ }
407
+ if (stat.isFile()) {
408
+ return 'file';
409
+ }
410
+ return 'other';
411
+ }
412
+ function previewKindForPath(filePath) {
413
+ const contentType = contentTypeForPath(filePath);
414
+ if (!contentType) {
415
+ return 'none';
416
+ }
417
+ return contentType === 'application/pdf' ? 'pdf' : 'image';
418
+ }
419
+ function contentTypeForPath(filePath) {
420
+ switch (path.extname(filePath).toLowerCase()) {
421
+ case '.apng':
422
+ return 'image/apng';
423
+ case '.avif':
424
+ return 'image/avif';
425
+ case '.gif':
426
+ return 'image/gif';
427
+ case '.jpg':
428
+ case '.jpeg':
429
+ return 'image/jpeg';
430
+ case '.png':
431
+ return 'image/png';
432
+ case '.svg':
433
+ return 'image/svg+xml';
434
+ case '.webp':
435
+ return 'image/webp';
436
+ case '.pdf':
437
+ return 'application/pdf';
438
+ default:
439
+ return null;
440
+ }
441
+ }
442
+ function languageForPath(filePath) {
443
+ const extension = path.extname(filePath).toLowerCase();
444
+ return extension === '.md' || extension === '.markdown' ? 'markdown' : 'text';
445
+ }
446
+ function isLikelyTextPath(filePath) {
447
+ const name = path.basename(filePath).toLowerCase();
448
+ if ([
449
+ '.env',
450
+ '.env.example',
451
+ '.gitignore',
452
+ '.npmrc',
453
+ '.nvmrc',
454
+ '.prettierrc',
455
+ '.eslintignore',
456
+ '.dockerignore',
457
+ 'dockerfile',
458
+ 'makefile',
459
+ 'license',
460
+ 'readme',
461
+ 'changelog'
462
+ ].includes(name)) {
463
+ return true;
464
+ }
465
+ switch (path.extname(name)) {
466
+ case '.bash':
467
+ case '.c':
468
+ case '.conf':
469
+ case '.cpp':
470
+ case '.cs':
471
+ case '.css':
472
+ case '.csv':
473
+ case '.cts':
474
+ case '.dockerfile':
475
+ case '.env':
476
+ case '.go':
477
+ case '.graphql':
478
+ case '.h':
479
+ case '.hpp':
480
+ case '.html':
481
+ case '.ini':
482
+ case '.java':
483
+ case '.js':
484
+ case '.json':
485
+ case '.jsx':
486
+ case '.kt':
487
+ case '.log':
488
+ case '.lua':
489
+ case '.mjs':
490
+ case '.md':
491
+ case '.mdx':
492
+ case '.mts':
493
+ case '.php':
494
+ case '.pl':
495
+ case '.properties':
496
+ case '.py':
497
+ case '.rb':
498
+ case '.rs':
499
+ case '.sh':
500
+ case '.sql':
501
+ case '.swift':
502
+ case '.toml':
503
+ case '.ts':
504
+ case '.tsx':
505
+ case '.txt':
506
+ case '.vue':
507
+ case '.xml':
508
+ case '.yaml':
509
+ case '.yml':
510
+ case '.zsh':
511
+ return true;
512
+ default:
513
+ return false;
514
+ }
515
+ }
516
+ function versionFromStats(stat) {
517
+ return {
518
+ size: stat.size,
519
+ mtimeMs: stat.mtimeMs,
520
+ ino: stat.ino
521
+ };
522
+ }
523
+ function sameVersion(left, right) {
524
+ return left.size === right.size && left.mtimeMs === right.mtimeMs && (right.ino === undefined || left.ino === right.ino);
525
+ }
526
+ async function assertStablePath(absolutePath, expected) {
527
+ assertSameVersion(await lstat(absolutePath), expected);
528
+ }
529
+ function assertSameVersion(actual, expected) {
530
+ if (!sameVersion(versionFromStats(actual), versionFromStats(expected))) {
531
+ throw new FileExplorerError(409, 'file_version_conflict');
532
+ }
533
+ }
534
+ function decodeTextFile(content) {
535
+ if (content.includes(0)) {
536
+ throw new FileExplorerError(415, 'unsupported_text_file');
537
+ }
538
+ try {
539
+ return new TextDecoder('utf-8', { fatal: true }).decode(content);
540
+ }
541
+ catch {
542
+ throw new FileExplorerError(415, 'unsupported_text_file');
543
+ }
544
+ }
545
+ function noFollowFlag() {
546
+ return constants.O_NOFOLLOW ?? 0;
547
+ }
548
+ function isNodeErrorWithCode(error, code) {
549
+ return typeof error === 'object' && error !== null && 'code' in error && error.code === code;
550
+ }
551
+ //# sourceMappingURL=fileExplorerService.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileExplorerService.js","sourceRoot":"","sources":["../../../src/server/files/fileExplorerService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import type { AppConfig } from '../config.js';
2
+ import type { FileVersion } from '../../shared/protocol.js';
3
+ export interface FileRootTokenPayload {
4
+ version: 1;
5
+ terminalId: string;
6
+ rootPath: string;
7
+ issuedAt: string;
8
+ nonce: string;
9
+ }
10
+ export interface SignFileRootTokenOptions {
11
+ terminalId: string;
12
+ rootPath: string;
13
+ now?: () => Date;
14
+ nonce?: () => string;
15
+ }
16
+ export interface SignedFileRootToken {
17
+ rootToken: string;
18
+ issuedAt: string;
19
+ }
20
+ interface FileDeletePreviewTokenPayload {
21
+ version: 1;
22
+ rootTokenHash: string;
23
+ path: string;
24
+ kind: string;
25
+ descendantCount: number;
26
+ entryVersion: FileVersion;
27
+ issuedAt: string;
28
+ nonce: string;
29
+ }
30
+ export interface SignFileDeletePreviewTokenOptions {
31
+ rootToken: string;
32
+ path: string;
33
+ kind: string;
34
+ descendantCount: number;
35
+ entryVersion: FileVersion;
36
+ now?: () => Date;
37
+ nonce?: () => string;
38
+ }
39
+ export declare class FileRootTokenError extends Error {
40
+ readonly code = "invalid_root_token";
41
+ constructor();
42
+ }
43
+ export declare class FileDeletePreviewTokenError extends Error {
44
+ readonly code = "invalid_delete_preview_token";
45
+ constructor();
46
+ }
47
+ export declare function signFileRootToken(config: Pick<AppConfig, 'sessionSecret'>, options: SignFileRootTokenOptions): SignedFileRootToken;
48
+ export declare function verifyFileRootToken(config: Pick<AppConfig, 'sessionSecret'>, token: string): FileRootTokenPayload;
49
+ export declare function signFileDeletePreviewToken(config: Pick<AppConfig, 'sessionSecret'>, options: SignFileDeletePreviewTokenOptions): string;
50
+ export declare function verifyFileDeletePreviewToken(config: Pick<AppConfig, 'sessionSecret'>, token: string, rootToken: string, expected: Pick<FileDeletePreviewTokenPayload, 'path' | 'kind' | 'descendantCount' | 'entryVersion'>): void;
51
+ export {};