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,484 @@
1
+ import * as plugins from './plugins.js';
2
+ import { controllerPackageName } from '../dist_ts_interfaces/index.js';
3
+ import { defaultControllerPort } from './classes.config.js';
4
+ const maximumProcessIdentities = 16_384;
5
+ const processIdentityBatchSize = 128;
6
+ const maximumProcessArguments = 512;
7
+ const maximumProcessArgumentBytes = 256 * 1024;
8
+ const maximumProcessCommandBytes = maximumProcessArgumentBytes + maximumProcessArguments;
9
+ const maximumReconstructedPathArguments = 32;
10
+ const maximumDataWriterCliPaths = 8;
11
+ const maximumDataWriterCandidates = 1_024;
12
+ const currentRuntimeName = String(controllerPackageName) === 'agl' ? 'AGL' : 'hcon';
13
+ const installedControllerPackagePaths = [
14
+ plugins.path.join('node_modules', '@modelprofile.com', 'harness-controller'),
15
+ plugins.path.join('node_modules', 'agl'),
16
+ ];
17
+ const boundedProcessArgumentsPrefix = (argumentsArg) => {
18
+ const bounded = [];
19
+ let totalBytes = 0;
20
+ for (const argument of argumentsArg) {
21
+ const argumentBytes = Buffer.byteLength(argument, 'utf8');
22
+ if (bounded.length >= maximumProcessArguments
23
+ || totalBytes + argumentBytes > maximumProcessArgumentBytes)
24
+ break;
25
+ bounded.push(argument);
26
+ totalBytes += argumentBytes;
27
+ }
28
+ return bounded;
29
+ };
30
+ const assertPid = (pidArg) => {
31
+ if (!Number.isSafeInteger(pidArg) || pidArg < 2) {
32
+ throw new Error('Controller PID is invalid.');
33
+ }
34
+ return pidArg;
35
+ };
36
+ const execFile = async (fileArg, argsArg, optionsArg = {}) => {
37
+ return await new Promise((resolve, reject) => {
38
+ plugins.childProcess.execFile(fileArg, argsArg, {
39
+ encoding: 'utf8',
40
+ maxBuffer: optionsArg.maxBufferBytes ?? 128 * 1024,
41
+ timeout: optionsArg.timeoutMs ?? 2_000,
42
+ killSignal: 'SIGKILL',
43
+ ...(optionsArg.detached === undefined ? {} : { detached: optionsArg.detached }),
44
+ }, (errorArg, stdoutArg) => {
45
+ if (errorArg) {
46
+ reject(errorArg);
47
+ return;
48
+ }
49
+ resolve(stdoutArg);
50
+ });
51
+ });
52
+ };
53
+ const readBoundedLinuxCommandArguments = async (pidArg) => {
54
+ // Read only the accepted argv budget plus one byte so oversized processes
55
+ // cannot make a system-wide inventory retain unbounded command data.
56
+ const handle = await plugins.fs.promises.open(`/proc/${pidArg}/cmdline`, plugins.fs.constants.O_RDONLY);
57
+ try {
58
+ const buffer = Buffer.allocUnsafe(maximumProcessCommandBytes + 1);
59
+ let bytesRead = 0;
60
+ while (bytesRead < buffer.length) {
61
+ const read = await handle.read(buffer, bytesRead, buffer.length - bytesRead, null);
62
+ if (read.bytesRead === 0)
63
+ break;
64
+ bytesRead += read.bytesRead;
65
+ }
66
+ const commandLength = Math.min(bytesRead, maximumProcessCommandBytes);
67
+ const argumentsResult = [];
68
+ let argumentStart = 0;
69
+ let argumentCountExceeded = false;
70
+ for (let index = 0; index < commandLength; index++) {
71
+ if (buffer[index] !== 0)
72
+ continue;
73
+ if (argumentsResult.length >= maximumProcessArguments) {
74
+ argumentCountExceeded = true;
75
+ break;
76
+ }
77
+ if (index > argumentStart) {
78
+ argumentsResult.push(buffer.subarray(argumentStart, index).toString('utf8'));
79
+ }
80
+ argumentStart = index + 1;
81
+ }
82
+ if (bytesRead <= maximumProcessCommandBytes
83
+ && !argumentCountExceeded
84
+ && argumentStart < commandLength
85
+ && argumentsResult.length < maximumProcessArguments) {
86
+ argumentsResult.push(buffer.subarray(argumentStart, commandLength).toString('utf8'));
87
+ }
88
+ return {
89
+ arguments: argumentsResult,
90
+ truncated: bytesRead > maximumProcessCommandBytes || argumentCountExceeded,
91
+ };
92
+ }
93
+ finally {
94
+ await handle.close();
95
+ }
96
+ };
97
+ const readLinuxIdentity = async (pidArg) => {
98
+ const [statBuffer, command] = await Promise.all([
99
+ plugins.fs.promises.readFile(`/proc/${pidArg}/stat`),
100
+ readBoundedLinuxCommandArguments(pidArg),
101
+ ]);
102
+ const stat = statBuffer.toString('utf8');
103
+ const statSuffixIndex = stat.lastIndexOf(') ');
104
+ if (statSuffixIndex < 0)
105
+ throw new Error('Unable to parse controller process metadata.');
106
+ const statFields = stat.slice(statSuffixIndex + 2).trim().split(/\s+/);
107
+ const processGroupId = Number(statFields[2]);
108
+ const startTime = statFields[19];
109
+ if (!Number.isSafeInteger(processGroupId) || !startTime) {
110
+ throw new Error('Unable to parse controller process identity.');
111
+ }
112
+ return {
113
+ pid: pidArg,
114
+ processGroupId,
115
+ processGroupLeader: processGroupId === pidArg,
116
+ arguments: command.arguments,
117
+ ...(command.truncated ? { argumentsTruncated: true } : {}),
118
+ fingerprint: `linux:${pidArg}:${startTime}`,
119
+ };
120
+ };
121
+ const readLinuxProcessGroupId = async (pidArg) => {
122
+ try {
123
+ const stat = await plugins.fs.promises.readFile(`/proc/${pidArg}/stat`, 'utf8');
124
+ const statSuffixIndex = stat.lastIndexOf(') ');
125
+ if (statSuffixIndex < 0)
126
+ return undefined;
127
+ const statFields = stat.slice(statSuffixIndex + 2).trim().split(/\s+/);
128
+ const processGroupId = Number(statFields[2]);
129
+ return Number.isSafeInteger(processGroupId) ? processGroupId : undefined;
130
+ }
131
+ catch (error) {
132
+ const code = error.code;
133
+ if (code === 'ENOENT' || code === 'ESRCH' || code === 'EACCES')
134
+ return undefined;
135
+ throw error;
136
+ }
137
+ };
138
+ const readPosixIdentity = async (pidArg) => {
139
+ const output = await execFile('ps', [
140
+ '-ww',
141
+ '-p',
142
+ String(pidArg),
143
+ '-o',
144
+ 'pgid=',
145
+ '-o',
146
+ 'lstart=',
147
+ '-o',
148
+ 'command=',
149
+ ], { maxBufferBytes: 8 * 1024 * 1024 });
150
+ const line = output.trim();
151
+ const match = /^\s*(\d+)\s+(.{24})\s+(.+)$/.exec(line);
152
+ if (!match)
153
+ throw new Error('Unable to parse controller process metadata.');
154
+ const processGroupId = Number(match[1]);
155
+ return {
156
+ pid: pidArg,
157
+ processGroupId,
158
+ processGroupLeader: processGroupId === pidArg,
159
+ arguments: parsePosixCommandArguments(match[3]),
160
+ fingerprint: `posix:${pidArg}:${match[2].trim()}`,
161
+ };
162
+ };
163
+ const parsePosixCommandArguments = (commandArg) => {
164
+ return (commandArg.match(/"[^"]*"|'[^']*'|\S+/g) ?? []).map((argumentArg) => {
165
+ const quoted = ((argumentArg.startsWith('"') && argumentArg.endsWith('"'))
166
+ || (argumentArg.startsWith("'") && argumentArg.endsWith("'")));
167
+ return quoted ? argumentArg.slice(1, -1) : argumentArg;
168
+ });
169
+ };
170
+ export const readControllerProcessIdentity = async (pidArg) => {
171
+ const pid = assertPid(pidArg);
172
+ try {
173
+ if (process.platform === 'linux')
174
+ return await readLinuxIdentity(pid);
175
+ if (process.platform !== 'win32')
176
+ return await readPosixIdentity(pid);
177
+ return null;
178
+ }
179
+ catch (error) {
180
+ const code = error.code;
181
+ if (code === 'ENOENT' || code === 'ESRCH')
182
+ return null;
183
+ throw error;
184
+ }
185
+ };
186
+ export const readProcessGroupMemberPids = async (processGroupIdArg) => {
187
+ const processGroupId = assertPid(processGroupIdArg);
188
+ if (process.platform === 'linux') {
189
+ const entries = await plugins.fs.promises.readdir('/proc');
190
+ const processIds = entries
191
+ .filter((entryArg) => /^[1-9][0-9]*$/.test(entryArg))
192
+ .map((entryArg) => Number(entryArg))
193
+ .filter((processIdArg) => processIdArg >= 2);
194
+ const groupIds = await Promise.all(processIds.map(async (processIdArg) => ({
195
+ processId: processIdArg,
196
+ processGroupId: await readLinuxProcessGroupId(processIdArg),
197
+ })));
198
+ return groupIds
199
+ .filter((entryArg) => entryArg.processGroupId === processGroupId)
200
+ .map((entryArg) => entryArg.processId)
201
+ .sort((leftArg, rightArg) => leftArg - rightArg);
202
+ }
203
+ if (process.platform !== 'win32') {
204
+ // A detached helper gets its own process group, so macOS `ps -ax` cannot
205
+ // report the probe itself as a member of the controller group being read.
206
+ const output = await execFile('ps', ['-ax', '-o', 'pid=', '-o', 'pgid='], { detached: true });
207
+ return output
208
+ .split(/\r?\n/)
209
+ .map((lineArg) => /^\s*(\d+)\s+(\d+)\s*$/.exec(lineArg))
210
+ .filter((matchArg) => matchArg !== null)
211
+ .filter((matchArg) => Number(matchArg[2]) === processGroupId)
212
+ .map((matchArg) => Number(matchArg[1]))
213
+ .sort((leftArg, rightArg) => leftArg - rightArg);
214
+ }
215
+ return [];
216
+ };
217
+ const findCliArgumentIndex = async (pidArg, argumentsArg, cliPathArg, allowMissingAbsolutePathArg = false) => {
218
+ const boundedArguments = boundedProcessArgumentsPrefix(argumentsArg);
219
+ const directIndex = boundedArguments.indexOf(cliPathArg);
220
+ if (directIndex >= 0)
221
+ return directIndex;
222
+ // A controller launched with a relative path (`node cli.js foreground`) is
223
+ // still the same file; resolve candidate tokens against the process's own
224
+ // working directory before declaring the identity unverifiable.
225
+ let processCwd;
226
+ if (process.platform === 'linux') {
227
+ try {
228
+ processCwd = await plugins.fs.promises.readlink(`/proc/${pidArg}/cwd`);
229
+ }
230
+ catch {
231
+ processCwd = undefined;
232
+ }
233
+ }
234
+ const cliBasename = plugins.path.basename(cliPathArg);
235
+ const normalizedCliPath = plugins.path.normalize(cliPathArg);
236
+ for (let endIndex = 1; endIndex <= boundedArguments.length; endIndex++) {
237
+ const minimumStartIndex = Math.max(0, endIndex - maximumReconstructedPathArguments);
238
+ for (let startIndex = endIndex - 1; startIndex >= minimumStartIndex; startIndex--) {
239
+ const candidate = boundedArguments.slice(startIndex, endIndex).join(' ');
240
+ if (plugins.path.basename(candidate) !== cliBasename)
241
+ continue;
242
+ try {
243
+ const resolved = await plugins.fs.promises.realpath(plugins.path.isAbsolute(candidate)
244
+ ? candidate
245
+ : plugins.path.resolve(processCwd ?? '', candidate));
246
+ if (resolved === cliPathArg)
247
+ return endIndex - 1;
248
+ }
249
+ catch {
250
+ // pnpm may remove A's package while its worker still owns the upgrade
251
+ // lock. Only that trusted caller may use an exact normalized old path.
252
+ if (allowMissingAbsolutePathArg
253
+ && plugins.path.isAbsolute(candidate)
254
+ && plugins.path.normalize(candidate) === normalizedCliPath)
255
+ return endIndex - 1;
256
+ continue;
257
+ }
258
+ }
259
+ }
260
+ return -1;
261
+ };
262
+ export const processIdentityHasFileArgument = async (identityArg, filePathArg, optionsArg = {}) => await findCliArgumentIndex(identityArg.pid, identityArg.arguments, filePathArg, optionsArg.allowMissingAbsolutePath === true) >= 0;
263
+ const findInstalledControllerPackageFileArgumentIndex = (argumentsArg, packageRelativePathArg) => {
264
+ const boundedArguments = boundedProcessArgumentsPrefix(argumentsArg);
265
+ const expectedSuffixes = installedControllerPackagePaths.map((packagePathArg) => (`${plugins.path.sep}${plugins.path.join(packagePathArg, packageRelativePathArg)}`));
266
+ const expectedBasename = plugins.path.basename(packageRelativePathArg);
267
+ for (let endIndex = 1; endIndex <= boundedArguments.length; endIndex++) {
268
+ const minimumStartIndex = Math.max(0, endIndex - maximumReconstructedPathArguments);
269
+ for (let startIndex = endIndex - 1; startIndex >= minimumStartIndex; startIndex--) {
270
+ const candidate = boundedArguments.slice(startIndex, endIndex).join(' ');
271
+ if (plugins.path.basename(candidate) === expectedBasename
272
+ && plugins.path.isAbsolute(candidate)
273
+ && expectedSuffixes.some((suffixArg) => (plugins.path.normalize(candidate).endsWith(suffixArg))))
274
+ return endIndex - 1;
275
+ }
276
+ }
277
+ return -1;
278
+ };
279
+ const processIdentityHasInstalledControllerCommand = (identityArg, commandArg) => {
280
+ const cliIndex = findInstalledControllerPackageFileArgumentIndex(identityArg.arguments, 'cli.js');
281
+ return cliIndex >= 0 && identityArg.arguments[cliIndex + 1] === commandArg;
282
+ };
283
+ const readEffectiveArgvPort = (argumentsArg) => {
284
+ let effectivePort = defaultControllerPort;
285
+ const boundedArguments = boundedProcessArgumentsPrefix(argumentsArg);
286
+ for (let index = 0; index < boundedArguments.length; index++) {
287
+ if (boundedArguments[index] === '--port') {
288
+ effectivePort = Number(boundedArguments[index + 1]);
289
+ }
290
+ else if (boundedArguments[index].startsWith('--port=')) {
291
+ effectivePort = Number(boundedArguments[index].slice('--port='.length));
292
+ }
293
+ }
294
+ return effectivePort;
295
+ };
296
+ export const processIdentityHasCliCommand = async (identityArg, cliPathArg, commandArg, optionsArg = {}) => {
297
+ const cliIndex = await findCliArgumentIndex(identityArg.pid, identityArg.arguments, cliPathArg, optionsArg.allowMissingAbsolutePath === true);
298
+ return cliIndex >= 0 && identityArg.arguments[cliIndex + 1] === commandArg;
299
+ };
300
+ const hasExpectedArguments = async (identityArg, cliPathArg, portArg, commandArg) => {
301
+ return await processIdentityHasCliCommand(identityArg, cliPathArg, commandArg)
302
+ && readEffectiveArgvPort(identityArg.arguments) === portArg;
303
+ };
304
+ const visitProcessIdentities = async (visitorArg) => {
305
+ if (process.platform === 'linux') {
306
+ const entries = await plugins.fs.promises.readdir('/proc');
307
+ const processIds = entries
308
+ .filter((entryArg) => /^[1-9][0-9]*$/.test(entryArg))
309
+ .map((entryArg) => Number(entryArg))
310
+ .filter((processIdArg) => processIdArg >= 2)
311
+ .sort((leftArg, rightArg) => leftArg - rightArg);
312
+ if (processIds.length > maximumProcessIdentities) {
313
+ throw new Error('Controller data-writer process inventory exceeds its scan bound.');
314
+ }
315
+ for (let index = 0; index < processIds.length; index += processIdentityBatchSize) {
316
+ const batch = await Promise.all(processIds.slice(index, index + processIdentityBatchSize).map(async (processIdArg) => {
317
+ try {
318
+ return await readControllerProcessIdentity(processIdArg);
319
+ }
320
+ catch (errorArg) {
321
+ const code = errorArg.code;
322
+ if (code === 'EACCES' || code === 'EPERM')
323
+ return null;
324
+ throw errorArg;
325
+ }
326
+ }));
327
+ for (const identity of batch) {
328
+ if (identity)
329
+ await visitorArg(identity);
330
+ }
331
+ }
332
+ return;
333
+ }
334
+ if (process.platform === 'win32')
335
+ return;
336
+ const output = await execFile('ps', [
337
+ '-ax',
338
+ '-ww',
339
+ '-o',
340
+ 'pid=',
341
+ '-o',
342
+ 'pgid=',
343
+ '-o',
344
+ 'lstart=',
345
+ '-o',
346
+ 'command=',
347
+ ], { maxBufferBytes: 8 * 1024 * 1024 });
348
+ let identityCount = 0;
349
+ for (const lineArg of output.split(/\r?\n/)) {
350
+ const match = /^\s*(\d+)\s+(\d+)\s+(.{24})\s+(.+)$/.exec(lineArg);
351
+ if (!match)
352
+ continue;
353
+ const pid = Number(match[1]);
354
+ const processGroupId = Number(match[2]);
355
+ if (!Number.isSafeInteger(pid) || !Number.isSafeInteger(processGroupId))
356
+ continue;
357
+ identityCount += 1;
358
+ if (identityCount > maximumProcessIdentities) {
359
+ throw new Error('Controller data-writer process inventory exceeds its scan bound.');
360
+ }
361
+ await visitorArg({
362
+ pid,
363
+ processGroupId,
364
+ processGroupLeader: processGroupId === pid,
365
+ arguments: parsePosixCommandArguments(match[4]),
366
+ fingerprint: `posix:${pid}:${match[3].trim()}`,
367
+ });
368
+ }
369
+ };
370
+ const compactProcessIdentity = (identityArg) => ({
371
+ ...identityArg,
372
+ arguments: [],
373
+ });
374
+ export const listControllerProcessesForCli = async (cliPathArg) => {
375
+ const candidates = [];
376
+ await visitProcessIdentities(async (identity) => {
377
+ for (const command of ['__serve', 'foreground']) {
378
+ if (!await processIdentityHasCliCommand(identity, cliPathArg, command))
379
+ continue;
380
+ const port = readEffectiveArgvPort(identity.arguments);
381
+ if (!Number.isSafeInteger(port) || port < 1 || port > 65_535) {
382
+ throw new Error(`An ${currentRuntimeName} process has an invalid port argument (PID ${identity.pid}).`);
383
+ }
384
+ candidates.push({ identity: compactProcessIdentity(identity), command, port });
385
+ }
386
+ });
387
+ return candidates.sort((leftArg, rightArg) => leftArg.identity.pid - rightArg.identity.pid);
388
+ };
389
+ export const listControllerDataWriterProcessesForCli = async (cliPathArg, optionsArg = {}) => await listControllerDataWriterProcessesForCliPaths([cliPathArg], optionsArg);
390
+ export const listControllerDataWriterProcessesForCliPaths = async (cliPathsArg, optionsArg = {}) => {
391
+ const cliPaths = [...new Set(cliPathsArg)];
392
+ if (cliPaths.length === 0
393
+ || cliPaths.length > maximumDataWriterCliPaths
394
+ || cliPaths.some((cliPathArg) => !plugins.path.isAbsolute(cliPathArg)))
395
+ throw new Error('Controller data-writer CLI path inventory is invalid.');
396
+ const flexChildPaths = cliPaths.map((cliPathArg) => plugins.path.join(plugins.path.dirname(cliPathArg), 'dist_ts', 'flexharness.child.js'));
397
+ const candidates = [];
398
+ await visitProcessIdentities(async (identity) => {
399
+ let matched = false;
400
+ for (const cliPath of cliPaths) {
401
+ if (await processIdentityHasCliCommand(identity, cliPath, '__serve')
402
+ || await processIdentityHasCliCommand(identity, cliPath, 'foreground')) {
403
+ matched = true;
404
+ break;
405
+ }
406
+ }
407
+ if (!matched
408
+ && optionsArg.includeInstalledPackagePaths === true
409
+ && (processIdentityHasInstalledControllerCommand(identity, '__serve')
410
+ || processIdentityHasInstalledControllerCommand(identity, 'foreground')))
411
+ matched = true;
412
+ if (matched) {
413
+ if (candidates.length >= maximumDataWriterCandidates) {
414
+ throw new Error('Controller data-writer candidate inventory exceeds its scan bound.');
415
+ }
416
+ candidates.push({ kind: 'controller', identity: compactProcessIdentity(identity) });
417
+ return;
418
+ }
419
+ for (const cliPath of cliPaths) {
420
+ if (await processIdentityHasCliCommand(identity, cliPath, 'temp-password')) {
421
+ matched = true;
422
+ break;
423
+ }
424
+ }
425
+ if (!matched
426
+ && optionsArg.includeInstalledPackagePaths === true
427
+ && processIdentityHasInstalledControllerCommand(identity, 'temp-password'))
428
+ matched = true;
429
+ if (matched) {
430
+ if (candidates.length >= maximumDataWriterCandidates) {
431
+ throw new Error('Controller data-writer candidate inventory exceeds its scan bound.');
432
+ }
433
+ candidates.push({ kind: 'temp-password', identity: compactProcessIdentity(identity) });
434
+ return;
435
+ }
436
+ for (const flexChildPath of flexChildPaths) {
437
+ if (await processIdentityHasFileArgument(identity, flexChildPath)) {
438
+ matched = true;
439
+ break;
440
+ }
441
+ }
442
+ if (!matched
443
+ && optionsArg.includeInstalledPackagePaths === true
444
+ && findInstalledControllerPackageFileArgumentIndex(identity.arguments, plugins.path.join('dist_ts', 'flexharness.child.js')) >= 0)
445
+ matched = true;
446
+ if (matched) {
447
+ if (candidates.length >= maximumDataWriterCandidates) {
448
+ throw new Error('Controller data-writer candidate inventory exceeds its scan bound.');
449
+ }
450
+ candidates.push({ kind: 'flex-child', identity: compactProcessIdentity(identity) });
451
+ }
452
+ });
453
+ return candidates.sort((leftArg, rightArg) => leftArg.identity.pid - rightArg.identity.pid);
454
+ };
455
+ export const inspectControllerProcess = async (optionsArg) => {
456
+ const identity = await readControllerProcessIdentity(optionsArg.pid);
457
+ if (!identity)
458
+ return null;
459
+ if (!await hasExpectedArguments(identity, optionsArg.cliPath, optionsArg.port, optionsArg.command)) {
460
+ return null;
461
+ }
462
+ if (optionsArg.expectedProcessGroupId !== undefined
463
+ && identity.processGroupId !== optionsArg.expectedProcessGroupId)
464
+ return null;
465
+ if (optionsArg.expectedFingerprint !== undefined
466
+ && identity.fingerprint !== optionsArg.expectedFingerprint)
467
+ return null;
468
+ return identity;
469
+ };
470
+ export const signalVerifiedControllerProcess = async (optionsArg) => {
471
+ const identity = await inspectControllerProcess(optionsArg);
472
+ if (!identity) {
473
+ throw new Error('Refusing to signal a process whose controller identity cannot be verified.');
474
+ }
475
+ if (optionsArg.signalProcessGroup) {
476
+ if (!identity.processGroupLeader) {
477
+ throw new Error('Refusing to signal a process group whose controller is not its leader.');
478
+ }
479
+ process.kill(-identity.processGroupId, optionsArg.signal);
480
+ return;
481
+ }
482
+ process.kill(identity.pid, optionsArg.signal);
483
+ };
484
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5wcm9jZXNzaW5zcGVjdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL2NsYXNzZXMucHJvY2Vzc2luc3BlY3Rpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDbEUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFzQjVELE1BQU0sd0JBQXdCLEdBQUcsTUFBTSxDQUFDO0FBQ3hDLE1BQU0sd0JBQXdCLEdBQUcsR0FBRyxDQUFDO0FBQ3JDLE1BQU0sdUJBQXVCLEdBQUcsR0FBRyxDQUFDO0FBQ3BDLE1BQU0sMkJBQTJCLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQztBQUMvQyxNQUFNLDBCQUEwQixHQUFHLDJCQUEyQixHQUFHLHVCQUF1QixDQUFDO0FBQ3pGLE1BQU0saUNBQWlDLEdBQUcsRUFBRSxDQUFDO0FBQzdDLE1BQU0seUJBQXlCLEdBQUcsQ0FBQyxDQUFDO0FBQ3BDLE1BQU0sMkJBQTJCLEdBQUcsS0FBSyxDQUFDO0FBQzFDLE1BQU0sa0JBQWtCLEdBQUcsTUFBTSxDQUFDLHFCQUFxQixDQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztBQUNwRixNQUFNLCtCQUErQixHQUFHO0lBQ3RDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGNBQWMsRUFBRSxtQkFBbUIsRUFBRSxvQkFBb0IsQ0FBQztJQUM1RSxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsS0FBSyxDQUFDO0NBQ2hDLENBQUM7QUFFWCxNQUFNLDZCQUE2QixHQUFHLENBQUMsWUFBK0IsRUFBWSxFQUFFO0lBQ2xGLE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQztJQUM3QixJQUFJ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
@@ -0,0 +1,64 @@
1
+ import { type TControllerResource, type TControllerSessionId } from '../dist_ts_interfaces/index.js';
2
+ import type { SmartDataAuthStore } from './classes.authstore.js';
3
+ import type { IControllerResourceDocument } from './interfaces.projects.js';
4
+ import { type IFlexBrowserResourceDescriptor } from './interfaces.flexipc.js';
5
+ export interface IControllerResourceRuntimeHost {
6
+ startResource(resourceArg: IControllerResourceDocument, signalArg: AbortSignal): Promise<void>;
7
+ stopResource(resourceArg: IControllerResourceDocument, signalArg: AbortSignal): Promise<void>;
8
+ isRunning(resourceArg: IControllerResourceDocument): boolean;
9
+ isAvailable(): boolean;
10
+ renameResource?(resourceArg: IControllerResourceDocument): Promise<void>;
11
+ reconcileAttachment(resourceArg: IControllerResourceDocument, signalArg: AbortSignal): Promise<void>;
12
+ retireResource(resourceArg: IControllerResourceDocument, signalArg: AbortSignal): Promise<void>;
13
+ }
14
+ export interface IControllerResourceCoordinatorOptions {
15
+ store: Pick<SmartDataAuthStore, 'listResources' | 'listRecoverableResources' | 'createResource' | 'renameResource' | 'beginResourceAttachmentTransition' | 'commitResourceAttachmentTransition' | 'beginResourceRetirement' | 'completeResourceRetirement'>;
16
+ terminalHost: IControllerResourceRuntimeHost;
17
+ browserHost: IControllerResourceRuntimeHost;
18
+ isFlexHarnessAvailable(): boolean;
19
+ }
20
+ export declare class ControllerResourceUnavailableError extends Error {
21
+ readonly code = "resource_unavailable";
22
+ constructor(messageArg: string);
23
+ }
24
+ export declare class ControllerProjectHasResourcesError extends Error {
25
+ readonly resourceIds: string[];
26
+ readonly code = "project_has_resources";
27
+ constructor(resourceIds: string[]);
28
+ }
29
+ export declare class ControllerResourceCoordinator {
30
+ private readonly options;
31
+ private readonly projectStates;
32
+ private readonly deletingSessions;
33
+ constructor(options: IControllerResourceCoordinatorOptions);
34
+ listResources(projectIdArg: string): Promise<TControllerResource[]>;
35
+ requireResourceKind(projectIdArg: string, resourceIdArg: string, kindArg: IControllerResourceDocument['kind']): Promise<boolean>;
36
+ createResource(inputArg: Parameters<SmartDataAuthStore['createResource']>[0], signalArg: AbortSignal): Promise<TControllerResource>;
37
+ renameResource(projectIdArg: string, resourceIdArg: string, titleArg: string): Promise<TControllerResource>;
38
+ changeAttachment(inputArg: {
39
+ projectId: string;
40
+ resourceId: string;
41
+ sessionId: TControllerSessionId | null;
42
+ expectedAttachmentRevision: number;
43
+ signal: AbortSignal;
44
+ }): Promise<TControllerResource>;
45
+ retireResource(projectIdArg: string, resourceIdArg: string, signalArg: AbortSignal): Promise<void>;
46
+ startResource(projectIdArg: string, resourceIdArg: string, signalArg: AbortSignal): Promise<TControllerResource>;
47
+ stopResource(projectIdArg: string, resourceIdArg: string, signalArg: AbortSignal): Promise<TControllerResource>;
48
+ recover(signalArg: AbortSignal): Promise<void>;
49
+ withSessionDeletion<T>(projectIdArg: string, sessionIdArg: TControllerSessionId, signalArg: AbortSignal, deleteArg: () => Promise<T>): Promise<T>;
50
+ withProjectRemovalGuard<T>(projectIdArg: string, removeArg: () => Promise<T>): Promise<T>;
51
+ resolveFlexBrowserResources(projectIdArg: string, sessionIdArg: string): Promise<IFlexBrowserResourceDescriptor[]>;
52
+ requireFlexBrowserResource(inputArg: {
53
+ projectId: string;
54
+ sessionId: string;
55
+ resourceId: string;
56
+ attachmentRevision: number;
57
+ }): Promise<IControllerResourceDocument>;
58
+ private reconcilePendingAttachment;
59
+ private toPublicResource;
60
+ private hostFor;
61
+ private projectState;
62
+ private runProjectMutation;
63
+ private sessionKey;
64
+ }