agl 1.0.17 → 21.0.2

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 (277) hide show
  1. package/.smartconfig.json +55 -0
  2. package/changelog.md +1026 -0
  3. package/cli.js +14 -0
  4. package/dist_serve/bundle.js +44778 -0
  5. package/dist_serve/index.html +13 -0
  6. package/dist_ts/00_commitinfo_data.d.ts +8 -0
  7. package/dist_ts/00_commitinfo_data.js +9 -0
  8. package/dist_ts/classes.authmodels.d.ts +126 -0
  9. package/dist_ts/classes.authmodels.js +1422 -0
  10. package/dist_ts/classes.authstore.d.ts +160 -0
  11. package/dist_ts/classes.authstore.js +2483 -0
  12. package/dist_ts/classes.browserresourcehost.d.ts +85 -0
  13. package/dist_ts/classes.browserresourcehost.js +912 -0
  14. package/dist_ts/classes.cli.d.ts +21 -0
  15. package/dist_ts/classes.cli.js +1082 -0
  16. package/dist_ts/classes.config.d.ts +23 -0
  17. package/dist_ts/classes.config.js +267 -0
  18. package/dist_ts/classes.controller.d.ts +523 -0
  19. package/dist_ts/classes.controller.js +10611 -0
  20. package/dist_ts/classes.controllermanagement.d.ts +32 -0
  21. package/dist_ts/classes.controllermanagement.js +222 -0
  22. package/dist_ts/classes.draftmanager.d.ts +30 -0
  23. package/dist_ts/classes.draftmanager.js +179 -0
  24. package/dist_ts/classes.embeddeddb.d.ts +30 -0
  25. package/dist_ts/classes.embeddeddb.js +159 -0
  26. package/dist_ts/classes.flexframedtransport.d.ts +56 -0
  27. package/dist_ts/classes.flexframedtransport.js +275 -0
  28. package/dist_ts/classes.flexmodels.private.d.ts +231 -0
  29. package/dist_ts/classes.flexmodels.private.js +985 -0
  30. package/dist_ts/classes.flexmodels.public.d.ts +207 -0
  31. package/dist_ts/classes.flexmodels.public.js +885 -0
  32. package/dist_ts/classes.flexprojectionreader.d.ts +89 -0
  33. package/dist_ts/classes.flexprojectionreader.js +580 -0
  34. package/dist_ts/classes.flexservice.d.ts +196 -0
  35. package/dist_ts/classes.flexservice.js +3704 -0
  36. package/dist_ts/classes.flexstore.d.ts +174 -0
  37. package/dist_ts/classes.flexstore.js +3400 -0
  38. package/dist_ts/classes.flexsupervisor.d.ts +105 -0
  39. package/dist_ts/classes.flexsupervisor.js +1191 -0
  40. package/dist_ts/classes.gitreversion.d.ts +431 -0
  41. package/dist_ts/classes.gitreversion.js +10592 -0
  42. package/dist_ts/classes.harnessoperationmanager.d.ts +113 -0
  43. package/dist_ts/classes.harnessoperationmanager.js +602 -0
  44. package/dist_ts/classes.opencodeclient.d.ts +146 -0
  45. package/dist_ts/classes.opencodeclient.js +3003 -0
  46. package/dist_ts/classes.opencodesupervisor.d.ts +60 -0
  47. package/dist_ts/classes.opencodesupervisor.js +1003 -0
  48. package/dist_ts/classes.passkeymanager.d.ts +34 -0
  49. package/dist_ts/classes.passkeymanager.js +456 -0
  50. package/dist_ts/classes.processinspection.d.ts +50 -0
  51. package/dist_ts/classes.processinspection.js +484 -0
  52. package/dist_ts/classes.resourcecoordinator.d.ts +64 -0
  53. package/dist_ts/classes.resourcecoordinator.js +294 -0
  54. package/dist_ts/classes.sessionintelligencereader.d.ts +13 -0
  55. package/dist_ts/classes.sessionintelligencereader.js +40 -0
  56. package/dist_ts/classes.systemmetricssampler.d.ts +53 -0
  57. package/dist_ts/classes.systemmetricssampler.js +168 -0
  58. package/dist_ts/classes.terminalmanager.d.ts +95 -0
  59. package/dist_ts/classes.terminalmanager.js +981 -0
  60. package/dist_ts/classes.terminalresourcehost.d.ts +20 -0
  61. package/dist_ts/classes.terminalresourcehost.js +84 -0
  62. package/dist_ts/classes.upgradecoordinator.d.ts +244 -0
  63. package/dist_ts/classes.upgradecoordinator.js +2155 -0
  64. package/dist_ts/classes.upgradetransaction.d.ts +92 -0
  65. package/dist_ts/classes.upgradetransaction.js +2125 -0
  66. package/dist_ts/classes.uploadmanager.d.ts +24 -0
  67. package/dist_ts/classes.uploadmanager.js +210 -0
  68. package/dist_ts/classes.validation.d.ts +91 -0
  69. package/dist_ts/classes.validation.js +1087 -0
  70. package/dist_ts/flexharness.child.d.ts +1 -0
  71. package/dist_ts/flexharness.child.js +28 -0
  72. package/dist_ts/functions.canonicaldirectory.d.ts +21 -0
  73. package/dist_ts/functions.canonicaldirectory.js +144 -0
  74. package/dist_ts/functions.controllerdataroot.d.ts +15 -0
  75. package/dist_ts/functions.controllerdataroot.js +76 -0
  76. package/dist_ts/functions.embeddeddb.d.ts +2 -0
  77. package/dist_ts/functions.embeddeddb.js +21 -0
  78. package/dist_ts/functions.flexcredentialstore.d.ts +16 -0
  79. package/dist_ts/functions.flexcredentialstore.js +93 -0
  80. package/dist_ts/functions.opencodeauth.d.ts +3 -0
  81. package/dist_ts/functions.opencodeauth.js +31 -0
  82. package/dist_ts/functions.runtimeenvironment.d.ts +2 -0
  83. package/dist_ts/functions.runtimeenvironment.js +79 -0
  84. package/dist_ts/functions.upgradefollower.d.ts +3 -0
  85. package/dist_ts/functions.upgradefollower.js +95 -0
  86. package/dist_ts/index.d.ts +24 -0
  87. package/dist_ts/index.js +25 -0
  88. package/dist_ts/interfaces.auth.d.ts +181 -0
  89. package/dist_ts/interfaces.auth.js +82 -0
  90. package/dist_ts/interfaces.config.d.ts +34 -0
  91. package/dist_ts/interfaces.config.js +2 -0
  92. package/dist_ts/interfaces.flexipc.d.ts +939 -0
  93. package/dist_ts/interfaces.flexipc.js +1492 -0
  94. package/dist_ts/interfaces.gitreversion.d.ts +246 -0
  95. package/dist_ts/interfaces.gitreversion.js +2 -0
  96. package/dist_ts/interfaces.lifecycle.d.ts +37 -0
  97. package/dist_ts/interfaces.lifecycle.js +2 -0
  98. package/dist_ts/interfaces.opencode.d.ts +101 -0
  99. package/dist_ts/interfaces.opencode.js +3 -0
  100. package/dist_ts/interfaces.projects.d.ts +156 -0
  101. package/dist_ts/interfaces.projects.js +5 -0
  102. package/dist_ts/plugins.d.ts +36 -0
  103. package/dist_ts/plugins.js +40 -0
  104. package/dist_ts_interfaces/index.d.ts +2 -0
  105. package/dist_ts_interfaces/index.js +3 -0
  106. package/dist_ts_interfaces/interfaces.d.ts +747 -0
  107. package/dist_ts_interfaces/interfaces.js +47 -0
  108. package/dist_ts_interfaces/plugins.d.ts +4 -0
  109. package/dist_ts_interfaces/plugins.js +3 -0
  110. package/dist_ts_interfaces/requests.d.ts +806 -0
  111. package/dist_ts_interfaces/requests.js +2 -0
  112. package/dist_ts_migration/classes.documentmigrationrunner.d.ts +8 -0
  113. package/dist_ts_migration/classes.documentmigrationrunner.js +24 -0
  114. package/dist_ts_migration/classes.flexmigrationrunner.d.ts +11 -0
  115. package/dist_ts_migration/classes.flexmigrationrunner.js +25 -0
  116. package/dist_ts_migration/classes.flexpostharnessmigrationrunner.d.ts +10 -0
  117. package/dist_ts_migration/classes.flexpostharnessmigrationrunner.js +15 -0
  118. package/dist_ts_migration/classes.migrationrunner.d.ts +8 -0
  119. package/dist_ts_migration/classes.migrationrunner.js +34 -0
  120. package/dist_ts_migration/index.d.ts +12 -0
  121. package/dist_ts_migration/index.js +13 -0
  122. package/dist_ts_migration/v10_flexharnessv3migration.d.ts +11 -0
  123. package/dist_ts_migration/v10_flexharnessv3migration.js +23 -0
  124. package/dist_ts_migration/v13_flexprojectionorder.d.ts +11 -0
  125. package/dist_ts_migration/v13_flexprojectionorder.js +23 -0
  126. package/dist_ts_migration/v16_flexprovidercredentials.d.ts +22 -0
  127. package/dist_ts_migration/v16_flexprovidercredentials.js +149 -0
  128. package/dist_ts_migration/v18_resourcelayout.d.ts +22 -0
  129. package/dist_ts_migration/v18_resourcelayout.js +23 -0
  130. package/dist_ts_migration/v18_resourcelayoutmigration.d.ts +6 -0
  131. package/dist_ts_migration/v18_resourcelayoutmigration.js +61 -0
  132. package/dist_ts_migration/v19_flexprojectmanagement.d.ts +11 -0
  133. package/dist_ts_migration/v19_flexprojectmanagement.js +21 -0
  134. package/dist_ts_migration/v1_embeddeddatabaselocation.d.ts +28 -0
  135. package/dist_ts_migration/v1_embeddeddatabaselocation.js +415 -0
  136. package/dist_ts_migration/v22_projectfilesystemidentitymigration.d.ts +7 -0
  137. package/dist_ts_migration/v22_projectfilesystemidentitymigration.js +105 -0
  138. package/dist_ts_migration/v2_controllerdataroot.d.ts +130 -0
  139. package/dist_ts_migration/v2_controllerdataroot.js +1887 -0
  140. package/dist_ts_migration/v6_protocoldocumentmigration.d.ts +7 -0
  141. package/dist_ts_migration/v6_protocoldocumentmigration.js +100 -0
  142. package/dist_ts_migration/v6_protocoldocuments.d.ts +7 -0
  143. package/dist_ts_migration/v6_protocoldocuments.js +138 -0
  144. package/html/index.html +13 -0
  145. package/{LICENSE → license.md} +2 -2
  146. package/package.json +86 -48
  147. package/readme.md +480 -0
  148. package/readme.plan.md +188 -0
  149. package/ts/00_commitinfo_data.ts +8 -0
  150. package/ts/classes.authmodels.ts +1245 -0
  151. package/ts/classes.authstore.ts +3274 -0
  152. package/ts/classes.browserresourcehost.ts +1205 -0
  153. package/ts/classes.cli.ts +1254 -0
  154. package/ts/classes.config.ts +351 -0
  155. package/ts/classes.controller.ts +14426 -0
  156. package/ts/classes.controllermanagement.ts +330 -0
  157. package/ts/classes.draftmanager.ts +232 -0
  158. package/ts/classes.embeddeddb.ts +166 -0
  159. package/ts/classes.flexframedtransport.ts +283 -0
  160. package/ts/classes.flexmodels.private.ts +823 -0
  161. package/ts/classes.flexmodels.public.ts +732 -0
  162. package/ts/classes.flexprojectionreader.ts +816 -0
  163. package/ts/classes.flexservice.ts +4302 -0
  164. package/ts/classes.flexstore.ts +4565 -0
  165. package/ts/classes.flexsupervisor.ts +1453 -0
  166. package/ts/classes.gitreversion.ts +13353 -0
  167. package/ts/classes.harnessoperationmanager.ts +870 -0
  168. package/ts/classes.opencodeclient.ts +4110 -0
  169. package/ts/classes.opencodesupervisor.ts +1280 -0
  170. package/ts/classes.passkeymanager.ts +570 -0
  171. package/ts/classes.processinspection.ts +623 -0
  172. package/ts/classes.resourcecoordinator.ts +436 -0
  173. package/ts/classes.sessionintelligencereader.ts +52 -0
  174. package/ts/classes.systemmetricssampler.ts +215 -0
  175. package/ts/classes.terminalmanager.ts +1207 -0
  176. package/ts/classes.terminalresourcehost.ts +122 -0
  177. package/ts/classes.upgradecoordinator.ts +2675 -0
  178. package/ts/classes.upgradetransaction.ts +2900 -0
  179. package/ts/classes.uploadmanager.ts +240 -0
  180. package/ts/classes.validation.ts +1409 -0
  181. package/ts/flexharness.child.ts +35 -0
  182. package/ts/functions.canonicaldirectory.ts +213 -0
  183. package/ts/functions.controllerdataroot.ts +107 -0
  184. package/ts/functions.embeddeddb.ts +22 -0
  185. package/ts/functions.flexcredentialstore.ts +128 -0
  186. package/ts/functions.opencodeauth.ts +34 -0
  187. package/ts/functions.runtimeenvironment.ts +90 -0
  188. package/ts/functions.upgradefollower.ts +115 -0
  189. package/ts/index.ts +36 -6
  190. package/ts/interfaces.auth.ts +316 -0
  191. package/ts/interfaces.config.ts +37 -0
  192. package/ts/interfaces.flexipc.ts +2586 -0
  193. package/ts/interfaces.gitreversion.ts +336 -0
  194. package/ts/interfaces.lifecycle.ts +46 -0
  195. package/ts/interfaces.opencode.ts +153 -0
  196. package/ts/interfaces.projects.ts +182 -0
  197. package/ts/plugins.ts +64 -0
  198. package/ts_interfaces/index.ts +2 -0
  199. package/ts_interfaces/interfaces.ts +827 -0
  200. package/ts_interfaces/plugins.ts +15 -0
  201. package/ts_interfaces/requests.ts +1186 -0
  202. package/ts_migration/classes.documentmigrationrunner.ts +32 -0
  203. package/ts_migration/classes.flexmigrationrunner.ts +33 -0
  204. package/ts_migration/classes.flexpostharnessmigrationrunner.ts +22 -0
  205. package/ts_migration/classes.migrationrunner.ts +40 -0
  206. package/ts_migration/index.ts +12 -0
  207. package/ts_migration/v10_flexharnessv3migration.ts +35 -0
  208. package/ts_migration/v13_flexprojectionorder.ts +33 -0
  209. package/ts_migration/v16_flexprovidercredentials.ts +196 -0
  210. package/ts_migration/v18_resourcelayout.ts +55 -0
  211. package/ts_migration/v18_resourcelayoutmigration.ts +68 -0
  212. package/ts_migration/v19_flexprojectmanagement.ts +28 -0
  213. package/ts_migration/v1_embeddeddatabaselocation.ts +560 -0
  214. package/ts_migration/v22_projectfilesystemidentitymigration.ts +121 -0
  215. package/ts_migration/v2_controllerdataroot.ts +2349 -0
  216. package/ts_migration/v6_protocoldocumentmigration.ts +144 -0
  217. package/ts_migration/v6_protocoldocuments.ts +198 -0
  218. package/ts_web/00_commitinfo_data.ts +8 -0
  219. package/ts_web/classes.controllersocketclient.ts +517 -0
  220. package/ts_web/classes.sessiondraftsync.ts +390 -0
  221. package/ts_web/elements.harnesscontrollerapp.ts +11494 -0
  222. package/ts_web/index.ts +2 -0
  223. package/ts_web/plugins.ts +31 -0
  224. package/.gitlab-ci.yml +0 -71
  225. package/.npmignore +0 -5
  226. package/README.md +0 -40
  227. package/dist/cli.js +0 -2
  228. package/dist/index.d.ts +0 -0
  229. package/dist/index.js +0 -9
  230. package/dist/mod_bundle/index.d.ts +0 -1
  231. package/dist/mod_bundle/index.js +0 -18
  232. package/dist/mod_bundle/mod.plugins.d.ts +0 -4
  233. package/dist/mod_bundle/mod.plugins.js +0 -11
  234. package/dist/mod_install/index.d.ts +0 -4
  235. package/dist/mod_install/index.js +0 -21
  236. package/dist/mod_install/mod.plugins.d.ts +0 -1
  237. package/dist/mod_install/mod.plugins.js +0 -7
  238. package/dist/mod_standard/index.d.ts +0 -4
  239. package/dist/mod_standard/index.js +0 -21
  240. package/dist/mod_standard/mod.browser.d.ts +0 -6
  241. package/dist/mod_standard/mod.browser.js +0 -14
  242. package/dist/mod_standard/mod.clean.d.ts +0 -4
  243. package/dist/mod_standard/mod.clean.js +0 -12
  244. package/dist/mod_standard/mod.compile.d.ts +0 -4
  245. package/dist/mod_standard/mod.compile.js +0 -21
  246. package/dist/mod_standard/mod.plugins.d.ts +0 -8
  247. package/dist/mod_standard/mod.plugins.js +0 -19
  248. package/dist/mod_standard/mod.test.d.ts +0 -4
  249. package/dist/mod_standard/mod.test.js +0 -12
  250. package/dist/plr.cli.d.ts +0 -3
  251. package/dist/plr.cli.js +0 -57
  252. package/dist/plr.config.d.ts +0 -11
  253. package/dist/plr.config.js +0 -26
  254. package/dist/plr.mods.d.ts +0 -17
  255. package/dist/plr.mods.js +0 -17
  256. package/dist/plr.paths.d.ts +0 -19
  257. package/dist/plr.paths.js +0 -26
  258. package/dist/plr.plugins.d.ts +0 -8
  259. package/dist/plr.plugins.js +0 -16
  260. package/npmextra.json +0 -10
  261. package/ts/mod_bundle/index.ts +0 -20
  262. package/ts/mod_bundle/mod.plugins.ts +0 -9
  263. package/ts/mod_install/index.ts +0 -20
  264. package/ts/mod_install/mod.plugins.ts +0 -1
  265. package/ts/mod_standard/index.ts +0 -23
  266. package/ts/mod_standard/mod.browser.ts +0 -17
  267. package/ts/mod_standard/mod.clean.ts +0 -13
  268. package/ts/mod_standard/mod.compile.ts +0 -23
  269. package/ts/mod_standard/mod.plugins.ts +0 -17
  270. package/ts/mod_standard/mod.test.ts +0 -13
  271. package/ts/plr.cli.ts +0 -60
  272. package/ts/plr.config.ts +0 -36
  273. package/ts/plr.mods.ts +0 -25
  274. package/ts/plr.paths.ts +0 -29
  275. package/ts/plr.plugins.ts +0 -17
  276. package/tslint.json +0 -3
  277. package/yarn.lock +0 -3464
@@ -0,0 +1,981 @@
1
+ import * as plugins from './plugins.js';
2
+ import { createSanitizedRuntimeEnvironment } from './functions.runtimeenvironment.js';
3
+ const maxTerminals = 32;
4
+ const maxTerminalsPerProject = 8;
5
+ const maxScrollbackBytes = 2 * 1024 * 1024;
6
+ const maxPtyCaptureBytes = 4 * 1024 * 1024;
7
+ const maxInputBytes = 8 * 1024;
8
+ const maxOutputFrameBytes = 64 * 1024;
9
+ const maxPeersPerTerminal = 32;
10
+ const maxPendingControlOperations = 256;
11
+ const defaultCleanupTimeoutMs = 10_000;
12
+ const normalizeError = (errorArg) => errorArg instanceof Error ? errorArg : new Error(String(errorArg));
13
+ const toTerminalDto = (terminalArg) => ({
14
+ ...terminalArg,
15
+ id: { ...terminalArg.id },
16
+ });
17
+ const appendBoundedChunk = (slabsArg, currentBytesArg, chunkArg) => {
18
+ if (chunkArg.byteLength === 0)
19
+ return currentBytesArg;
20
+ let sourceOffset = 0;
21
+ let currentBytes = currentBytesArg;
22
+ if (chunkArg.byteLength >= maxScrollbackBytes) {
23
+ slabsArg.splice(0, slabsArg.length);
24
+ sourceOffset = chunkArg.byteLength - maxScrollbackBytes;
25
+ currentBytes = 0;
26
+ }
27
+ while (sourceOffset < chunkArg.byteLength) {
28
+ let slab = slabsArg.at(-1);
29
+ if (!slab || slab.end >= slab.buffer.byteLength) {
30
+ slab = {
31
+ buffer: Buffer.allocUnsafe(maxOutputFrameBytes),
32
+ start: 0,
33
+ end: 0,
34
+ };
35
+ slabsArg.push(slab);
36
+ }
37
+ const copyBytes = Math.min(chunkArg.byteLength - sourceOffset, slab.buffer.byteLength - slab.end);
38
+ chunkArg.copy(slab.buffer, slab.end, sourceOffset, sourceOffset + copyBytes);
39
+ slab.end += copyBytes;
40
+ sourceOffset += copyBytes;
41
+ currentBytes += copyBytes;
42
+ }
43
+ let excess = currentBytes - maxScrollbackBytes;
44
+ while (excess > 0) {
45
+ const first = slabsArg[0];
46
+ const firstBytes = first.end - first.start;
47
+ if (firstBytes <= excess) {
48
+ slabsArg.shift();
49
+ currentBytes -= firstBytes;
50
+ excess -= firstBytes;
51
+ }
52
+ else {
53
+ first.start += excess;
54
+ currentBytes -= excess;
55
+ excess = 0;
56
+ }
57
+ }
58
+ return currentBytes;
59
+ };
60
+ const appendOutput = (outputArg, chunkArg) => {
61
+ if (chunkArg.byteLength === 0)
62
+ return;
63
+ outputArg.end += chunkArg.byteLength;
64
+ outputArg.bytes = appendBoundedChunk(outputArg.slabs, outputArg.bytes, chunkArg);
65
+ outputArg.start = outputArg.end - outputArg.bytes;
66
+ };
67
+ const validateExecutable = async (candidateArg, platformArg) => {
68
+ const pathApi = platformArg === 'win32' ? plugins.path.win32 : plugins.path.posix;
69
+ if (!pathApi.isAbsolute(candidateArg)) {
70
+ throw new Error('The terminal shell executable must be an absolute path.');
71
+ }
72
+ const executable = await plugins.fs.promises.realpath(candidateArg);
73
+ const stats = await plugins.fs.promises.stat(executable);
74
+ if (!stats.isFile())
75
+ throw new Error('The terminal shell executable is not a file.');
76
+ if (platformArg !== 'win32') {
77
+ await plugins.fs.promises.access(executable, plugins.fs.constants.X_OK);
78
+ }
79
+ return executable;
80
+ };
81
+ export const resolveControllerTerminalShell = async (environmentArg = process.env, platformArg = process.platform, validateExecutableArg = validateExecutable) => {
82
+ const environment = createSanitizedRuntimeEnvironment(environmentArg);
83
+ if (platformArg === 'win32') {
84
+ const candidates = [];
85
+ if (environmentArg.COMSPEC && plugins.path.win32.isAbsolute(environmentArg.COMSPEC)) {
86
+ candidates.push(environmentArg.COMSPEC);
87
+ }
88
+ const systemRoot = environmentArg.SystemRoot ?? environmentArg.SYSTEMROOT;
89
+ if (systemRoot && plugins.path.win32.isAbsolute(systemRoot)) {
90
+ candidates.push(plugins.path.win32.join(systemRoot, 'System32', 'cmd.exe'));
91
+ }
92
+ for (const candidate of [...new Set(candidates)]) {
93
+ try {
94
+ const executable = await validateExecutableArg(candidate, platformArg);
95
+ delete environment.SHELL;
96
+ environment.COMSPEC = executable;
97
+ return { executable, args: [], environment };
98
+ }
99
+ catch {
100
+ // Try the trusted SystemRoot fallback before failing closed.
101
+ }
102
+ }
103
+ throw new Error('No trusted Windows terminal shell executable is available.');
104
+ }
105
+ const candidates = [
106
+ ...(environmentArg.SHELL && plugins.path.posix.isAbsolute(environmentArg.SHELL)
107
+ ? [environmentArg.SHELL]
108
+ : []),
109
+ '/bin/sh',
110
+ ];
111
+ for (const candidate of [...new Set(candidates)]) {
112
+ try {
113
+ const executable = await validateExecutableArg(candidate, platformArg);
114
+ delete environment.COMSPEC;
115
+ environment.SHELL = executable;
116
+ return { executable, args: [], environment };
117
+ }
118
+ catch {
119
+ // Fall through to /bin/sh, then fail closed.
120
+ }
121
+ }
122
+ throw new Error('No trusted POSIX terminal shell executable is available.');
123
+ };
124
+ const waitUntil = async (promiseArg, deadlineAtArg) => {
125
+ const remainingMs = deadlineAtArg - Date.now();
126
+ if (remainingMs <= 0)
127
+ throw new Error('Terminal cleanup exceeded its deadline.');
128
+ let timeout;
129
+ try {
130
+ await Promise.race([
131
+ promiseArg,
132
+ new Promise((_resolve, reject) => {
133
+ timeout = setTimeout(() => reject(new Error('Terminal cleanup exceeded its deadline.')), remainingMs);
134
+ }),
135
+ ]);
136
+ }
137
+ finally {
138
+ if (timeout)
139
+ clearTimeout(timeout);
140
+ }
141
+ };
142
+ export class ControllerTerminalManager {
143
+ options;
144
+ ptySpawner;
145
+ resolveShell;
146
+ cleanupTimeoutMs;
147
+ entries = new Map();
148
+ projectStates = new Map();
149
+ activeRetirements = new Set();
150
+ pendingRemovalCleanups = new Map();
151
+ state = 'new';
152
+ shell;
153
+ initPromise;
154
+ closePromise;
155
+ pendingCreates = 0;
156
+ pendingCreatesByProject = new Map();
157
+ peerGeneration = 0;
158
+ constructor(options) {
159
+ this.options = options;
160
+ this.ptySpawner = options.ptySpawner ?? new plugins.smartshell.Smartshell({
161
+ executor: 'sh',
162
+ sourceFilePaths: [],
163
+ });
164
+ this.resolveShell = options.resolveShell ?? (() => resolveControllerTerminalShell());
165
+ this.cleanupTimeoutMs = options.cleanupTimeoutMs ?? defaultCleanupTimeoutMs;
166
+ if (!Number.isSafeInteger(this.cleanupTimeoutMs)
167
+ || this.cleanupTimeoutMs < 1
168
+ || this.cleanupTimeoutMs > 60_000) {
169
+ throw new Error('cleanupTimeoutMs must be an integer between 1 and 60000.');
170
+ }
171
+ }
172
+ async init() {
173
+ if (this.state === 'open')
174
+ return;
175
+ if (this.initPromise)
176
+ return this.initPromise;
177
+ if (this.state !== 'new')
178
+ throw new Error('The terminal manager cannot be initialized now.');
179
+ const initPromise = (async () => {
180
+ const [shell] = await Promise.all([
181
+ this.resolveShell(),
182
+ this.ptySpawner.ensurePtySupport(),
183
+ ]);
184
+ if (this.state !== 'new')
185
+ throw new Error('Terminal manager initialization was cancelled.');
186
+ this.shell = shell;
187
+ this.state = 'open';
188
+ })();
189
+ this.initPromise = initPromise;
190
+ try {
191
+ await initPromise;
192
+ }
193
+ finally {
194
+ if (this.initPromise === initPromise)
195
+ this.initPromise = undefined;
196
+ }
197
+ }
198
+ async listTerminals(projectIdArg) {
199
+ return this.runProjectOperation(projectIdArg, async () => {
200
+ await this.options.resolveProjectDirectory(projectIdArg);
201
+ return [...this.entries.values()]
202
+ .filter((entry) => entry.projectId === projectIdArg && entry.finalState !== 'exited')
203
+ .map((entry) => toTerminalDto(entry.terminal));
204
+ });
205
+ }
206
+ async createTerminal(projectIdArg, titleArg) {
207
+ return this.runProjectOperation(projectIdArg, async () => {
208
+ this.reserveCreate(projectIdArg);
209
+ try {
210
+ const directory = await this.options.resolveProjectDirectory(projectIdArg);
211
+ const shell = this.requireShell();
212
+ const terminalNativeId = this.createTerminalId();
213
+ return this.spawnTerminal({
214
+ projectId: projectIdArg,
215
+ terminalNativeId,
216
+ title: titleArg ?? plugins.path.basename(shell.executable),
217
+ command: shell.executable,
218
+ args: [...shell.args],
219
+ cwd: directory,
220
+ environment: { ...shell.environment },
221
+ });
222
+ }
223
+ finally {
224
+ this.releaseCreate(projectIdArg);
225
+ }
226
+ });
227
+ }
228
+ async resolveTerminalResourceMetadata(projectIdArg, titleArg) {
229
+ const directory = await this.options.resolveProjectDirectory(projectIdArg);
230
+ const shell = this.requireShell();
231
+ return {
232
+ title: titleArg ?? plugins.path.basename(shell.executable),
233
+ terminal: {
234
+ command: shell.executable,
235
+ args: [...shell.args],
236
+ cwd: directory,
237
+ stoppedAt: new Date(),
238
+ },
239
+ };
240
+ }
241
+ async startTerminalResource(resourceArg) {
242
+ if (resourceArg.kind !== 'terminal' || !resourceArg.terminal) {
243
+ throw new Error('The resource is not a terminal.');
244
+ }
245
+ const terminal = resourceArg.terminal;
246
+ return this.runProjectOperation(resourceArg.projectId, async () => {
247
+ this.reserveCreate(resourceArg.projectId);
248
+ try {
249
+ if (this.entries.has(resourceArg.id)) {
250
+ throw new Error('The terminal resource is already running.');
251
+ }
252
+ const directory = await this.options.resolveProjectDirectory(resourceArg.projectId);
253
+ if (directory !== terminal.cwd) {
254
+ throw new Error('The terminal resource project directory binding changed.');
255
+ }
256
+ const shell = this.requireShell();
257
+ return this.spawnTerminal({
258
+ projectId: resourceArg.projectId,
259
+ terminalNativeId: resourceArg.id,
260
+ title: resourceArg.title,
261
+ command: terminal.command,
262
+ args: [...terminal.args],
263
+ cwd: directory,
264
+ environment: { ...shell.environment },
265
+ });
266
+ }
267
+ finally {
268
+ this.releaseCreate(resourceArg.projectId);
269
+ }
270
+ });
271
+ }
272
+ async stopTerminalResource(projectIdArg, resourceIdArg) {
273
+ const entry = this.entries.get(resourceIdArg);
274
+ if (!entry || entry.projectId !== projectIdArg)
275
+ return;
276
+ await this.runProjectOperation(projectIdArg, async () => {
277
+ await this.closeEntry(entry, Date.now() + this.cleanupTimeoutMs);
278
+ });
279
+ }
280
+ isTerminalRunning(projectIdArg, resourceIdArg) {
281
+ const entry = this.entries.get(resourceIdArg);
282
+ return entry?.projectId === projectIdArg && entry.finalState === 'running';
283
+ }
284
+ async spawnTerminal(inputArg) {
285
+ let entry;
286
+ const output = {
287
+ slabs: [],
288
+ start: 0,
289
+ end: 0,
290
+ bytes: 0,
291
+ };
292
+ const execution = await this.ptySpawner.execSpawnStreamingInteractiveControlPty(inputArg.command, [...inputArg.args], {
293
+ cwd: inputArg.cwd,
294
+ env: { ...inputArg.environment },
295
+ maxBuffer: maxPtyCaptureBytes,
296
+ ptyCols: 120,
297
+ ptyRows: 30,
298
+ ptyTerm: 'xterm-256color',
299
+ onData: (chunkArg) => {
300
+ const chunk = Buffer.from(chunkArg, 'utf8');
301
+ if (entry)
302
+ this.appendOutput(entry, chunk);
303
+ else
304
+ appendOutput(output, chunk);
305
+ },
306
+ });
307
+ let resolveRootExit;
308
+ const rootExitPromise = new Promise((resolve) => {
309
+ resolveRootExit = resolve;
310
+ });
311
+ const createdEntry = {
312
+ projectId: inputArg.projectId,
313
+ terminal: {
314
+ id: { harnessId: 'controller', nativeId: inputArg.terminalNativeId },
315
+ title: inputArg.title,
316
+ command: inputArg.command,
317
+ cwd: inputArg.cwd,
318
+ },
319
+ execution,
320
+ peers: new Map(),
321
+ sizesByPeer: new Map(),
322
+ output,
323
+ controlQueue: Promise.resolve(),
324
+ pendingControlOperations: 0,
325
+ sizeRevision: 0,
326
+ sizeReconciliationActive: false,
327
+ closing: false,
328
+ finalState: 'running',
329
+ rootExitPromise,
330
+ resolveRootExit,
331
+ };
332
+ entry = createdEntry;
333
+ this.entries.set(inputArg.terminalNativeId, createdEntry);
334
+ createdEntry.exitSubscription = execution.ptyProcess.onExit((eventArg) => this.confirmRootExit(createdEntry, eventArg.exitCode));
335
+ if (createdEntry.finalState === 'exited')
336
+ createdEntry.exitSubscription.dispose();
337
+ void execution.finalPromise.then((resultArg) => this.confirmRootExit(createdEntry, resultArg.exitCode), (errorArg) => {
338
+ if (createdEntry.finalState === 'running')
339
+ createdEntry.finalState = 'failed-unconfirmed';
340
+ createdEntry.finalError = normalizeError(errorArg);
341
+ });
342
+ if (createdEntry.finalState === 'exited' || this.state !== 'open') {
343
+ await this.closeEntry(createdEntry, Date.now() + this.cleanupTimeoutMs);
344
+ throw new Error('The terminal exited while it was being created.');
345
+ }
346
+ const projectState = this.projectState(inputArg.projectId);
347
+ if (projectState.retiring || projectState.retired) {
348
+ await this.closeEntry(createdEntry, Date.now() + this.cleanupTimeoutMs);
349
+ throw new Error('The project stopped accepting terminal operations.');
350
+ }
351
+ this.options.onTerminalsChanged(inputArg.projectId);
352
+ return toTerminalDto(createdEntry.terminal);
353
+ }
354
+ async renameTerminal(projectIdArg, terminalIdArg, titleArg) {
355
+ const entry = this.requireEntry(projectIdArg, terminalIdArg);
356
+ return this.runProjectOperation(projectIdArg, () => (this.runEntryControl(entry, async () => {
357
+ this.assertEntryRunning(entry);
358
+ entry.terminal.title = titleArg;
359
+ this.options.onTerminalsChanged(projectIdArg);
360
+ return toTerminalDto(entry.terminal);
361
+ })));
362
+ }
363
+ async renameTerminalResource(projectIdArg, terminalIdArg, titleArg) {
364
+ const entry = this.entries.get(terminalIdArg);
365
+ if (!entry || entry.projectId !== projectIdArg || entry.finalState === 'exited')
366
+ return;
367
+ await this.runProjectOperation(projectIdArg, () => (this.runEntryControl(entry, async () => {
368
+ this.assertEntryRunning(entry);
369
+ entry.terminal.title = titleArg;
370
+ this.options.onTerminalsChanged(projectIdArg);
371
+ })));
372
+ }
373
+ async removeTerminal(projectIdArg, terminalIdArg) {
374
+ const entry = this.entries.get(terminalIdArg);
375
+ return this.runProjectOperation(projectIdArg, async () => {
376
+ if (!entry || entry.projectId !== projectIdArg)
377
+ return false;
378
+ await this.closeEntry(entry, Date.now() + this.cleanupTimeoutMs);
379
+ return true;
380
+ });
381
+ }
382
+ async attach(peerIdArg, projectIdArg, terminalIdArg, isPeerConnectedArg = () => true) {
383
+ const entry = this.requireEntry(projectIdArg, terminalIdArg);
384
+ return this.runProjectOperation(projectIdArg, () => (this.runEntryControl(entry, async () => {
385
+ this.assertEntryRunning(entry);
386
+ if (!isPeerConnectedArg())
387
+ throw new Error('The terminal peer disconnected before attach.');
388
+ const previous = entry.peers.get(peerIdArg);
389
+ if (previous) {
390
+ this.detachPeerState(entry, previous);
391
+ if (previous.deliveryPromise) {
392
+ await waitUntil(previous.deliveryPromise.catch(() => undefined), Date.now() + this.cleanupTimeoutMs).catch(() => undefined);
393
+ }
394
+ await this.applyMinimumSizeUntilStable(entry);
395
+ }
396
+ if (entry.peers.size >= maxPeersPerTerminal) {
397
+ throw new Error(`At most ${maxPeersPerTerminal} peers may attach to one terminal.`);
398
+ }
399
+ const peer = {
400
+ peerId: peerIdArg,
401
+ generation: ++this.peerGeneration,
402
+ cursor: entry.output.start,
403
+ detaching: false,
404
+ finalizing: false,
405
+ };
406
+ entry.peers.set(peerIdArg, peer);
407
+ try {
408
+ await this.schedulePeerDelivery(entry, peer, true);
409
+ if (!isPeerConnectedArg() || entry.peers.get(peerIdArg) !== peer) {
410
+ throw new Error('The terminal peer disconnected during attach.');
411
+ }
412
+ }
413
+ catch (errorArg) {
414
+ this.detachPeerState(entry, peer);
415
+ throw errorArg;
416
+ }
417
+ })));
418
+ }
419
+ async detach(peerIdArg, projectIdArg, terminalIdArg) {
420
+ const entry = this.entries.get(terminalIdArg);
421
+ return this.runProjectOperation(projectIdArg, () => {
422
+ if (!entry || entry.projectId !== projectIdArg)
423
+ return Promise.resolve();
424
+ return this.runEntryControl(entry, async () => {
425
+ const peer = entry.peers.get(peerIdArg);
426
+ if (!peer)
427
+ return;
428
+ this.detachPeerState(entry, peer);
429
+ if (peer.deliveryPromise) {
430
+ await waitUntil(peer.deliveryPromise.catch(() => undefined), Date.now() + this.cleanupTimeoutMs).catch(() => undefined);
431
+ }
432
+ await this.applyMinimumSizeUntilStable(entry);
433
+ });
434
+ });
435
+ }
436
+ async detachPeer(peerIdArg) {
437
+ const reconciliations = [];
438
+ for (const entry of this.entries.values()) {
439
+ const peer = entry.peers.get(peerIdArg);
440
+ if (!peer)
441
+ continue;
442
+ this.detachPeerState(entry, peer);
443
+ reconciliations.push(this.requestSizeReconciliation(entry));
444
+ }
445
+ await Promise.allSettled(reconciliations);
446
+ }
447
+ async input(peerIdArg, projectIdArg, terminalIdArg, dataArg) {
448
+ if (dataArg.byteLength > maxInputBytes) {
449
+ throw new Error('Terminal input exceeds the per-message limit.');
450
+ }
451
+ const entry = this.requireEntry(projectIdArg, terminalIdArg);
452
+ return this.runProjectOperation(projectIdArg, () => (this.runEntryControl(entry, async () => {
453
+ this.assertAttached(entry, peerIdArg);
454
+ await entry.execution.sendInput(dataArg.toString('utf8'));
455
+ })));
456
+ }
457
+ async resize(peerIdArg, projectIdArg, terminalIdArg, rowsArg, colsArg) {
458
+ const entry = this.requireEntry(projectIdArg, terminalIdArg);
459
+ return this.runProjectOperation(projectIdArg, () => (this.runEntryControl(entry, async () => {
460
+ this.assertAttached(entry, peerIdArg);
461
+ entry.sizesByPeer.set(peerIdArg, { rows: rowsArg, cols: colsArg });
462
+ entry.sizeRevision += 1;
463
+ await this.applyMinimumSizeUntilStable(entry);
464
+ })));
465
+ }
466
+ async retireProject(projectIdArg, retireArg) {
467
+ if (this.state !== 'open')
468
+ throw new Error('The terminal manager is not accepting operations.');
469
+ const projectState = this.projectState(projectIdArg);
470
+ if (projectState.retiring || projectState.retired) {
471
+ throw new Error('The project is already leaving terminal admission.');
472
+ }
473
+ projectState.retiring = true;
474
+ const deadlineAt = Date.now() + this.cleanupTimeoutMs;
475
+ const retirementPromise = (async () => {
476
+ await this.closeProjectEntries(projectIdArg, deadlineAt);
477
+ await waitUntil(this.waitForProjectDrain(projectState), deadlineAt);
478
+ await this.closeProjectEntries(projectIdArg, deadlineAt);
479
+ if ([...this.pendingRemovalCleanups.values()].includes(projectIdArg)) {
480
+ await waitUntil(this.waitForRemovalCleanups(projectIdArg), deadlineAt);
481
+ }
482
+ const retired = await retireArg();
483
+ projectState.retired = retired;
484
+ return retired;
485
+ })();
486
+ projectState.retirementPromise = retirementPromise;
487
+ this.activeRetirements.add(retirementPromise);
488
+ try {
489
+ return await retirementPromise;
490
+ }
491
+ finally {
492
+ this.activeRetirements.delete(retirementPromise);
493
+ if (projectState.retirementPromise === retirementPromise) {
494
+ projectState.retirementPromise = undefined;
495
+ }
496
+ projectState.retiring = false;
497
+ this.pruneProjectState(projectIdArg, projectState);
498
+ }
499
+ }
500
+ async closeAll() {
501
+ if (this.state === 'closed')
502
+ return;
503
+ if (this.closePromise)
504
+ return this.closePromise;
505
+ this.state = 'closing';
506
+ const deadlineAt = Date.now() + this.cleanupTimeoutMs;
507
+ const closePromise = (async () => {
508
+ const initialClosures = [...this.entries.values()]
509
+ .map((entry) => this.closeEntry(entry, deadlineAt));
510
+ const coordination = Promise.all([
511
+ Promise.allSettled(initialClosures).then(() => undefined),
512
+ this.waitForAllProjectDrains(),
513
+ Promise.allSettled([...this.activeRetirements]).then(() => undefined),
514
+ ]).then(() => this.waitForRemovalCleanups());
515
+ let coordinationError;
516
+ try {
517
+ await waitUntil(coordination, deadlineAt);
518
+ }
519
+ catch (errorArg) {
520
+ coordinationError = errorArg;
521
+ }
522
+ const finalOutcomes = await Promise.allSettled([...this.entries.values()].map((entry) => this.closeEntry(entry, deadlineAt)));
523
+ let cleanupError;
524
+ if (this.pendingRemovalCleanups.size > 0) {
525
+ try {
526
+ await waitUntil(this.waitForRemovalCleanups(), deadlineAt);
527
+ }
528
+ catch (errorArg) {
529
+ cleanupError = errorArg;
530
+ if (this.entries.size === 0)
531
+ this.pendingRemovalCleanups.clear();
532
+ }
533
+ }
534
+ const activeOperations = [...this.projectStates.values()]
535
+ .reduce((sum, projectState) => sum + projectState.activeOperations, 0);
536
+ const errors = [];
537
+ if (this.entries.size > 0) {
538
+ errors.push(new Error('One or more terminal roots remain unconfirmed.'));
539
+ }
540
+ if (activeOperations > 0) {
541
+ errors.push(new Error('One or more terminal operations remain active.'));
542
+ }
543
+ if (this.activeRetirements.size > 0) {
544
+ errors.push(new Error('One or more project retirements remain active.'));
545
+ }
546
+ if (this.pendingRemovalCleanups.size > 0) {
547
+ errors.push(new Error('One or more terminal layout cleanups remain active.'));
548
+ }
549
+ if (errors.length > 0 && coordinationError)
550
+ errors.push(coordinationError);
551
+ if (errors.length > 0 && cleanupError)
552
+ errors.push(cleanupError);
553
+ if (this.entries.size > 0) {
554
+ errors.push(...finalOutcomes.flatMap((outcome) => (outcome.status === 'rejected' ? [outcome.reason] : [])));
555
+ }
556
+ if (errors.length > 0) {
557
+ throw new AggregateError(errors, 'The terminal manager did not close every PTY.');
558
+ }
559
+ this.state = 'closed';
560
+ })();
561
+ this.closePromise = closePromise;
562
+ try {
563
+ await closePromise;
564
+ }
565
+ finally {
566
+ if (this.closePromise === closePromise)
567
+ this.closePromise = undefined;
568
+ }
569
+ }
570
+ projectState(projectIdArg) {
571
+ let state = this.projectStates.get(projectIdArg);
572
+ if (!state) {
573
+ const newState = {
574
+ activeOperations: 0,
575
+ retiring: false,
576
+ retired: false,
577
+ };
578
+ this.projectStates.set(projectIdArg, newState);
579
+ state = newState;
580
+ }
581
+ return state;
582
+ }
583
+ pruneProjectState(projectIdArg, projectStateArg) {
584
+ if (this.projectStates.get(projectIdArg) === projectStateArg
585
+ && projectStateArg.activeOperations === 0
586
+ && !projectStateArg.retiring
587
+ && !projectStateArg.retirementPromise) {
588
+ this.projectStates.delete(projectIdArg);
589
+ }
590
+ }
591
+ async runProjectOperation(projectIdArg, operationArg) {
592
+ if (this.state !== 'open')
593
+ throw new Error('The terminal manager is not accepting operations.');
594
+ const projectState = this.projectState(projectIdArg);
595
+ if (projectState.retiring || projectState.retired) {
596
+ throw new Error('The project is not accepting terminal operations.');
597
+ }
598
+ if (projectState.activeOperations === 0) {
599
+ let resolveDrain;
600
+ projectState.drainPromise = new Promise((resolve) => {
601
+ resolveDrain = resolve;
602
+ });
603
+ projectState.resolveDrain = resolveDrain;
604
+ }
605
+ projectState.activeOperations += 1;
606
+ try {
607
+ return await operationArg();
608
+ }
609
+ finally {
610
+ projectState.activeOperations -= 1;
611
+ if (projectState.activeOperations === 0) {
612
+ projectState.resolveDrain?.();
613
+ projectState.resolveDrain = undefined;
614
+ projectState.drainPromise = undefined;
615
+ this.pruneProjectState(projectIdArg, projectState);
616
+ }
617
+ }
618
+ }
619
+ waitForProjectDrain(projectStateArg) {
620
+ return projectStateArg.drainPromise ?? Promise.resolve();
621
+ }
622
+ async waitForAllProjectDrains() {
623
+ await Promise.all([...this.projectStates.values()].map((state) => this.waitForProjectDrain(state)));
624
+ }
625
+ async waitForRemovalCleanups(projectIdArg) {
626
+ while (true) {
627
+ const pending = [...this.pendingRemovalCleanups.entries()]
628
+ .filter(([, projectId]) => projectIdArg === undefined || projectId === projectIdArg)
629
+ .map(([cleanup]) => cleanup);
630
+ if (pending.length === 0)
631
+ return;
632
+ await Promise.all(pending);
633
+ }
634
+ }
635
+ reserveCreate(projectIdArg) {
636
+ const activeForProject = [...this.entries.values()]
637
+ .filter((entry) => entry.projectId === projectIdArg && entry.finalState !== 'exited').length;
638
+ const pendingForProject = this.pendingCreatesByProject.get(projectIdArg) ?? 0;
639
+ if (this.entries.size + this.pendingCreates >= maxTerminals) {
640
+ throw new Error(`At most ${maxTerminals} controller terminals may run concurrently.`);
641
+ }
642
+ if (activeForProject + pendingForProject >= maxTerminalsPerProject) {
643
+ throw new Error(`At most ${maxTerminalsPerProject} terminals may run in one project.`);
644
+ }
645
+ this.pendingCreates += 1;
646
+ this.pendingCreatesByProject.set(projectIdArg, pendingForProject + 1);
647
+ }
648
+ releaseCreate(projectIdArg) {
649
+ this.pendingCreates -= 1;
650
+ const remaining = (this.pendingCreatesByProject.get(projectIdArg) ?? 1) - 1;
651
+ if (remaining <= 0)
652
+ this.pendingCreatesByProject.delete(projectIdArg);
653
+ else
654
+ this.pendingCreatesByProject.set(projectIdArg, remaining);
655
+ }
656
+ createTerminalId() {
657
+ for (let attempt = 0; attempt < 8; attempt += 1) {
658
+ const id = `terminal_${plugins.crypto.randomBytes(16).toString('base64url')}`;
659
+ if (!this.entries.has(id))
660
+ return id;
661
+ }
662
+ throw new Error('Unable to allocate a unique terminal identifier.');
663
+ }
664
+ requireShell() {
665
+ if (!this.shell || this.state !== 'open')
666
+ throw new Error('The terminal manager is not initialized.');
667
+ return this.shell;
668
+ }
669
+ requireEntry(projectIdArg, terminalIdArg) {
670
+ const entry = this.entries.get(terminalIdArg);
671
+ if (!entry || entry.projectId !== projectIdArg || entry.finalState === 'exited') {
672
+ throw new Error('The requested terminal does not exist in this project.');
673
+ }
674
+ return entry;
675
+ }
676
+ assertEntryRunning(entryArg) {
677
+ if (entryArg.closing || entryArg.finalState !== 'running') {
678
+ throw new Error('The terminal is not accepting operations.');
679
+ }
680
+ }
681
+ assertAttached(entryArg, peerIdArg) {
682
+ this.assertEntryRunning(entryArg);
683
+ const peer = entryArg.peers.get(peerIdArg);
684
+ if (!peer || peer.detaching)
685
+ throw new Error('The terminal is not attached by this peer.');
686
+ return peer;
687
+ }
688
+ runEntryControl(entryArg, operationArg, internalArg = false) {
689
+ if (!internalArg && entryArg.pendingControlOperations >= maxPendingControlOperations) {
690
+ return Promise.reject(new Error('The terminal control queue is full.'));
691
+ }
692
+ if (!internalArg)
693
+ entryArg.pendingControlOperations += 1;
694
+ const operation = entryArg.controlQueue.then(async () => {
695
+ if (entryArg.closing || entryArg.finalState !== 'running') {
696
+ throw new Error('The terminal is not accepting operations.');
697
+ }
698
+ return operationArg();
699
+ });
700
+ entryArg.controlQueue = operation.then(() => undefined, () => undefined);
701
+ if (internalArg)
702
+ return operation;
703
+ return operation.finally(() => {
704
+ entryArg.pendingControlOperations -= 1;
705
+ });
706
+ }
707
+ appendOutput(entryArg, chunkArg) {
708
+ if (chunkArg.byteLength === 0 || entryArg.finalState === 'exited')
709
+ return;
710
+ appendOutput(entryArg.output, chunkArg);
711
+ if (entryArg.closing)
712
+ return;
713
+ for (const peer of entryArg.peers.values()) {
714
+ if (!peer.deliveryPromise)
715
+ void this.schedulePeerDelivery(entryArg, peer);
716
+ }
717
+ }
718
+ schedulePeerDelivery(entryArg, peerArg, forceResetArg = false) {
719
+ if (peerArg.detaching || peerArg.finalizing || entryArg.peers.get(peerArg.peerId) !== peerArg) {
720
+ return Promise.resolve();
721
+ }
722
+ if (peerArg.deliveryPromise)
723
+ return peerArg.deliveryPromise;
724
+ const targetEnd = entryArg.output.end;
725
+ const needsReset = forceResetArg || peerArg.cursor < entryArg.output.start;
726
+ const start = needsReset ? entryArg.output.start : Math.min(peerArg.cursor, targetEnd);
727
+ const delivery = this.deliverRange(entryArg, peerArg, start, targetEnd, needsReset);
728
+ peerArg.deliveryPromise = delivery;
729
+ void delivery.catch(() => {
730
+ if (entryArg.peers.get(peerArg.peerId) === peerArg) {
731
+ this.detachPeerState(entryArg, peerArg);
732
+ void this.requestSizeReconciliation(entryArg);
733
+ }
734
+ }).finally(() => {
735
+ if (peerArg.deliveryPromise === delivery)
736
+ peerArg.deliveryPromise = undefined;
737
+ if (!peerArg.detaching
738
+ && !peerArg.finalizing
739
+ && entryArg.peers.get(peerArg.peerId) === peerArg
740
+ && peerArg.cursor < entryArg.output.end) {
741
+ void this.schedulePeerDelivery(entryArg, peerArg);
742
+ }
743
+ });
744
+ return delivery;
745
+ }
746
+ async deliverRange(entryArg, peerArg, startArg, endArg, resetArg, deadlineAtArg) {
747
+ let cursor = startArg;
748
+ let resetPending = resetArg;
749
+ let sentFrame = false;
750
+ while (cursor < endArg) {
751
+ if (peerArg.detaching || entryArg.peers.get(peerArg.peerId) !== peerArg)
752
+ return;
753
+ if (cursor < entryArg.output.start) {
754
+ cursor = entryArg.output.start;
755
+ peerArg.cursor = cursor;
756
+ resetPending = true;
757
+ }
758
+ if (cursor >= endArg)
759
+ break;
760
+ const frame = this.readOutputFrame(entryArg, cursor, endArg);
761
+ if (!frame || frame.byteLength === 0)
762
+ break;
763
+ const send = this.sendPeerOutput(entryArg, peerArg, frame, resetPending);
764
+ if (deadlineAtArg === undefined)
765
+ await send;
766
+ else
767
+ await waitUntil(send, deadlineAtArg);
768
+ if (peerArg.detaching || entryArg.peers.get(peerArg.peerId) !== peerArg)
769
+ return;
770
+ cursor += frame.byteLength;
771
+ peerArg.cursor = cursor;
772
+ resetPending = false;
773
+ sentFrame = true;
774
+ }
775
+ if (resetPending && !sentFrame) {
776
+ const send = this.sendPeerOutput(entryArg, peerArg, Buffer.alloc(0), true);
777
+ if (deadlineAtArg === undefined)
778
+ await send;
779
+ else
780
+ await waitUntil(send, deadlineAtArg);
781
+ peerArg.cursor = Math.max(peerArg.cursor, entryArg.output.start);
782
+ }
783
+ }
784
+ readOutputFrame(entryArg, startArg, endArg) {
785
+ if (startArg >= endArg)
786
+ return undefined;
787
+ let slabStart = entryArg.output.start;
788
+ for (const slab of entryArg.output.slabs) {
789
+ const slabBytes = slab.end - slab.start;
790
+ const slabEnd = slabStart + slabBytes;
791
+ if (slabEnd <= startArg) {
792
+ slabStart = slabEnd;
793
+ continue;
794
+ }
795
+ if (slabStart >= endArg)
796
+ break;
797
+ const offset = Math.max(0, startArg - slabStart);
798
+ const frameBytes = Math.min(maxOutputFrameBytes, slabBytes - offset, endArg - startArg);
799
+ return slab.buffer.subarray(slab.start + offset, slab.start + offset + frameBytes);
800
+ }
801
+ return undefined;
802
+ }
803
+ async sendPeerOutput(entryArg, peerArg, dataArg, resetArg) {
804
+ if (peerArg.detaching || entryArg.peers.get(peerArg.peerId) !== peerArg)
805
+ return;
806
+ await this.options.sendOutput(peerArg.peerId, {
807
+ terminalId: { ...entryArg.terminal.id },
808
+ dataBase64: dataArg.toString('base64'),
809
+ ...(resetArg ? { reset: true } : {}),
810
+ });
811
+ }
812
+ detachPeerState(entryArg, peerArg) {
813
+ peerArg.detaching = true;
814
+ if (entryArg.peers.get(peerArg.peerId) === peerArg) {
815
+ entryArg.peers.delete(peerArg.peerId);
816
+ if (entryArg.sizesByPeer.delete(peerArg.peerId))
817
+ entryArg.sizeRevision += 1;
818
+ }
819
+ }
820
+ async applyMinimumSize(entryArg) {
821
+ if (entryArg.sizesByPeer.size === 0 || entryArg.closing)
822
+ return;
823
+ let rows = Number.POSITIVE_INFINITY;
824
+ let cols = Number.POSITIVE_INFINITY;
825
+ for (const size of entryArg.sizesByPeer.values()) {
826
+ rows = Math.min(rows, size.rows);
827
+ cols = Math.min(cols, size.cols);
828
+ }
829
+ if (Number.isFinite(rows) && Number.isFinite(cols)) {
830
+ await entryArg.execution.resize(cols, rows);
831
+ }
832
+ }
833
+ async applyMinimumSizeUntilStable(entryArg) {
834
+ if (entryArg.sizeReconciliationActive || entryArg.closing)
835
+ return;
836
+ entryArg.sizeReconciliationActive = true;
837
+ try {
838
+ let appliedRevision;
839
+ do {
840
+ appliedRevision = entryArg.sizeRevision;
841
+ await this.applyMinimumSize(entryArg);
842
+ } while (!entryArg.closing && appliedRevision !== entryArg.sizeRevision);
843
+ }
844
+ finally {
845
+ entryArg.sizeReconciliationActive = false;
846
+ }
847
+ }
848
+ requestSizeReconciliation(entryArg) {
849
+ if (entryArg.closing || entryArg.sizeReconciliationActive)
850
+ return Promise.resolve();
851
+ if (entryArg.sizeReconciliationPromise)
852
+ return entryArg.sizeReconciliationPromise;
853
+ const reconciliation = this.runEntryControl(entryArg, () => this.applyMinimumSizeUntilStable(entryArg), true);
854
+ entryArg.sizeReconciliationPromise = reconciliation;
855
+ void reconciliation.catch(() => undefined).finally(() => {
856
+ if (entryArg.sizeReconciliationPromise === reconciliation) {
857
+ entryArg.sizeReconciliationPromise = undefined;
858
+ }
859
+ });
860
+ return reconciliation;
861
+ }
862
+ confirmRootExit(entryArg, exitCodeArg) {
863
+ if (entryArg.finalState === 'exited')
864
+ return;
865
+ entryArg.finalState = 'exited';
866
+ if (exitCodeArg !== undefined)
867
+ entryArg.exitCode = exitCodeArg;
868
+ entryArg.exitSubscription?.dispose();
869
+ entryArg.resolveRootExit();
870
+ entryArg.finalizePromise = this.finalizeExitedEntry(entryArg, entryArg.finalizationDeadlineAt ?? Date.now() + this.cleanupTimeoutMs);
871
+ }
872
+ async finalizeExitedPeer(entryArg, peerArg, finalOutputEndArg, deadlineAtArg) {
873
+ if (peerArg.detaching || entryArg.peers.get(peerArg.peerId) !== peerArg)
874
+ return;
875
+ peerArg.finalizing = true;
876
+ try {
877
+ if (peerArg.deliveryPromise) {
878
+ await waitUntil(peerArg.deliveryPromise, deadlineAtArg);
879
+ }
880
+ if (peerArg.detaching || entryArg.peers.get(peerArg.peerId) !== peerArg)
881
+ return;
882
+ const needsReset = peerArg.cursor < entryArg.output.start;
883
+ await this.deliverRange(entryArg, peerArg, needsReset ? entryArg.output.start : peerArg.cursor, finalOutputEndArg, needsReset, deadlineAtArg);
884
+ if (peerArg.detaching
885
+ || entryArg.peers.get(peerArg.peerId) !== peerArg
886
+ || peerArg.cursor < finalOutputEndArg)
887
+ return;
888
+ await waitUntil(this.options.sendOutput(peerArg.peerId, {
889
+ terminalId: { ...entryArg.terminal.id },
890
+ dataBase64: '',
891
+ ended: true,
892
+ }), deadlineAtArg);
893
+ }
894
+ catch {
895
+ // A stalled peer is detached without an ended frame; output can never race ended.
896
+ }
897
+ finally {
898
+ this.detachPeerState(entryArg, peerArg);
899
+ }
900
+ }
901
+ async finalizeExitedEntry(entryArg, deadlineAtArg) {
902
+ if (this.entries.get(entryArg.terminal.id.nativeId) !== entryArg)
903
+ return;
904
+ const finalOutputEnd = entryArg.output.end;
905
+ await Promise.allSettled([...entryArg.peers.values()].map((peer) => (this.finalizeExitedPeer(entryArg, peer, finalOutputEnd, deadlineAtArg))));
906
+ this.entries.delete(entryArg.terminal.id.nativeId);
907
+ entryArg.peers.clear();
908
+ entryArg.sizesByPeer.clear();
909
+ const terminalId = { ...entryArg.terminal.id };
910
+ const removalCleanup = Promise.resolve()
911
+ .then(() => this.options.onTerminalStopped(entryArg.projectId, terminalId, entryArg.exitCode))
912
+ .catch(() => undefined);
913
+ this.pendingRemovalCleanups.set(removalCleanup, entryArg.projectId);
914
+ try {
915
+ await waitUntil(removalCleanup, deadlineAtArg);
916
+ }
917
+ catch {
918
+ // Resource ownership is already released; startup pruning recovers a timed-out cleanup.
919
+ }
920
+ finally {
921
+ this.pendingRemovalCleanups.delete(removalCleanup);
922
+ }
923
+ try {
924
+ this.options.onTerminalsChanged(entryArg.projectId);
925
+ }
926
+ catch {
927
+ // Root ownership is already released; a notification callback cannot restore it.
928
+ }
929
+ }
930
+ async closeEntry(entryArg, deadlineAtArg) {
931
+ if (this.entries.get(entryArg.terminal.id.nativeId) !== entryArg)
932
+ return;
933
+ if (entryArg.finalState === 'exited') {
934
+ await waitUntil(entryArg.finalizePromise ?? Promise.resolve(), deadlineAtArg);
935
+ return;
936
+ }
937
+ if (!entryArg.closeLifecyclePromise) {
938
+ entryArg.closing = true;
939
+ entryArg.finalizationDeadlineAt = deadlineAtArg;
940
+ const lifecycle = (async () => {
941
+ await entryArg.rootExitPromise;
942
+ await entryArg.finalizePromise;
943
+ })();
944
+ entryArg.closeLifecyclePromise = lifecycle;
945
+ try {
946
+ const signal = entryArg.execution.kill();
947
+ void signal.catch((errorArg) => {
948
+ entryArg.signalError = normalizeError(errorArg);
949
+ });
950
+ }
951
+ catch (errorArg) {
952
+ entryArg.signalError = normalizeError(errorArg);
953
+ }
954
+ }
955
+ try {
956
+ await waitUntil(entryArg.closeLifecyclePromise, deadlineAtArg);
957
+ }
958
+ catch (errorArg) {
959
+ if (this.entries.get(entryArg.terminal.id.nativeId) !== entryArg)
960
+ return;
961
+ throw entryArg.signalError
962
+ ? new AggregateError([entryArg.signalError, errorArg], 'The terminal root could not be confirmed stopped.')
963
+ : errorArg;
964
+ }
965
+ }
966
+ async closeProjectEntries(projectIdArg, deadlineAtArg) {
967
+ const outcomes = await Promise.allSettled([...this.entries.values()]
968
+ .filter((entry) => entry.projectId === projectIdArg)
969
+ .map((entry) => this.closeEntry(entry, deadlineAtArg)));
970
+ const errors = outcomes.flatMap((outcome) => (outcome.status === 'rejected' ? [outcome.reason] : []));
971
+ const remaining = [...this.entries.values()]
972
+ .filter((entry) => entry.projectId === projectIdArg);
973
+ if (remaining.length > 0) {
974
+ errors.push(new Error('One or more project terminal roots remain unconfirmed.'));
975
+ }
976
+ if (errors.length > 0) {
977
+ throw new AggregateError(errors, 'The project terminal roots could not all be confirmed stopped.');
978
+ }
979
+ }
980
+ }
981
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50ZXJtaW5hbG1hbmFnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9jbGFzc2VzLnRlcm1pbmFsbWFuYWdlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUd4QyxPQUFPLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQXNHdEYsTUFBTSxZQUFZLEdBQUcsRUFBRSxDQUFDO0FBQ3hCLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxDQUFDO0FBQ2pDLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLENBQUM7QUFDM0MsTUFBTSxrQkFBa0IsR0FBRyxDQUFDLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUMzQyxNQUFNLGFBQWEsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQy9CLE1BQU0sbUJBQW1CLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUN0QyxNQUFNLG1CQUFtQixHQUFHLEVBQUUsQ0FBQztBQUMvQixNQUFNLDJCQUEyQixHQUFHLEdBQUcsQ0FBQztBQUN4QyxNQUFNLHVCQUF1QixHQUFHLE1BQU0sQ0FBQztBQUV2QyxNQUFNLGNBQWMsR0FBRyxDQUFDLFFBQWlCLEVBQVMsRUFBRSxDQUNsRCxRQUFRLFlBQVksS0FBSyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBRXJFLE1BQU0sYUFBYSxHQUFHLENBQUMsV0FBcUMsRUFBdUIsRUFBRSxDQUFDLENBQUM7SUFDckYsR0FBRyxXQUFXO0lBQ2QsRUFBRSxFQUFFLEVBQUUsR0FBRyxXQUFXLENBQUMsRUFBRSxFQUFFO0NBQzFCLENBQUMsQ0FBQztBQUVILE1BQU0sa0JBQWtCLEdBQUcsQ0FDekIsUUFBdUIsRUFDdkIsZUFBdUIsRUFDdkIsUUFB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