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,1003 @@
1
+ import * as plugins from './plugins.js';
2
+ import { openCodeExpectedVersion, openCodeUsername, } from './interfaces.opencode.js';
3
+ import { createSanitizedRuntimeEnvironment } from './functions.runtimeenvironment.js';
4
+ const defaultStartupTimeoutMs = 20_000;
5
+ const defaultHealthRequestTimeoutMs = 1_500;
6
+ const defaultHealthPollIntervalMs = 150;
7
+ const defaultStopTimeoutMs = 5_000;
8
+ const defaultFinalStopTimeoutMs = 2_000;
9
+ const defaultLogEntryLimit = 200;
10
+ const defaultLogLineByteLimit = 8 * 1024;
11
+ const maxHealthResponseBytes = 32 * 1024;
12
+ const logTruncationSuffix = '… [truncated]';
13
+ const macOsLsofPath = '/usr/sbin/lsof';
14
+ class OpenCodeVersionMismatchError extends Error {
15
+ }
16
+ class OpenCodeListenerOwnershipError extends Error {
17
+ }
18
+ const validateIntegerOption = (value, fallback, name, minimum, maximum) => {
19
+ const selected = value ?? fallback;
20
+ if (!Number.isInteger(selected) || selected < minimum || selected > maximum) {
21
+ throw new Error(`${name} must be an integer between ${minimum} and ${maximum}.`);
22
+ }
23
+ return selected;
24
+ };
25
+ const waitForPauseOrLifecycle = async (milliseconds, lifecycle, signal) => {
26
+ let timeout;
27
+ let abortListener;
28
+ try {
29
+ const outcomes = [
30
+ new Promise((resolve) => {
31
+ timeout = setTimeout(() => resolve(undefined), milliseconds);
32
+ }),
33
+ lifecycle,
34
+ ];
35
+ if (signal) {
36
+ outcomes.push(new Promise((resolve) => {
37
+ if (signal.aborted) {
38
+ resolve({ type: 'abort', reason: signal.reason });
39
+ return;
40
+ }
41
+ abortListener = () => resolve({ type: 'abort', reason: signal.reason });
42
+ signal.addEventListener('abort', abortListener, { once: true });
43
+ }));
44
+ }
45
+ return await Promise.race(outcomes);
46
+ }
47
+ finally {
48
+ if (timeout) {
49
+ clearTimeout(timeout);
50
+ }
51
+ if (signal && abortListener) {
52
+ signal.removeEventListener('abort', abortListener);
53
+ }
54
+ }
55
+ };
56
+ const waitForStartupOperation = async (operation, lifecycle, signal) => {
57
+ let abortListener;
58
+ try {
59
+ const outcomes = [
60
+ operation.then((value) => ({ type: 'value', value }), (error) => ({ type: 'operationError', error })),
61
+ lifecycle.then((outcome) => ({ type: 'lifecycle', outcome })),
62
+ ];
63
+ if (signal) {
64
+ outcomes.push(new Promise((resolve) => {
65
+ if (signal.aborted) {
66
+ resolve({ type: 'abort', reason: signal.reason });
67
+ return;
68
+ }
69
+ abortListener = () => resolve({ type: 'abort', reason: signal.reason });
70
+ signal.addEventListener('abort', abortListener, { once: true });
71
+ }));
72
+ }
73
+ return await Promise.race(outcomes);
74
+ }
75
+ finally {
76
+ if (signal && abortListener) {
77
+ signal.removeEventListener('abort', abortListener);
78
+ }
79
+ }
80
+ };
81
+ const startupAbortError = (reason) => reason instanceof Error
82
+ ? reason
83
+ : new Error('OpenCode startup was aborted.', { cause: reason });
84
+ const waitBounded = async (promise, timeoutMs) => {
85
+ let timeout;
86
+ try {
87
+ return await Promise.race([
88
+ promise.then(() => true),
89
+ new Promise((resolve) => {
90
+ timeout = setTimeout(() => resolve(false), timeoutMs);
91
+ }),
92
+ ]);
93
+ }
94
+ finally {
95
+ if (timeout) {
96
+ clearTimeout(timeout);
97
+ }
98
+ }
99
+ };
100
+ const isMissingProcessError = (errorArg) => typeof errorArg === 'object'
101
+ && errorArg !== null
102
+ && 'code' in errorArg
103
+ && errorArg.code === 'ESRCH';
104
+ const defaultProcessGroupController = {
105
+ isAlive: (processGroupIdArg) => {
106
+ try {
107
+ process.kill(-processGroupIdArg, 0);
108
+ return true;
109
+ }
110
+ catch (errorArg) {
111
+ if (isMissingProcessError(errorArg))
112
+ return false;
113
+ throw errorArg;
114
+ }
115
+ },
116
+ signal: (processGroupIdArg, signalArg) => {
117
+ try {
118
+ process.kill(-processGroupIdArg, signalArg);
119
+ }
120
+ catch (errorArg) {
121
+ if (!isMissingProcessError(errorArg))
122
+ throw errorArg;
123
+ }
124
+ },
125
+ };
126
+ const waitForProcessGroupExit = async (processGroupControllerArg, processGroupIdArg, timeoutMsArg) => {
127
+ const deadline = Date.now() + timeoutMsArg;
128
+ while (await processGroupControllerArg.isAlive(processGroupIdArg)) {
129
+ const remainingMs = deadline - Date.now();
130
+ if (remainingMs <= 0)
131
+ return false;
132
+ await new Promise((resolve) => {
133
+ setTimeout(resolve, Math.min(20, remainingMs));
134
+ });
135
+ }
136
+ return true;
137
+ };
138
+ const truncateLogLine = (value, byteLimit) => {
139
+ if (Buffer.byteLength(value, 'utf8') <= byteLimit) {
140
+ return { line: value, truncated: false };
141
+ }
142
+ const suffixBytes = Buffer.byteLength(logTruncationSuffix, 'utf8');
143
+ const contentBytes = Math.max(0, byteLimit - suffixBytes);
144
+ let line = Buffer.from(value, 'utf8').subarray(0, contentBytes).toString('utf8');
145
+ line = line.replace(/\uFFFD$/u, '');
146
+ return {
147
+ line: `${line}${logTruncationSuffix}`,
148
+ truncated: true,
149
+ };
150
+ };
151
+ const readBoundedResponseText = async (response) => {
152
+ if (!response.body) {
153
+ return '';
154
+ }
155
+ const reader = response.body.getReader();
156
+ const chunks = [];
157
+ let byteLength = 0;
158
+ try {
159
+ while (true) {
160
+ const { done, value } = await reader.read();
161
+ if (done) {
162
+ break;
163
+ }
164
+ byteLength += value.byteLength;
165
+ if (byteLength > maxHealthResponseBytes) {
166
+ await reader.cancel('OpenCode health response exceeded its size limit.');
167
+ throw new Error('OpenCode health response exceeded its size limit.');
168
+ }
169
+ chunks.push(value);
170
+ }
171
+ }
172
+ finally {
173
+ reader.releaseLock();
174
+ }
175
+ const body = new Uint8Array(byteLength);
176
+ let offset = 0;
177
+ for (const chunk of chunks) {
178
+ body.set(chunk, offset);
179
+ offset += chunk.byteLength;
180
+ }
181
+ return new TextDecoder().decode(body);
182
+ };
183
+ const createOpenCodeEnvironment = (password) => {
184
+ const environment = createSanitizedRuntimeEnvironment();
185
+ environment.OPENCODE_SERVER_USERNAME = openCodeUsername;
186
+ environment.OPENCODE_SERVER_PASSWORD = password;
187
+ return environment;
188
+ };
189
+ const isRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value);
190
+ const detectLinuxLibc = () => {
191
+ const report = process.report?.getReport();
192
+ if (isRecord(report)) {
193
+ const header = isRecord(report.header) ? report.header : undefined;
194
+ if (typeof header?.glibcVersionRuntime === 'string' &&
195
+ header.glibcVersionRuntime.length > 0) {
196
+ return 'glibc';
197
+ }
198
+ if (Array.isArray(report.sharedObjects) &&
199
+ report.sharedObjects.some((entry) => typeof entry === 'string' &&
200
+ (entry.includes('/ld-musl-') || entry.includes('/libc.musl-')))) {
201
+ return 'musl';
202
+ }
203
+ }
204
+ if (plugins.fs.existsSync('/etc/alpine-release')) {
205
+ return 'musl';
206
+ }
207
+ throw new Error('Unable to determine whether this Linux runtime uses glibc or musl.');
208
+ };
209
+ const resolvePlatformPackage = () => {
210
+ if (process.platform === 'linux') {
211
+ const libcSuffix = detectLinuxLibc() === 'musl' ? '-musl' : '';
212
+ if (process.arch === 'x64') {
213
+ return {
214
+ packageName: `opencode-linux-x64-baseline${libcSuffix}`,
215
+ binaryName: 'opencode',
216
+ };
217
+ }
218
+ if (process.arch === 'arm64') {
219
+ return {
220
+ packageName: `opencode-linux-arm64${libcSuffix}`,
221
+ binaryName: 'opencode',
222
+ };
223
+ }
224
+ }
225
+ else if (process.platform === 'darwin') {
226
+ if (process.arch === 'x64') {
227
+ return {
228
+ packageName: 'opencode-darwin-x64-baseline',
229
+ binaryName: 'opencode',
230
+ };
231
+ }
232
+ if (process.arch === 'arm64') {
233
+ return {
234
+ packageName: 'opencode-darwin-arm64',
235
+ binaryName: 'opencode',
236
+ };
237
+ }
238
+ }
239
+ else if (process.platform === 'win32') {
240
+ if (process.arch === 'x64') {
241
+ return {
242
+ packageName: 'opencode-windows-x64-baseline',
243
+ binaryName: 'opencode.exe',
244
+ };
245
+ }
246
+ if (process.arch === 'arm64') {
247
+ return {
248
+ packageName: 'opencode-windows-arm64',
249
+ binaryName: 'opencode.exe',
250
+ };
251
+ }
252
+ }
253
+ throw new Error(`OpenCode does not provide a supported package for ${process.platform}/${process.arch}.`);
254
+ };
255
+ const collectLinuxLoopbackListenerInodes = (port) => {
256
+ const portHex = port.toString(16).toUpperCase().padStart(4, '0');
257
+ const expectedAddress = `0100007F:${portHex}`;
258
+ const inodes = new Set();
259
+ const table = plugins.fs.readFileSync('/proc/net/tcp', 'utf8');
260
+ for (const line of table.split('\n').slice(1)) {
261
+ const fields = line.trim().split(/\s+/u);
262
+ if (fields.length >= 10 && fields[1] === expectedAddress && fields[3] === '0A') {
263
+ inodes.add(fields[9]);
264
+ }
265
+ }
266
+ return inodes;
267
+ };
268
+ const verifyLinuxListenerOwnership = (processId, port) => {
269
+ const listenerInodes = collectLinuxLoopbackListenerInodes(port);
270
+ if (listenerInodes.size === 0) {
271
+ return false;
272
+ }
273
+ const descriptorDirectory = `/proc/${processId}/fd`;
274
+ let descriptorNames;
275
+ try {
276
+ descriptorNames = plugins.fs.readdirSync(descriptorDirectory);
277
+ }
278
+ catch (error) {
279
+ if (error.code === 'ENOENT') {
280
+ return false;
281
+ }
282
+ throw new Error(`Unable to inspect OpenCode process ${processId} file descriptors.`, {
283
+ cause: error,
284
+ });
285
+ }
286
+ for (const descriptorName of descriptorNames) {
287
+ let target;
288
+ try {
289
+ target = plugins.fs.readlinkSync(plugins.path.join(descriptorDirectory, descriptorName));
290
+ }
291
+ catch (error) {
292
+ if (error.code === 'ENOENT') {
293
+ continue;
294
+ }
295
+ throw new Error(`Unable to inspect OpenCode process ${processId} socket ownership.`, {
296
+ cause: error,
297
+ });
298
+ }
299
+ const match = /^socket:\[(\d+)\]$/u.exec(target);
300
+ if (match?.[1] && listenerInodes.has(match[1])) {
301
+ return true;
302
+ }
303
+ }
304
+ return false;
305
+ };
306
+ const verifyMacOsListenerOwnership = (processId, port) => {
307
+ const result = plugins.childProcess.spawnSync(macOsLsofPath, [
308
+ '-nP',
309
+ '-a',
310
+ '-p',
311
+ String(processId),
312
+ `-iTCP@127.0.0.1:${port}`,
313
+ '-sTCP:LISTEN',
314
+ '-Fpn',
315
+ ], {
316
+ encoding: 'utf8',
317
+ maxBuffer: 64 * 1024,
318
+ timeout: 1_500,
319
+ windowsHide: true,
320
+ });
321
+ if (result.error) {
322
+ throw new Error('Unable to inspect OpenCode listener ownership with lsof.', {
323
+ cause: result.error,
324
+ });
325
+ }
326
+ if (result.status === 1) {
327
+ return false;
328
+ }
329
+ if (result.status !== 0) {
330
+ throw new Error(`lsof failed while inspecting OpenCode with status ${result.status}.`);
331
+ }
332
+ const lines = result.stdout.split(/\r?\n/u);
333
+ return (lines.includes(`p${processId}`) &&
334
+ lines.some((line) => line === `n127.0.0.1:${port}`));
335
+ };
336
+ const verifyWindowsListenerOwnership = (processId, port) => {
337
+ const systemRoot = process.env.SystemRoot;
338
+ if (!systemRoot || !plugins.path.isAbsolute(systemRoot)) {
339
+ throw new Error('SystemRoot is unavailable for Windows listener ownership verification.');
340
+ }
341
+ const resolvedSystemRoot = plugins.fs.realpathSync.native(systemRoot);
342
+ const netstatPath = plugins.fs.realpathSync.native(plugins.path.join(resolvedSystemRoot, 'System32', 'netstat.exe'));
343
+ const relativeNetstatPath = plugins.path.relative(resolvedSystemRoot, netstatPath);
344
+ if (relativeNetstatPath.startsWith(`..${plugins.path.sep}`) ||
345
+ relativeNetstatPath === '..' ||
346
+ plugins.path.isAbsolute(relativeNetstatPath)) {
347
+ throw new Error('The Windows netstat executable escaped SystemRoot.');
348
+ }
349
+ const result = plugins.childProcess.spawnSync(netstatPath, ['-ano', '-p', 'tcp'], {
350
+ encoding: 'utf8',
351
+ maxBuffer: 2 * 1024 * 1024,
352
+ timeout: 1_500,
353
+ windowsHide: true,
354
+ });
355
+ if (result.error) {
356
+ throw new Error('Unable to inspect OpenCode listener ownership with netstat.', {
357
+ cause: result.error,
358
+ });
359
+ }
360
+ if (result.status !== 0) {
361
+ throw new Error(`netstat failed while inspecting OpenCode with status ${result.status}.`);
362
+ }
363
+ const expectedEndpoint = `127.0.0.1:${port}`;
364
+ return result.stdout.split(/\r?\n/u).some((line) => {
365
+ const fields = line.trim().split(/\s+/u);
366
+ return (fields.length >= 5 &&
367
+ fields[0]?.toUpperCase() === 'TCP' &&
368
+ fields[1] === expectedEndpoint &&
369
+ fields[3]?.toUpperCase() === 'LISTENING' &&
370
+ fields[4] === String(processId));
371
+ });
372
+ };
373
+ export const verifyOpenCodeListenerOwnership = (processId, port) => {
374
+ if (!Number.isSafeInteger(processId) || processId <= 0) {
375
+ return false;
376
+ }
377
+ if (process.platform === 'linux') {
378
+ return verifyLinuxListenerOwnership(processId, port);
379
+ }
380
+ if (process.platform === 'darwin') {
381
+ return verifyMacOsListenerOwnership(processId, port);
382
+ }
383
+ if (process.platform === 'win32') {
384
+ return verifyWindowsListenerOwnership(processId, port);
385
+ }
386
+ throw new Error(`Listener ownership verification is unsupported on ${process.platform}.`);
387
+ };
388
+ export class OpenCodeSupervisor {
389
+ directory;
390
+ port;
391
+ baseUrl;
392
+ executablePath;
393
+ password;
394
+ startupTimeoutMs;
395
+ healthRequestTimeoutMs;
396
+ healthPollIntervalMs;
397
+ stopTimeoutMs;
398
+ finalStopTimeoutMs;
399
+ logEntryLimit;
400
+ logLineByteLimit;
401
+ spawnFactory;
402
+ fetchImplementation;
403
+ listenerOwnershipVerifier;
404
+ processGroupController;
405
+ onChildExit;
406
+ state = 'stopped';
407
+ healthy = false;
408
+ version;
409
+ startedAt;
410
+ child;
411
+ childLifecycle;
412
+ ownedProcessGroupId;
413
+ orphanedProcessGroupId;
414
+ orphanReapTask;
415
+ childExitCleanupPending = false;
416
+ startPromise;
417
+ stopPromise;
418
+ logs = [];
419
+ stdoutAccumulator = {
420
+ decoder: new TextDecoder(),
421
+ partial: '',
422
+ droppingUntilNewline: false,
423
+ };
424
+ stderrAccumulator = {
425
+ decoder: new TextDecoder(),
426
+ partial: '',
427
+ droppingUntilNewline: false,
428
+ };
429
+ constructor(options) {
430
+ this.directory = plugins.fs.realpathSync.native(options.directory);
431
+ const directoryStat = plugins.fs.statSync(this.directory);
432
+ if (!directoryStat.isDirectory()) {
433
+ throw new Error('The configured OpenCode working directory is not a directory.');
434
+ }
435
+ this.port = validateIntegerOption(options.port, options.port, 'OpenCode port', 1, 65_535);
436
+ this.baseUrl = `http://127.0.0.1:${this.port}`;
437
+ this.startupTimeoutMs = validateIntegerOption(options.startupTimeoutMs, defaultStartupTimeoutMs, 'OpenCode startup timeout', 1, 300_000);
438
+ this.healthRequestTimeoutMs = validateIntegerOption(options.healthRequestTimeoutMs, defaultHealthRequestTimeoutMs, 'OpenCode health request timeout', 1, 60_000);
439
+ this.healthPollIntervalMs = validateIntegerOption(options.healthPollIntervalMs, defaultHealthPollIntervalMs, 'OpenCode health poll interval', 1, 60_000);
440
+ this.stopTimeoutMs = validateIntegerOption(options.stopTimeoutMs, defaultStopTimeoutMs, 'OpenCode stop timeout', 1, 300_000);
441
+ this.finalStopTimeoutMs = validateIntegerOption(options.finalStopTimeoutMs, defaultFinalStopTimeoutMs, 'OpenCode final stop timeout', 1, 60_000);
442
+ this.logEntryLimit = validateIntegerOption(options.logEntryLimit, defaultLogEntryLimit, 'OpenCode log entry limit', 1, 10_000);
443
+ this.logLineByteLimit = validateIntegerOption(options.logLineByteLimit, defaultLogLineByteLimit, 'OpenCode log line byte limit', 16, 1024 * 1024);
444
+ this.spawnFactory = options.spawnFactory ?? plugins.childProcess.spawn;
445
+ this.fetchImplementation = options.fetchImplementation ?? globalThis.fetch;
446
+ this.listenerOwnershipVerifier =
447
+ options.listenerOwnershipVerifier ?? verifyOpenCodeListenerOwnership;
448
+ this.processGroupController = process.platform !== 'win32'
449
+ && (options.spawnFactory === undefined || options.processGroupController !== undefined)
450
+ ? (options.processGroupController ?? defaultProcessGroupController)
451
+ : undefined;
452
+ this.onChildExit = options.onChildExit;
453
+ this.password = plugins.crypto.randomBytes(32).toString('base64url');
454
+ this.executablePath = this.resolveExecutablePath();
455
+ }
456
+ getStatus() {
457
+ return {
458
+ state: this.state,
459
+ healthy: this.healthy,
460
+ ...(this.child?.pid ? { pid: this.child.pid } : {}),
461
+ ...(this.version ? { version: this.version } : {}),
462
+ ...(this.startedAt ? { startedAt: this.startedAt } : {}),
463
+ };
464
+ }
465
+ getConnectionConfig() {
466
+ return {
467
+ baseUrl: this.baseUrl,
468
+ directory: this.directory,
469
+ username: openCodeUsername,
470
+ password: this.password,
471
+ };
472
+ }
473
+ getLogSnapshot() {
474
+ return this.logs.map((entry) => ({ ...entry }));
475
+ }
476
+ async start(signal) {
477
+ if (this.state === 'ready' && this.child) {
478
+ return this.getStatus();
479
+ }
480
+ if (this.startPromise) {
481
+ return this.startPromise;
482
+ }
483
+ if (this.state === 'stopping') {
484
+ throw new Error('OpenCode cannot start while it is stopping.');
485
+ }
486
+ const startPromise = this.performStart(signal);
487
+ this.startPromise = startPromise;
488
+ try {
489
+ return await startPromise;
490
+ }
491
+ finally {
492
+ if (this.startPromise === startPromise) {
493
+ this.startPromise = undefined;
494
+ }
495
+ }
496
+ }
497
+ async checkHealth() {
498
+ try {
499
+ const health = await this.fetchHealth();
500
+ this.healthy = true;
501
+ this.version = health.version;
502
+ return health;
503
+ }
504
+ catch (error) {
505
+ this.healthy = false;
506
+ throw error;
507
+ }
508
+ }
509
+ async stop() {
510
+ if (this.stopPromise) {
511
+ return this.stopPromise;
512
+ }
513
+ const child = this.child;
514
+ const lifecycle = this.childLifecycle;
515
+ if (!child || !lifecycle) {
516
+ if (this.ownedProcessGroupId !== undefined) {
517
+ throw new Error('OpenCode process-group ownership outlived child lifecycle tracking.');
518
+ }
519
+ await this.drainOrphanedProcessGroup();
520
+ this.child = undefined;
521
+ this.childLifecycle = undefined;
522
+ this.healthy = false;
523
+ this.state = 'stopped';
524
+ this.startedAt = undefined;
525
+ return;
526
+ }
527
+ const stopPromise = this.performStop(child, lifecycle);
528
+ this.stopPromise = stopPromise;
529
+ try {
530
+ await stopPromise;
531
+ }
532
+ finally {
533
+ if (this.stopPromise === stopPromise) {
534
+ this.stopPromise = undefined;
535
+ }
536
+ }
537
+ }
538
+ resolveExecutablePath() {
539
+ const require = plugins.createRequire(import.meta.url);
540
+ const platformPackage = resolvePlatformPackage();
541
+ const platformPackageJsonPath = plugins.fs.realpathSync.native(require.resolve(`${platformPackage.packageName}/package.json`));
542
+ const installedPackageJson = JSON.parse(plugins.fs.readFileSync(platformPackageJsonPath, 'utf8'));
543
+ if (!isRecord(installedPackageJson) ||
544
+ installedPackageJson.name !== platformPackage.packageName ||
545
+ installedPackageJson.version !== openCodeExpectedVersion) {
546
+ throw new Error(`Expected ${platformPackage.packageName} ${openCodeExpectedVersion}.`);
547
+ }
548
+ const packageDirectory = plugins.fs.realpathSync.native(plugins.path.dirname(platformPackageJsonPath));
549
+ const executablePath = plugins.fs.realpathSync.native(plugins.path.join(packageDirectory, 'bin', platformPackage.binaryName));
550
+ const relativeExecutablePath = plugins.path.relative(packageDirectory, executablePath);
551
+ if (relativeExecutablePath.startsWith(`..${plugins.path.sep}`) ||
552
+ relativeExecutablePath === '..' ||
553
+ plugins.path.isAbsolute(relativeExecutablePath)) {
554
+ throw new Error('The package-owned OpenCode executable escaped its package directory.');
555
+ }
556
+ const executableStat = plugins.fs.statSync(executablePath);
557
+ if (!executableStat.isFile() ||
558
+ (process.platform !== 'win32' && (executableStat.mode & 0o111) === 0)) {
559
+ throw new Error('The package-owned OpenCode executable is not a file.');
560
+ }
561
+ return executablePath;
562
+ }
563
+ async performStart(signal) {
564
+ this.state = 'starting';
565
+ this.healthy = false;
566
+ this.version = undefined;
567
+ this.startedAt = undefined;
568
+ try {
569
+ signal?.throwIfAborted();
570
+ const child = this.spawnFactory(this.executablePath, [
571
+ 'serve',
572
+ '--hostname',
573
+ '127.0.0.1',
574
+ '--port',
575
+ String(this.port),
576
+ '--mdns=false',
577
+ '--print-logs',
578
+ ], {
579
+ cwd: this.directory,
580
+ detached: this.processGroupController !== undefined,
581
+ shell: false,
582
+ windowsHide: true,
583
+ stdio: ['ignore', 'pipe', 'pipe'],
584
+ env: createOpenCodeEnvironment(this.password),
585
+ });
586
+ this.child = child;
587
+ this.childLifecycle = this.observeChild(child);
588
+ if (!child.pid) {
589
+ throw new Error('OpenCode did not provide a process ID after spawn.');
590
+ }
591
+ if (this.processGroupController) {
592
+ this.ownedProcessGroupId = child.pid;
593
+ }
594
+ const deadline = Date.now() + this.startupTimeoutMs;
595
+ let lastHealthError;
596
+ while (Date.now() < deadline) {
597
+ const lifecycle = this.childLifecycle;
598
+ if (!lifecycle) {
599
+ throw new Error('OpenCode child lifecycle tracking was lost.');
600
+ }
601
+ const ownershipOutcome = await waitForStartupOperation(Promise.resolve().then(() => this.listenerOwnershipVerifier(child.pid, this.port)), lifecycle, signal);
602
+ if (ownershipOutcome.type === 'abort') {
603
+ throw startupAbortError(ownershipOutcome.reason);
604
+ }
605
+ if (ownershipOutcome.type === 'lifecycle') {
606
+ throw this.lifecycleError(ownershipOutcome.outcome, 'OpenCode exited during startup.');
607
+ }
608
+ if (ownershipOutcome.type === 'operationError') {
609
+ throw new OpenCodeListenerOwnershipError('OpenCode listener ownership could not be verified.', { cause: ownershipOutcome.error });
610
+ }
611
+ const listenerOwned = ownershipOutcome.value;
612
+ if (!listenerOwned) {
613
+ lastHealthError = new OpenCodeListenerOwnershipError('The loopback listener is not owned by the spawned OpenCode process.');
614
+ const remainingMs = deadline - Date.now();
615
+ if (remainingMs <= 0) {
616
+ break;
617
+ }
618
+ const pauseOutcome = await waitForPauseOrLifecycle(Math.min(this.healthPollIntervalMs, remainingMs), lifecycle, signal);
619
+ if (pauseOutcome) {
620
+ if (pauseOutcome.type === 'abort') {
621
+ throw startupAbortError(pauseOutcome.reason);
622
+ }
623
+ throw this.lifecycleError(pauseOutcome, 'OpenCode exited during startup.');
624
+ }
625
+ continue;
626
+ }
627
+ const healthOutcome = await waitForStartupOperation(this.fetchHealth(signal), lifecycle, signal);
628
+ if (healthOutcome.type === 'abort') {
629
+ throw startupAbortError(healthOutcome.reason);
630
+ }
631
+ if (healthOutcome.type === 'lifecycle') {
632
+ throw this.lifecycleError(healthOutcome.outcome, 'OpenCode exited during startup.');
633
+ }
634
+ if (healthOutcome.type === 'value') {
635
+ const secondOwnershipOutcome = await waitForStartupOperation(Promise.resolve().then(() => this.listenerOwnershipVerifier(child.pid, this.port)), lifecycle, signal);
636
+ if (secondOwnershipOutcome.type === 'abort') {
637
+ throw startupAbortError(secondOwnershipOutcome.reason);
638
+ }
639
+ if (secondOwnershipOutcome.type === 'lifecycle') {
640
+ throw this.lifecycleError(secondOwnershipOutcome.outcome, 'OpenCode exited during startup.');
641
+ }
642
+ if (secondOwnershipOutcome.type === 'operationError') {
643
+ throw new OpenCodeListenerOwnershipError('OpenCode listener ownership could not be reverified.', { cause: secondOwnershipOutcome.error });
644
+ }
645
+ const stillOwned = secondOwnershipOutcome.value;
646
+ if (!stillOwned) {
647
+ throw new OpenCodeListenerOwnershipError('OpenCode lost ownership of its loopback listener during startup.');
648
+ }
649
+ if (child.exitCode !== null || child.signalCode !== null || this.child !== child) {
650
+ throw new Error('OpenCode exited while completing its health check.');
651
+ }
652
+ this.healthy = true;
653
+ this.version = healthOutcome.value.version;
654
+ this.startedAt = Date.now();
655
+ this.state = 'ready';
656
+ return this.getStatus();
657
+ }
658
+ lastHealthError = healthOutcome.error;
659
+ if (lastHealthError instanceof OpenCodeVersionMismatchError) {
660
+ throw lastHealthError;
661
+ }
662
+ const remainingMs = deadline - Date.now();
663
+ if (remainingMs <= 0) {
664
+ break;
665
+ }
666
+ const pauseOutcome = await waitForPauseOrLifecycle(Math.min(this.healthPollIntervalMs, remainingMs), lifecycle, signal);
667
+ if (pauseOutcome) {
668
+ if (pauseOutcome.type === 'abort') {
669
+ throw startupAbortError(pauseOutcome.reason);
670
+ }
671
+ throw this.lifecycleError(pauseOutcome, 'OpenCode exited during startup.');
672
+ }
673
+ }
674
+ throw new Error(`OpenCode did not become healthy within ${this.startupTimeoutMs}ms.`, {
675
+ cause: lastHealthError,
676
+ });
677
+ }
678
+ catch (error) {
679
+ let cleanupError;
680
+ try {
681
+ await this.stop();
682
+ }
683
+ catch (caughtCleanupError) {
684
+ cleanupError = caughtCleanupError;
685
+ }
686
+ this.state = 'failed';
687
+ this.healthy = false;
688
+ this.startedAt = undefined;
689
+ if (cleanupError) {
690
+ throw new AggregateError([error, cleanupError], 'OpenCode startup failed and its child process could not be cleaned up.');
691
+ }
692
+ throw new Error('OpenCode startup failed.', { cause: error });
693
+ }
694
+ }
695
+ /**
696
+ * best-effort reaping of group members that survived their leader's exit.
697
+ * Runs at exit time because that is when the pgid is still provably ours:
698
+ * living members keep it reserved, and an already-empty group answers ESRCH.
699
+ */
700
+ async reapOrphanedGroup(processGroupIdArg) {
701
+ if (!this.processGroupController)
702
+ return;
703
+ if (!(await this.processGroupController.isAlive(processGroupIdArg)))
704
+ return;
705
+ await this.processGroupController.signal(processGroupIdArg, 'SIGTERM');
706
+ let exited = await waitForProcessGroupExit(this.processGroupController, processGroupIdArg, this.stopTimeoutMs);
707
+ if (!exited) {
708
+ await this.processGroupController.signal(processGroupIdArg, 'SIGKILL');
709
+ exited = await waitForProcessGroupExit(this.processGroupController, processGroupIdArg, this.finalStopTimeoutMs);
710
+ }
711
+ if (!exited)
712
+ throw new Error('An owned OpenCode process-group member survived SIGKILL.');
713
+ }
714
+ notifyChildExitCleanup() {
715
+ if (!this.childExitCleanupPending)
716
+ return;
717
+ this.childExitCleanupPending = false;
718
+ try {
719
+ this.onChildExit?.();
720
+ }
721
+ catch {
722
+ // Child lifecycle cleanup must not prevent lifecycle settlement.
723
+ }
724
+ }
725
+ async drainOrphanedProcessGroup() {
726
+ const orphanReapTask = this.orphanReapTask;
727
+ if (orphanReapTask)
728
+ await orphanReapTask;
729
+ const processGroupId = this.orphanedProcessGroupId;
730
+ if (processGroupId !== undefined) {
731
+ await this.reapOrphanedGroup(processGroupId);
732
+ if (this.orphanedProcessGroupId === processGroupId) {
733
+ this.orphanedProcessGroupId = undefined;
734
+ }
735
+ }
736
+ this.notifyChildExitCleanup();
737
+ }
738
+ observeChild(child) {
739
+ child.stdout?.on('data', (chunk) => {
740
+ this.consumeLogChunk('stdout', chunk, this.stdoutAccumulator);
741
+ });
742
+ child.stderr?.on('data', (chunk) => {
743
+ this.consumeLogChunk('stderr', chunk, this.stderrAccumulator);
744
+ });
745
+ return new Promise((resolve) => {
746
+ let settled = false;
747
+ const finish = (outcome) => {
748
+ if (settled) {
749
+ return;
750
+ }
751
+ settled = true;
752
+ this.flushLogAccumulator('stdout', this.stdoutAccumulator);
753
+ this.flushLogAccumulator('stderr', this.stderrAccumulator);
754
+ this.healthy = false;
755
+ // once the group leader is gone the kernel may recycle its pid, so a
756
+ // LATER stop() must never signal this group — but surviving group
757
+ // descendants must still be reaped NOW, while living members keep the
758
+ // pgid reserved and therefore safely targetable
759
+ const orphanedGroupId = this.ownedProcessGroupId;
760
+ this.ownedProcessGroupId = undefined;
761
+ this.childExitCleanupPending = true;
762
+ if (orphanedGroupId !== undefined && this.processGroupController) {
763
+ this.orphanedProcessGroupId = orphanedGroupId;
764
+ let reap;
765
+ reap = this.reapOrphanedGroup(orphanedGroupId).then(() => {
766
+ if (this.orphanedProcessGroupId === orphanedGroupId) {
767
+ this.orphanedProcessGroupId = undefined;
768
+ }
769
+ this.notifyChildExitCleanup();
770
+ }).finally(() => {
771
+ if (this.orphanReapTask === reap)
772
+ this.orphanReapTask = undefined;
773
+ });
774
+ this.orphanReapTask = reap;
775
+ void reap.catch(() => undefined);
776
+ }
777
+ else {
778
+ this.notifyChildExitCleanup();
779
+ }
780
+ if (this.state === 'stopping') {
781
+ this.state = 'stopped';
782
+ }
783
+ else if (this.state === 'starting' || this.state === 'ready') {
784
+ this.state = 'failed';
785
+ }
786
+ resolve(outcome);
787
+ };
788
+ child.once('exit', (code, signal) => {
789
+ finish({ type: 'exit', code, signal });
790
+ });
791
+ child.once('error', (error) => {
792
+ this.addLogEntry('stderr', `OpenCode process error: ${error.message}`, false);
793
+ if (!child.pid) {
794
+ finish({ type: 'error', error });
795
+ }
796
+ });
797
+ });
798
+ }
799
+ async fetchHealth(callerSignal) {
800
+ callerSignal?.throwIfAborted();
801
+ const requestAbortController = new AbortController();
802
+ const abortFromCaller = () => {
803
+ requestAbortController.abort(callerSignal?.reason);
804
+ };
805
+ callerSignal?.addEventListener('abort', abortFromCaller, { once: true });
806
+ if (callerSignal?.aborted) {
807
+ abortFromCaller();
808
+ }
809
+ const timeout = setTimeout(() => {
810
+ requestAbortController.abort(new Error(`OpenCode health request exceeded ${this.healthRequestTimeoutMs}ms.`));
811
+ }, this.healthRequestTimeoutMs);
812
+ timeout.unref();
813
+ const authorization = Buffer.from(`${openCodeUsername}:${this.password}`, 'utf8').toString('base64');
814
+ try {
815
+ const response = await this.fetchImplementation(`${this.baseUrl}/global/health`, {
816
+ method: 'GET',
817
+ headers: {
818
+ Accept: 'application/json',
819
+ Authorization: `Basic ${authorization}`,
820
+ },
821
+ redirect: 'error',
822
+ signal: requestAbortController.signal,
823
+ });
824
+ if (!response.ok) {
825
+ throw new Error(`OpenCode health check returned HTTP ${response.status}.`);
826
+ }
827
+ const body = await readBoundedResponseText(response);
828
+ let parsed;
829
+ try {
830
+ parsed = JSON.parse(body);
831
+ }
832
+ catch (error) {
833
+ throw new Error('OpenCode health check returned invalid JSON.', { cause: error });
834
+ }
835
+ if (typeof parsed !== 'object' ||
836
+ parsed === null ||
837
+ !('healthy' in parsed) ||
838
+ !('version' in parsed) ||
839
+ parsed.healthy !== true ||
840
+ typeof parsed.version !== 'string') {
841
+ throw new Error('OpenCode health check returned an invalid payload.');
842
+ }
843
+ if (parsed.version !== openCodeExpectedVersion) {
844
+ throw new OpenCodeVersionMismatchError(`OpenCode reported version ${parsed.version}; expected ${openCodeExpectedVersion}.`);
845
+ }
846
+ return {
847
+ healthy: true,
848
+ version: openCodeExpectedVersion,
849
+ };
850
+ }
851
+ finally {
852
+ clearTimeout(timeout);
853
+ callerSignal?.removeEventListener('abort', abortFromCaller);
854
+ }
855
+ }
856
+ async performStop(child, lifecycle) {
857
+ this.state = 'stopping';
858
+ this.healthy = false;
859
+ // a leader that already exited cleared ownedProcessGroupId in observeChild
860
+ // and handed surviving members to reapOrphanedGroup, so this branch only
861
+ // ever signals a group whose leader is still ours
862
+ const ownedProcessGroupId = this.ownedProcessGroupId;
863
+ if (this.processGroupController && ownedProcessGroupId !== undefined) {
864
+ let exited = !(await this.processGroupController.isAlive(ownedProcessGroupId));
865
+ if (!exited) {
866
+ await this.processGroupController.signal(ownedProcessGroupId, 'SIGTERM');
867
+ exited = await waitForProcessGroupExit(this.processGroupController, ownedProcessGroupId, this.stopTimeoutMs);
868
+ }
869
+ if (!exited) {
870
+ await this.processGroupController.signal(ownedProcessGroupId, 'SIGKILL');
871
+ exited = await waitForProcessGroupExit(this.processGroupController, ownedProcessGroupId, this.finalStopTimeoutMs);
872
+ }
873
+ if (!exited) {
874
+ this.state = 'failed';
875
+ throw new Error('The owned OpenCode process group did not exit after SIGKILL.');
876
+ }
877
+ const lifecycleSettled = await waitBounded(lifecycle, this.finalStopTimeoutMs);
878
+ if (!lifecycleSettled) {
879
+ this.state = 'failed';
880
+ throw new Error('OpenCode process-group exit was not confirmed by the child lifecycle.');
881
+ }
882
+ this.ownedProcessGroupId = undefined;
883
+ }
884
+ else {
885
+ if (child.exitCode === null && child.signalCode === null) {
886
+ try {
887
+ child.kill('SIGTERM');
888
+ }
889
+ catch (error) {
890
+ if (child.exitCode === null && child.signalCode === null) {
891
+ throw new Error('Failed to send SIGTERM to OpenCode.', { cause: error });
892
+ }
893
+ }
894
+ }
895
+ let exited = await waitBounded(lifecycle, this.stopTimeoutMs);
896
+ if (!exited && child.exitCode === null && child.signalCode === null) {
897
+ try {
898
+ child.kill('SIGKILL');
899
+ }
900
+ catch (error) {
901
+ if (child.exitCode === null && child.signalCode === null) {
902
+ throw new Error('Failed to send SIGKILL to OpenCode.', { cause: error });
903
+ }
904
+ }
905
+ exited = await waitBounded(lifecycle, this.finalStopTimeoutMs);
906
+ }
907
+ if (!exited && child.exitCode === null && child.signalCode === null) {
908
+ this.state = 'failed';
909
+ throw new Error('OpenCode did not exit after SIGKILL.');
910
+ }
911
+ }
912
+ // a leader that exited on its own may have left a reap task running; stop()
913
+ // must not return while owned group members are still being signalled
914
+ await this.drainOrphanedProcessGroup();
915
+ if (this.child === child) {
916
+ this.child = undefined;
917
+ }
918
+ if (this.childLifecycle === lifecycle) {
919
+ this.childLifecycle = undefined;
920
+ }
921
+ this.state = 'stopped';
922
+ this.healthy = false;
923
+ this.startedAt = undefined;
924
+ }
925
+ lifecycleError(outcome, message) {
926
+ if (outcome.type === 'error') {
927
+ return new Error(message, { cause: outcome.error });
928
+ }
929
+ const detail = outcome.signal
930
+ ? `signal ${outcome.signal}`
931
+ : `exit code ${String(outcome.code)}`;
932
+ return new Error(`${message} (${detail})`);
933
+ }
934
+ consumeLogChunk(stream, chunk, accumulator) {
935
+ let bytes;
936
+ if (typeof chunk === 'string') {
937
+ bytes = Buffer.from(chunk, 'utf8');
938
+ }
939
+ else if (chunk instanceof Uint8Array) {
940
+ bytes = chunk;
941
+ }
942
+ else {
943
+ return;
944
+ }
945
+ let text = accumulator.decoder.decode(bytes, { stream: true });
946
+ while (text.length > 0) {
947
+ if (accumulator.droppingUntilNewline) {
948
+ const newlineIndex = text.indexOf('\n');
949
+ if (newlineIndex === -1) {
950
+ return;
951
+ }
952
+ accumulator.droppingUntilNewline = false;
953
+ text = text.slice(newlineIndex + 1);
954
+ continue;
955
+ }
956
+ const newlineIndex = text.indexOf('\n');
957
+ if (newlineIndex !== -1) {
958
+ const completeLine = `${accumulator.partial}${text.slice(0, newlineIndex)}`.replace(/\r$/u, '');
959
+ accumulator.partial = '';
960
+ const bounded = truncateLogLine(completeLine, this.logLineByteLimit);
961
+ this.addLogEntry(stream, bounded.line, bounded.truncated);
962
+ text = text.slice(newlineIndex + 1);
963
+ continue;
964
+ }
965
+ const combined = `${accumulator.partial}${text}`;
966
+ if (Buffer.byteLength(combined, 'utf8') > this.logLineByteLimit) {
967
+ const bounded = truncateLogLine(combined, this.logLineByteLimit);
968
+ this.addLogEntry(stream, bounded.line, true);
969
+ accumulator.partial = '';
970
+ accumulator.droppingUntilNewline = true;
971
+ }
972
+ else {
973
+ accumulator.partial = combined;
974
+ }
975
+ return;
976
+ }
977
+ }
978
+ flushLogAccumulator(stream, accumulator) {
979
+ const finalText = accumulator.decoder.decode();
980
+ if (finalText) {
981
+ this.consumeLogChunk(stream, finalText, accumulator);
982
+ }
983
+ if (accumulator.partial && !accumulator.droppingUntilNewline) {
984
+ const bounded = truncateLogLine(accumulator.partial, this.logLineByteLimit);
985
+ this.addLogEntry(stream, bounded.line, bounded.truncated);
986
+ }
987
+ accumulator.partial = '';
988
+ accumulator.droppingUntilNewline = false;
989
+ }
990
+ addLogEntry(stream, line, truncated) {
991
+ this.logs.push({
992
+ timestamp: Date.now(),
993
+ stream,
994
+ line,
995
+ truncated,
996
+ });
997
+ const excessEntries = this.logs.length - this.logEntryLimit;
998
+ if (excessEntries > 0) {
999
+ this.logs.splice(0, excessEntries);
1000
+ }
1001
+ }
1002
+ }
1003
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5vcGVuY29kZXN1cGVydmlzb3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9jbGFzc2VzLm9wZW5jb2Rlc3VwZXJ2aXNvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGdCQUFnQixHQU9qQixNQUFNLDBCQUEwQixDQUFDO0FBQ2xDLE9BQU8sRUFBRSxpQ0FBaUMsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBRXRGLE1BQU0sdUJBQXVCLEdBQUcsTUFBTSxDQUFDO0FBQ3ZDLE1BQU0sNkJBQTZCLEdBQUcsS0FBSyxDQUFDO0FBQzVDLE1BQU0sMkJBQTJCLEdBQUcsR0FBRyxDQUFDO0FBQ3hDLE1BQU0sb0JBQW9CLEdBQUcsS0FBSyxDQUFDO0FBQ25DLE1BQU0seUJBQXlCLEdBQUcsS0FBSyxDQUFDO0FBQ3hDLE1BQU0sb0JBQW9CLEdBQUcsR0FBRyxDQUFDO0FBQ2pDLE1BQU0sdUJBQXVCLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQztBQUN6QyxNQUFNLHNCQUFzQixHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDekMsTUFBTSxtQkFBbUIsR0FBRyxlQUFlLENBQUM7QUFDNUMsTUFBTSxhQUFhLEdBQUcsZ0JBQWdCLENBQUM7QUFxQnZDLE1BQU0sNEJBQTZCLFNBQVEsS0FBSztDQUFHO0FBQ25ELE1BQU0sOEJBQStCLFNBQVEsS0FBSztDQUFHO0FBRXJELE1BQU0scUJBQXFCLEdBQUcsQ0FDNUIsS0FBeUIsRUFDekIsUUFBZ0IsRUFDaEIsSUFBWSxFQUNaLE9BQWUsRUFDZixPQUFlLEVBQ1AsRUFBRTtJQUNWLE1BQU0sUUFBUSxHQUFHLEtBQUssSUFBSSxRQUFRLENBQUM7SUFDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLElBQUksUUFBUSxHQUFHLE9BQU8sSUFBSSxR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