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,275 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { closeSync, mkdirSync, openSync, renameSync, writeSync } from 'node:fs';
3
+ import { mkdir, open, readFile, rename } from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { normalizeTerminalLayoutState } from '../../shared/layoutState.js';
6
+ const emptyState = () => ({
7
+ passwordCredential: null,
8
+ totpCredential: null,
9
+ mainName: null,
10
+ agents: [],
11
+ trustedDevices: [],
12
+ ipWhitelist: [],
13
+ terminalLayout: null,
14
+ agentLayouts: {},
15
+ notificationAssets: [],
16
+ notificationAssetDisabledIds: []
17
+ });
18
+ function normalizeState(value) {
19
+ if (!value || typeof value !== 'object') {
20
+ return emptyState();
21
+ }
22
+ const state = value;
23
+ const passwordCredential = state.passwordCredential &&
24
+ typeof state.passwordCredential === 'object' &&
25
+ state.passwordCredential.algorithm === 'scrypt' &&
26
+ typeof state.passwordCredential.hash === 'string' &&
27
+ typeof state.passwordCredential.salt === 'string' &&
28
+ typeof state.passwordCredential.createdAt === 'string' &&
29
+ typeof state.passwordCredential.updatedAt === 'string'
30
+ ? state.passwordCredential
31
+ : null;
32
+ const totpCredential = state.totpCredential &&
33
+ typeof state.totpCredential === 'object' &&
34
+ typeof state.totpCredential.secret === 'string' &&
35
+ state.totpCredential.algorithm === 'SHA1' &&
36
+ state.totpCredential.digits === 6 &&
37
+ state.totpCredential.period === 30 &&
38
+ typeof state.totpCredential.createdAt === 'string'
39
+ ? state.totpCredential
40
+ : null;
41
+ const agents = Array.isArray(state.agents)
42
+ ? state.agents.filter((a) => a !== null &&
43
+ typeof a === 'object' &&
44
+ typeof a.id === 'string' &&
45
+ typeof a.name === 'string' &&
46
+ typeof a.url === 'string' &&
47
+ typeof a.token === 'string' &&
48
+ typeof a.createdAt === 'string')
49
+ : [];
50
+ const trustedDevices = Array.isArray(state.trustedDevices)
51
+ ? state.trustedDevices.filter((d) => d !== null &&
52
+ typeof d === 'object' &&
53
+ typeof d.id === 'string' &&
54
+ typeof d.tokenHash === 'string' &&
55
+ typeof d.label === 'string' &&
56
+ typeof d.createdAt === 'string' &&
57
+ typeof d.lastSeenAt === 'string' &&
58
+ typeof d.expiresAt === 'string')
59
+ : [];
60
+ const ipWhitelist = Array.isArray(state.ipWhitelist)
61
+ ? state.ipWhitelist.filter((r) => r !== null &&
62
+ typeof r === 'object' &&
63
+ typeof r.id === 'string' &&
64
+ typeof r.value === 'string' &&
65
+ typeof r.label === 'string' &&
66
+ typeof r.createdAt === 'string')
67
+ : [];
68
+ const agentLayouts = {};
69
+ if (state.agentLayouts && typeof state.agentLayouts === 'object') {
70
+ for (const [agentId, value] of Object.entries(state.agentLayouts)) {
71
+ const normalized = normalizeStoredTerminalLayout(value);
72
+ if (normalized) {
73
+ agentLayouts[agentId] = normalized;
74
+ }
75
+ }
76
+ }
77
+ const notificationAssets = Array.isArray(state.notificationAssets)
78
+ ? state.notificationAssets.filter((asset) => asset !== null &&
79
+ typeof asset === 'object' &&
80
+ typeof asset.id === 'string' &&
81
+ typeof asset.filename === 'string' &&
82
+ typeof asset.storedFilename === 'string' &&
83
+ (asset.contentType === 'video/mp4' ||
84
+ asset.contentType === 'video/webm') &&
85
+ typeof asset.size === 'number' &&
86
+ Number.isFinite(asset.size) &&
87
+ asset.size >= 0 &&
88
+ typeof asset.createdAt === 'string')
89
+ : [];
90
+ const notificationAssetDisabledIds = Array.isArray(state.notificationAssetDisabledIds)
91
+ ? Array.from(new Set(state.notificationAssetDisabledIds.filter((assetId) => typeof assetId === 'string' && assetId.length > 0)))
92
+ : [];
93
+ // mainName: only accept non-empty strings, otherwise null so older state
94
+ // files (pre-mainName) and operators who cleared the field both fall back
95
+ // to the client's "Local" default.
96
+ const rawMainName = typeof state.mainName === 'string' ? state.mainName.trim() : '';
97
+ const mainName = rawMainName || null;
98
+ return {
99
+ passwordCredential,
100
+ totpCredential,
101
+ mainName,
102
+ agents,
103
+ trustedDevices,
104
+ ipWhitelist,
105
+ terminalLayout: normalizeStoredTerminalLayout(state.terminalLayout),
106
+ agentLayouts,
107
+ notificationAssets,
108
+ notificationAssetDisabledIds
109
+ };
110
+ }
111
+ function normalizeStoredTerminalLayout(value) {
112
+ if (!value || typeof value !== 'object') {
113
+ return null;
114
+ }
115
+ const candidate = value;
116
+ const layout = normalizeTerminalLayoutState(candidate.layout);
117
+ const revision = candidate.revision;
118
+ if (!layout || typeof revision !== 'number' || !Number.isInteger(revision) || revision < 0 || typeof candidate.updatedAt !== 'string') {
119
+ return null;
120
+ }
121
+ return {
122
+ layout,
123
+ revision,
124
+ updatedAt: candidate.updatedAt
125
+ };
126
+ }
127
+ const DEFAULT_COALESCE_WINDOW_MS = 1000;
128
+ export class FileStore {
129
+ path;
130
+ memoryState = null;
131
+ dirty = false;
132
+ flushTimer = null;
133
+ updateQueue = Promise.resolve();
134
+ coalesceWindowMs;
135
+ onError;
136
+ constructor(path, options = {}) {
137
+ this.path = path;
138
+ this.coalesceWindowMs = options.coalesceWindowMs ?? DEFAULT_COALESCE_WINDOW_MS;
139
+ this.onError = options.onError ?? defaultOnError;
140
+ }
141
+ // Replace the error handler after construction. The Fastify logger is not
142
+ // available when the store is built in index.ts, so we wire it in once the
143
+ // app is constructed.
144
+ setErrorHandler(handler) {
145
+ this.onError = handler;
146
+ }
147
+ async init() {
148
+ await mkdir(path.dirname(this.path), { recursive: true, mode: 0o700 });
149
+ try {
150
+ this.memoryState = deepFreeze(await this.readFromDisk());
151
+ }
152
+ catch (error) {
153
+ if (error.code !== 'ENOENT') {
154
+ throw error;
155
+ }
156
+ this.memoryState = deepFreeze(emptyState());
157
+ await this.writeToDisk(this.memoryState);
158
+ }
159
+ }
160
+ async read() {
161
+ if (this.memoryState) {
162
+ return this.memoryState;
163
+ }
164
+ const state = deepFreeze(await this.readFromDisk());
165
+ this.memoryState = state;
166
+ return state;
167
+ }
168
+ async update(updater, options = {}) {
169
+ const mode = options.flush ?? 'coalesced';
170
+ return this.enqueue(async () => {
171
+ const current = this.memoryState ?? deepFreeze(await this.readFromDisk());
172
+ const next = deepFreeze(await updater(current));
173
+ this.memoryState = next;
174
+ this.dirty = true;
175
+ if (mode === 'immediate') {
176
+ await this.flushDirty();
177
+ }
178
+ else {
179
+ this.scheduleFlush();
180
+ }
181
+ return next;
182
+ });
183
+ }
184
+ // Force any pending coalesced write to disk now.
185
+ async flush() {
186
+ await this.enqueue(() => this.flushDirty());
187
+ }
188
+ // Synchronous flush for shutdown handlers. Bypasses the update queue so it
189
+ // works inside `beforeExit` and SIGTERM handlers without an extra microtask
190
+ // tick. Safe to call after a normal async `flush()` — becomes a no-op.
191
+ flushSync() {
192
+ this.cancelTimer();
193
+ if (!this.dirty || !this.memoryState) {
194
+ return;
195
+ }
196
+ mkdirSync(path.dirname(this.path), { recursive: true, mode: 0o700 });
197
+ const tempPath = `${this.path}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`;
198
+ const fd = openSync(tempPath, 'w', 0o600);
199
+ try {
200
+ writeSync(fd, `${JSON.stringify(this.memoryState, null, 2)}\n`);
201
+ }
202
+ finally {
203
+ closeSync(fd);
204
+ }
205
+ renameSync(tempPath, this.path);
206
+ this.dirty = false;
207
+ }
208
+ async flushDirty() {
209
+ this.cancelTimer();
210
+ if (!this.dirty || !this.memoryState) {
211
+ return;
212
+ }
213
+ await this.writeToDisk(this.memoryState);
214
+ this.dirty = false;
215
+ }
216
+ scheduleFlush() {
217
+ if (this.flushTimer) {
218
+ return;
219
+ }
220
+ const window = Math.max(0, this.coalesceWindowMs);
221
+ this.flushTimer = setTimeout(() => {
222
+ this.flushTimer = null;
223
+ this.flush().catch((err) => this.onError(err));
224
+ }, window);
225
+ if (typeof this.flushTimer.unref === 'function') {
226
+ this.flushTimer.unref();
227
+ }
228
+ }
229
+ cancelTimer() {
230
+ if (this.flushTimer) {
231
+ clearTimeout(this.flushTimer);
232
+ this.flushTimer = null;
233
+ }
234
+ }
235
+ async readFromDisk() {
236
+ const raw = await readFile(this.path, 'utf8');
237
+ return normalizeState(JSON.parse(raw));
238
+ }
239
+ async writeToDisk(state) {
240
+ await mkdir(path.dirname(this.path), { recursive: true, mode: 0o700 });
241
+ const tempPath = `${this.path}.${process.pid}.${Date.now()}.${randomUUID()}.tmp`;
242
+ const handle = await open(tempPath, 'w', 0o600);
243
+ try {
244
+ await handle.writeFile(`${JSON.stringify(state, null, 2)}\n`, 'utf8');
245
+ }
246
+ finally {
247
+ await handle.close();
248
+ }
249
+ await rename(tempPath, this.path);
250
+ }
251
+ enqueue(fn) {
252
+ const run = () => fn();
253
+ const result = this.updateQueue.then(run, run);
254
+ this.updateQueue = result.then(() => undefined, () => undefined);
255
+ return result;
256
+ }
257
+ }
258
+ function defaultOnError(err) {
259
+ console.error('FileStore: coalesced flush failed', err);
260
+ }
261
+ // Recursively `Object.freeze` so callers of `read()` can't accidentally mutate
262
+ // the store's internal state without going through `update()`. Skips already
263
+ // frozen subtrees, so freezing a new state that reuses sub-objects from the
264
+ // previous frozen state is cheap.
265
+ function deepFreeze(value) {
266
+ if (value === null || typeof value !== 'object' || Object.isFrozen(value)) {
267
+ return value;
268
+ }
269
+ Object.freeze(value);
270
+ for (const key of Object.keys(value)) {
271
+ deepFreeze(value[key]);
272
+ }
273
+ return value;
274
+ }
275
+ //# sourceMappingURL=fileStore.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fileStore.js","sourceRoot":"","sources":["../../../src/server/storage/fileStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { SystemStatsResponse } from '../../shared/protocol.js';
2
+ export declare function collectSystemStats(): SystemStatsResponse;
@@ -0,0 +1,37 @@
1
+ import os from 'node:os';
2
+ let previousSample = null;
3
+ function takeCpuSample() {
4
+ let idle = 0;
5
+ let total = 0;
6
+ for (const cpu of os.cpus()) {
7
+ const t = cpu.times;
8
+ idle += t.idle;
9
+ total += t.user + t.nice + t.sys + t.idle + t.irq;
10
+ }
11
+ return { idle, total };
12
+ }
13
+ export function collectSystemStats() {
14
+ const sample = takeCpuSample();
15
+ let cpuPercent = null;
16
+ if (previousSample !== null) {
17
+ const totalDelta = sample.total - previousSample.total;
18
+ const idleDelta = sample.idle - previousSample.idle;
19
+ if (totalDelta > 0) {
20
+ const busy = Math.max(0, 1 - idleDelta / totalDelta);
21
+ cpuPercent = Math.round(busy * 1000) / 10;
22
+ }
23
+ }
24
+ previousSample = sample;
25
+ const totalBytes = os.totalmem();
26
+ const freeBytes = os.freemem();
27
+ const usedBytes = Math.max(0, totalBytes - freeBytes);
28
+ const memoryPercent = totalBytes > 0 ? Math.round((usedBytes / totalBytes) * 1000) / 10 : 0;
29
+ return {
30
+ cpuPercent,
31
+ memoryPercent,
32
+ memoryUsedBytes: usedBytes,
33
+ memoryTotalBytes: totalBytes,
34
+ cores: os.cpus().length
35
+ };
36
+ }
37
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/server/system/stats.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AAgBzB,IAAI,cAAc,GAA0B,IAAI,CAAC;AAEjD,SAAS,aAAa;IACpB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,GAAG,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC;QACpB,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC;QACf,KAAK,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC;IACpD,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,MAAM,MAAM,GAAG,aAAa,EAAE,CAAC;IAC/B,IAAI,UAAU,GAAkB,IAAI,CAAC;IACrC,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;QAC5B,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC;QACvD,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,GAAG,cAAc,CAAC,IAAI,CAAC;QACpD,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,GAAG,UAAU,CAAC,CAAC;YACrD,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,cAAc,GAAG,MAAM,CAAC;IAExB,MAAM,UAAU,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;IACjC,MAAM,SAAS,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC,CAAC;IACtD,MAAM,aAAa,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,GAAG,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAE5F,OAAO;QACL,UAAU;QACV,aAAa;QACb,eAAe,EAAE,SAAS;QAC1B,gBAAgB,EAAE,UAAU;QAC5B,KAAK,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,MAAM;KACxB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { PtyAdapter, PtyProcess, PtySpawnOptions } from './PtyAdapter.js';
2
+ export declare class NodePtyAdapter implements PtyAdapter {
3
+ spawn(options: PtySpawnOptions): PtyProcess;
4
+ }
@@ -0,0 +1,14 @@
1
+ import * as nodePty from 'node-pty';
2
+ export class NodePtyAdapter {
3
+ spawn(options) {
4
+ const pty = nodePty.spawn(options.shell, [], {
5
+ name: 'xterm-256color',
6
+ cols: options.cols,
7
+ rows: options.rows,
8
+ cwd: options.cwd,
9
+ env: options.env
10
+ });
11
+ return pty;
12
+ }
13
+ }
14
+ //# sourceMappingURL=NodePtyAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NodePtyAdapter.js","sourceRoot":"","sources":["../../../src/server/terminal/NodePtyAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,UAAU,CAAC;AAGpC,MAAM,OAAO,cAAc;IACzB,KAAK,CAAC,OAAwB;QAC5B,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,EAAE;YAC3C,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,GAAG,EAAE,OAAO,CAAC,GAAG;YAChB,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;QACH,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
@@ -0,0 +1,57 @@
1
+ import type { TerminalTranscriptProvider } from '../../shared/protocol.js';
2
+ export interface PtyExit {
3
+ exitCode: number | null;
4
+ }
5
+ export interface PtyProcess {
6
+ pid: number;
7
+ write(data: string): void;
8
+ resize(cols: number, rows: number): void;
9
+ pause(): void;
10
+ resume(): void;
11
+ kill(): void;
12
+ onData(listener: (data: string) => void): Disposable;
13
+ onExit(listener: (event: PtyExit) => void): Disposable;
14
+ }
15
+ export interface Disposable {
16
+ dispose(): void;
17
+ }
18
+ export interface PtySpawnOptions {
19
+ sessionId: string;
20
+ shell: string;
21
+ cwd: string;
22
+ cols: number;
23
+ rows: number;
24
+ env: NodeJS.ProcessEnv;
25
+ }
26
+ export interface PersistedSession {
27
+ sessionId: string;
28
+ title?: string;
29
+ }
30
+ export interface PtyHistoryCapture {
31
+ startLine: number;
32
+ endLine: number;
33
+ hasMore: boolean;
34
+ output: string[];
35
+ }
36
+ export interface PtyHistoryCaptureOptions {
37
+ beforeLine?: number;
38
+ limit: number;
39
+ }
40
+ export interface PtyTranscriptSource {
41
+ provider: TerminalTranscriptProvider;
42
+ sessionId: string;
43
+ filePath: string;
44
+ }
45
+ export interface PtyAdapter {
46
+ spawn(options: PtySpawnOptions & {
47
+ title?: string;
48
+ }): PtyProcess;
49
+ listExisting?(): PersistedSession[];
50
+ setSessionTitle?(sessionId: string, title: string): void;
51
+ pollSessions?(): Promise<Map<string, {
52
+ currentCommand: string;
53
+ busy: boolean;
54
+ }>>;
55
+ captureHistory?(sessionId: string, options: PtyHistoryCaptureOptions): PtyHistoryCapture | null;
56
+ resolveTranscriptSource?(sessionId: string): PtyTranscriptSource | null;
57
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=PtyAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PtyAdapter.js","sourceRoot":"","sources":["../../../src/server/terminal/PtyAdapter.ts"],"names":[],"mappings":""}
@@ -0,0 +1,74 @@
1
+ import type { AppConfig } from '../config.js';
2
+ import type { ServerTerminalMessage, TerminalHistoryCursor, TerminalHistoryResponse, TerminalTranscriptHistoryResponse, TerminalTranscriptSourceResponse } from '../../shared/protocol.js';
3
+ import type { TerminalId, TerminalSummary } from '../../shared/types.js';
4
+ import type { PtyAdapter } from './PtyAdapter.js';
5
+ export interface CreateTerminalOptions {
6
+ parentTerminalId?: TerminalId;
7
+ cwd?: string;
8
+ cols?: number;
9
+ rows?: number;
10
+ }
11
+ export interface AttachTerminalOptions {
12
+ replay?: boolean;
13
+ }
14
+ export interface TerminalAttachment {
15
+ terminal: TerminalSummary;
16
+ output: string[];
17
+ history: TerminalHistoryCursor | null;
18
+ pause(): void;
19
+ resume(): void;
20
+ dispose(): void;
21
+ }
22
+ export interface TerminalManagerOptions {
23
+ resolveCwd?: (pid: number) => Promise<string | null>;
24
+ now?: () => Date;
25
+ }
26
+ type TerminalSubscriber = (message: ServerTerminalMessage) => void;
27
+ export declare class TerminalManager {
28
+ private readonly config;
29
+ private readonly ptyAdapter;
30
+ private readonly terminals;
31
+ private readonly resolveCwd;
32
+ private readonly now;
33
+ private readonly shellBasename;
34
+ private statusPollTimer;
35
+ private statusPollInflight;
36
+ constructor(config: AppConfig, ptyAdapter: PtyAdapter, options?: TerminalManagerOptions);
37
+ private startStatusPoller;
38
+ private pollOnce;
39
+ dispose(): void;
40
+ createTerminal(options?: CreateTerminalOptions): Promise<TerminalSummary>;
41
+ restoreSessions(): Promise<void>;
42
+ private wireUpPty;
43
+ private reattachToSession;
44
+ private captureTerminalHistoryCursor;
45
+ listTerminals(): TerminalSummary[];
46
+ getTerminal(id: TerminalId): TerminalSummary | null;
47
+ getOutputSnapshot(id: TerminalId): string[] | null;
48
+ getTerminalHistory(id: TerminalId, options?: {
49
+ beforeLine?: number;
50
+ limit?: number;
51
+ }): TerminalHistoryResponse | null;
52
+ getTerminalTranscriptHistory(id: TerminalId, options?: {
53
+ cursor?: string;
54
+ limit?: number;
55
+ }): TerminalTranscriptHistoryResponse | null;
56
+ getTerminalTranscriptSource(id: TerminalId): TerminalTranscriptSourceResponse | null;
57
+ resolveTerminalCwd(id: TerminalId): Promise<string | null>;
58
+ renameTerminal(id: TerminalId, title: string): TerminalSummary | null;
59
+ refreshTerminalCwd(id: TerminalId): Promise<TerminalSummary | null>;
60
+ attachTerminal(id: TerminalId, subscriber: TerminalSubscriber, options?: AttachTerminalOptions): TerminalAttachment | null;
61
+ writeToTerminal(id: TerminalId, data: string): boolean;
62
+ resizeTerminal(id: TerminalId, cols: number, rows: number): boolean;
63
+ closeTerminal(id: TerminalId): boolean;
64
+ closeAll(): void;
65
+ private ensureAttached;
66
+ private resolveInitialCwd;
67
+ private safeResolveCwd;
68
+ private refreshCwd;
69
+ private publish;
70
+ private disposeRecord;
71
+ private createTitle;
72
+ private timestamp;
73
+ }
74
+ export {};