bdy 1.22.99-stage → 1.23.0-dev

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bdy",
3
3
  "preferGlobal": false,
4
- "version": "1.22.99-stage",
4
+ "version": "1.23.0-dev",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
7
7
  "homepage": "https://buddy.works/docs/cli",
@@ -26,7 +26,8 @@
26
26
  "e2e:pipeline": "vitest run --config e2e/vitest.config.ts e2e/modules/pipeline/",
27
27
  "e2e:tunnel": "vitest run --config e2e/vitest.config.ts e2e/modules/tunnel/",
28
28
  "e2e:agent": "vitest run --config e2e/vitest.config.ts e2e/modules/agent/",
29
- "e2e:distro": "vitest run --config e2e/vitest.config.ts e2e/modules/distro/"
29
+ "e2e:distro": "vitest run --config e2e/vitest.config.ts e2e/modules/distro/",
30
+ "unit": "vitest run --config vitest.config.ts"
30
31
  },
31
32
  "files": [
32
33
  "distTs"
@@ -243,6 +243,14 @@ class Agent extends events_1.default {
243
243
  this.socket.update(!this.disabled, this.getTunnelsUpdate(), force);
244
244
  }
245
245
  }
246
+ // A pending action stays on the agent until an empty one is sent back, and it is
247
+ // re-read on every fetch - so an action that is refused rather than acked would be
248
+ // retried on each refresh instead of once.
249
+ ackAction() {
250
+ if (this.socket) {
251
+ this.socket.fetch(!this.disabled, '', null, false, this.getTunnelsUpdate(), true);
252
+ }
253
+ }
246
254
  async makeAction(action) {
247
255
  if (action === tunnel_1.TUNNEL_AGENT_ACTION.DELETE) {
248
256
  if (this.manager) {
@@ -250,6 +258,19 @@ class Agent extends events_1.default {
250
258
  }
251
259
  return this.delete();
252
260
  }
261
+ if (action === tunnel_1.TUNNEL_AGENT_ACTION.UPDATE) {
262
+ // Without a manager this is a foreground tunnel, not an installed agent, so
263
+ // there is no binary of ours to replace - ack so it is not asked again.
264
+ if (!this.manager)
265
+ return this.ackAction();
266
+ // Deliberately not awaited. Callers use this promise to gate tunnel reconciliation
267
+ // (see _onSocketFetch), and the swap downloads a whole release - awaiting it would
268
+ // leave tunnels unreconciled for the duration, including when the update then
269
+ // fails. selfUpdate guards its own re-entry and reports its own failures, so there
270
+ // is nothing here worth waiting for.
271
+ this.manager.selfUpdate().catch((err) => logger_1.default.error(err));
272
+ return;
273
+ }
253
274
  }
254
275
  refreshTunnels(tunnels) {
255
276
  if (this.tunnelsUpdating)
@@ -21,6 +21,10 @@ class AgentManagerClass {
21
21
  host;
22
22
  token;
23
23
  port;
24
+ updating = false;
25
+ // shutdown() only schedules the exit, so it can be a moment before the process is
26
+ // actually gone. Anything that must not start in that window checks this.
27
+ exiting = false;
24
28
  sshHostKey;
25
29
  agent;
26
30
  ws;
@@ -54,24 +58,134 @@ class AgentManagerClass {
54
58
  start(id, host, token, port, onProcessExit = () => { }) {
55
59
  const onExit = () => {
56
60
  onProcessExit();
57
- if (this.ws) {
58
- this.ws.clients.forEach((client) => client.terminate());
59
- this.ws.close();
60
- }
61
- if (this.server) {
62
- if (!(0, utils_1.isWindows)()) {
63
- this.connections.forEach((socket) => socket.resetAndDestroy());
64
- }
65
- this.server.close(() => {
66
- output_1.default.exitNormal();
67
- });
68
- }
69
- setTimeout(() => output_1.default.exitNormal(), 1000);
61
+ this.shutdown();
70
62
  };
71
63
  process.on('SIGINT', onExit);
72
64
  process.on('SIGTERM', onExit);
73
65
  process.on('SIGQUIT', onExit);
74
- this.load(id, host, token, port).then();
66
+ // Anything load() throws would otherwise be an unhandled rejection: no entry in the
67
+ // agent log, just a stack on stderr that a service swallows. Exit non-zero so the
68
+ // supervisor still retries, but say why first.
69
+ this.load(id, host, token, port).catch((err) => {
70
+ try {
71
+ logger_1.default.error(err);
72
+ }
73
+ catch {
74
+ // best effort - a broken filesystem is a plausible reason for being here at all
75
+ }
76
+ output_1.default.exitError(err);
77
+ });
78
+ }
79
+ // Closes the listener before exiting. A self update depends on this: the supervisor
80
+ // starts the replacement as soon as we are gone, and a port still held by this
81
+ // process would meet it with EADDRINUSE.
82
+ shutdown() {
83
+ this.exiting = true;
84
+ if (this.ws) {
85
+ this.ws.clients.forEach((client) => client.terminate());
86
+ this.ws.close();
87
+ }
88
+ if (this.server) {
89
+ if (!(0, utils_1.isWindows)()) {
90
+ this.connections.forEach((socket) => socket.resetAndDestroy());
91
+ }
92
+ this.server.close(() => {
93
+ output_1.default.exitNormal();
94
+ });
95
+ }
96
+ setTimeout(() => output_1.default.exitNormal(), 1000);
97
+ }
98
+ // Called on every start. If the previous process swapped the binary, this is the
99
+ // first look at whether the new one works. Rolling back is keyed on how many times
100
+ // we have been started since the swap, not on whether the api is reachable: a
101
+ // healthy binary does not restart, while an api outage would look the same from here
102
+ // and would revert the whole fleet at once.
103
+ //
104
+ // Returns false when it has rolled back and this process is on its way out, so the
105
+ // caller must not carry on starting up.
106
+ checkUpdateProbation() {
107
+ const state = this.system.loadUpdateProbation();
108
+ if (!state)
109
+ return true;
110
+ const attempts = this.system.registerUpdateAttempt();
111
+ // The deadline only matters when the count cannot be persisted, in which case it is
112
+ // the sole way out of a restart loop. Checked at startup like the count, so an agent
113
+ // that is up and merely cannot reach the api is never rolled back.
114
+ const expired = Date.now() - state.startedAt > utils_1.AGENT_UPDATE_PROBATION_MS;
115
+ if (attempts <= utils_1.AGENT_UPDATE_MAX_ATTEMPTS && !expired) {
116
+ logger_1.default.info((0, texts_1.LOG_AGENT_UPDATE_ATTEMPT)(attempts, utils_1.AGENT_UPDATE_MAX_ATTEMPTS));
117
+ return true;
118
+ }
119
+ if (!this.system.rollbackUpdate(state.to)) {
120
+ // Nothing to restore, so running the binary we have is the only option left
121
+ logger_1.default.error(texts_1.LOG_AGENT_UPDATE_ROLLBACK_MISSING);
122
+ return true;
123
+ }
124
+ logger_1.default.error((0, texts_1.LOG_AGENT_UPDATE_ROLLED_BACK)(state.from, state.to));
125
+ // Exit rather than keep running: the restored binary only takes effect when the
126
+ // service starts it, and this process is still the new one.
127
+ this.shutdown();
128
+ return false;
129
+ }
130
+ // Triggered remotely through the agent's `action` field. Every path that does not
131
+ // end in a restart has to ack, or the flag stays set on the backend and the update
132
+ // is retried on every refresh.
133
+ async selfUpdate() {
134
+ // `updating` is released in the finally below, but after a swap this process is only
135
+ // scheduled to exit, not gone. A sync push arriving in that window would otherwise
136
+ // re-enter and swap again - and the second swap would move the binary we just
137
+ // installed into the rollback slot, leaving nothing good to roll back to.
138
+ if (this.updating || this.exiting)
139
+ return;
140
+ this.updating = true;
141
+ try {
142
+ if (this.system.isStandaloneInstall()) {
143
+ logger_1.default.error(texts_1.LOG_AGENT_UPDATE_STANDALONE);
144
+ return this.agent?.ackAction();
145
+ }
146
+ const hasAdminRights = await this.system.hasAdminRights();
147
+ if (!hasAdminRights) {
148
+ logger_1.default.error(texts_1.LOG_AGENT_UPDATE_NO_ADMIN);
149
+ return this.agent?.ackAction();
150
+ }
151
+ const current = (0, utils_1.getVersion)();
152
+ const latest = await (0, utils_1.getLatestVersion)();
153
+ if (!latest || latest === '0.0.0' || latest === current) {
154
+ logger_1.default.info((0, texts_1.LOG_AGENT_UPDATE_NOT_NEEDED)(current));
155
+ return this.agent?.ackAction();
156
+ }
157
+ logger_1.default.info((0, texts_1.LOG_AGENT_UPDATE_REQUESTED)(current, latest));
158
+ const target = latest.match(/^\d+\.\d+\.\d+/);
159
+ if (!target) {
160
+ logger_1.default.error(texts_1.LOG_AGENT_UPDATE_FAILED);
161
+ return this.agent?.ackAction();
162
+ }
163
+ const swapped = await this.system.swapBinaryToVersion(target[0]);
164
+ if (!swapped) {
165
+ logger_1.default.error((0, texts_1.LOG_AGENT_UPDATE_BINARY_INVALID)(latest));
166
+ return this.agent?.ackAction();
167
+ }
168
+ try {
169
+ this.system.beginUpdateProbation(current, latest);
170
+ }
171
+ catch (err) {
172
+ // Losing the probation window costs us the rollback, not the update - the new
173
+ // binary is already in place, so carry on rather than restarting into limbo.
174
+ logger_1.default.error(err);
175
+ }
176
+ logger_1.default.info((0, texts_1.LOG_AGENT_UPDATE_SWAPPED)(latest));
177
+ // No ack here: the replacement acks on start, which also reports the new
178
+ // version. Acking now would clear the flag even if the restart never lands.
179
+ this.shutdown();
180
+ }
181
+ catch (err) {
182
+ logger_1.default.error(texts_1.LOG_AGENT_UPDATE_FAILED);
183
+ logger_1.default.error(err);
184
+ this.agent?.ackAction();
185
+ }
186
+ finally {
187
+ this.updating = false;
188
+ }
75
189
  }
76
190
  async tryFetch() {
77
191
  let delay = utils_1.AGENT_FETCH_RETRY_MIN;
@@ -87,6 +201,22 @@ class AgentManagerClass {
87
201
  });
88
202
  await this.agent.start();
89
203
  this.status = tunnel_1.TUNNEL_AGENT_STATUS.ENABLED;
204
+ // Reaching the api is what makes an update stick: drop the previous binary and
205
+ // close the probation window so later restarts are not counted against it.
206
+ const probation = this.system.loadUpdateProbation();
207
+ if (probation) {
208
+ this.system.commitUpdate();
209
+ logger_1.default.info((0, texts_1.LOG_AGENT_UPDATE_COMMITTED)(probation.to));
210
+ }
211
+ // A rollback could not ack for itself: it happens before there is a socket. The
212
+ // action is still set, so without this the restored binary would start the same
213
+ // failing update again right here.
214
+ const pendingAck = this.system.loadPendingAck();
215
+ if (pendingAck) {
216
+ this.system.clearPendingAck();
217
+ this.agent.ackAction();
218
+ logger_1.default.error((0, texts_1.LOG_AGENT_UPDATE_ROLLBACK_ACKED)(pendingAck));
219
+ }
90
220
  return;
91
221
  }
92
222
  catch (err) {
@@ -285,6 +415,9 @@ class AgentManagerClass {
285
415
  id: this.id,
286
416
  status: this.status,
287
417
  version: (0, utils_1.getVersion)(),
418
+ // Lets `bdy agent update` bow out instead of stopping the service from under a
419
+ // swap. Liveness comes for free: if this process is gone, so is the answer.
420
+ updating: this.updating,
288
421
  enabled: !this.agent?.disabled,
289
422
  target: !!this.agent?.target,
290
423
  tunneling: !!this.agent?.tunneling,
@@ -567,9 +700,16 @@ class AgentManagerClass {
567
700
  this.ws = new WsServer({ noServer: true });
568
701
  this.ws.on('connection', (con, id) => this.processWebsocketConnection(con, id));
569
702
  this.server.on('upgrade', (req, socket, head) => this.processUpgrade(req, socket, head));
570
- this.server.on('error', async (err) => {
703
+ this.server.on('error', (err) => {
571
704
  if (err.code === 'EADDRINUSE') {
572
- await this.disableAgentAndExit(texts_1.LOG_ERROR_STARTING_AGENT_SERVER);
705
+ // Exit and let the supervisor retry (systemd Restart=always, launchd
706
+ // KeepAlive, nssm AppExit Restart). Tearing the agent down here would
707
+ // unregister a working agent server-side over a port that is busy for
708
+ // a moment - a restart racing its own predecessor is enough - and the
709
+ // machine would then need a manual reinstall with a new token.
710
+ const msg = (0, texts_1.LOG_ERROR_STARTING_AGENT_SERVER)(this.port || 0);
711
+ logger_1.default.error(msg);
712
+ output_1.default.exitError(msg);
573
713
  }
574
714
  else {
575
715
  logger_1.default.error(err);
@@ -616,6 +756,11 @@ class AgentManagerClass {
616
756
  await this.disableAgentAndExit(texts_1.ERR_SAVING_AGENT_CONFIG);
617
757
  return;
618
758
  }
759
+ // A rolled back update leaves this process exiting: binding the port and opening
760
+ // tunnels on the binary we just replaced would be pointless at best, and a fetch
761
+ // that came back 'agent not found' in that window would unregister us for good.
762
+ if (!this.checkUpdateProbation())
763
+ return;
619
764
  this.createServer();
620
765
  await this.tryFetch();
621
766
  logger_1.default.info(texts_1.LOG_AGENT_STARTED);
@@ -90,7 +90,12 @@ class AgentSystem {
90
90
  .catch(reject);
91
91
  });
92
92
  }
93
+ // The install/`bdy agent update` path, which replaces the binary in place. Any pending
94
+ // self-update probation is void afterwards - it would otherwise judge this binary and
95
+ // could roll back to one two versions old. `swapBinaryToVersion` does not come through
96
+ // here, so its own probation is not affected.
93
97
  extractBinaryArchive() {
98
+ this.clearUpdateFiles();
94
99
  (0, node_fs_1.rmSync)(this.getSystemBinaryPath(), { force: true });
95
100
  return this.extractArchive(this.getBinaryArchivePath(), this.getSystemConfigDir());
96
101
  }
@@ -123,9 +128,18 @@ class AgentSystem {
123
128
  const str = (0, node_fs_1.readFileSync)(this.getNewAgentConfigPath(), 'utf-8');
124
129
  return JSON.parse(str);
125
130
  }
131
+ // Left behind by a self update. They have to go with the rest of the install: a stale
132
+ // probation file would make the next install count restarts against an update that
133
+ // never happened and then 'roll back' to a binary from before the uninstall.
134
+ clearUpdateFiles() {
135
+ (0, node_fs_1.rmSync)(this.getUpdateStatePath(), { force: true });
136
+ (0, node_fs_1.rmSync)(this.getSystemBinaryBackupPath(), { force: true });
137
+ (0, node_fs_1.rmSync)(this.getUpdateTempDir(), { recursive: true, force: true });
138
+ }
126
139
  clearSystemFiles() {
127
140
  (0, node_fs_1.rmSync)(this.getSystemBinaryPath(), { force: true });
128
141
  (0, node_fs_1.rmSync)(this.getSystemConfigPath(), { force: true });
142
+ this.clearUpdateFiles();
129
143
  }
130
144
  clearAgentFiles() {
131
145
  (0, node_fs_1.rmSync)(this.getAgentConfigPath(), { force: true });
@@ -193,15 +207,229 @@ class AgentSystem {
193
207
  });
194
208
  });
195
209
  }
196
- downloadBinaryArchive() {
210
+ // `version` is the bare `x.y.z` of the release to fetch. It defaults to the running
211
+ // one because `bdy agent update` is run by an already-updated cli pushing its own
212
+ // version down; a remotely triggered update runs inside the old agent and has to ask
213
+ // for the target explicitly, or it would re-download what it is already running.
214
+ downloadBinaryArchive(version = (0, utils_1.getCurrentVersionWithoutEnv)()) {
197
215
  const archivePath = this.getBinaryArchivePath();
198
216
  const env = (0, utils_1.getVersionEnv)();
199
- const version = (0, utils_1.getCurrentVersionWithoutEnv)();
200
217
  const archive = this.getBinaryArchive();
201
218
  const url = `https://es.buddy.works/bdy/${env}/${version}/${archive}`;
202
219
  logger_1.default.info(url);
203
220
  return this.downloadFile(url, archivePath);
204
221
  }
222
+ isStandaloneInstall() {
223
+ try {
224
+ // `standalone` is not always stored as a bool, see command/pre.ts
225
+ return !!this.loadSystemConfig().standalone;
226
+ }
227
+ catch {
228
+ // An unreadable config is not a service install we can prove, and swapping the
229
+ // binary of an install we cannot identify is worse than not updating it.
230
+ return true;
231
+ }
232
+ }
233
+ getSystemBinaryBackupPath() {
234
+ return `${this.getSystemBinaryPath()}.old`;
235
+ }
236
+ getUpdateTempDir() {
237
+ return path_1.default.join(this.getSystemConfigDir(), 'update');
238
+ }
239
+ getUpdateStatePath() {
240
+ return path_1.default.join(this.getSystemConfigDir(), 'update.json');
241
+ }
242
+ // Runs the downloaded binary before committing to it. Catches the whole class of
243
+ // failures a checksum would not - wrong architecture, missing shared libraries, a
244
+ // truncated archive - while the working binary is still in place. A binary that
245
+ // cannot run at all could never roll itself back afterwards.
246
+ // `agent selftest` rather than `--version`: it is hermetic, so it cannot be slowed
247
+ // down or confused by an unreachable es.buddy.works, and the version it prints is a
248
+ // contract we own. Comparing that against the release we asked for is the only check
249
+ // there is on the archive actually holding it - nothing is published to verify against.
250
+ verifyBinary(binaryPath, expectedVersion) {
251
+ return new Promise((resolve) => {
252
+ try {
253
+ const { execFile } = require('node:child_process');
254
+ execFile(binaryPath, ['agent', 'selftest'], { timeout: 60000 }, (err, stdout) => {
255
+ if (err)
256
+ return resolve(false);
257
+ // Compare on the bare x.y.z: the channel suffix is derived from the running
258
+ // binary, so it is not something the archive can get wrong.
259
+ const reported = String(stdout || '').match(/\d+\.\d+\.\d+/);
260
+ const wanted = expectedVersion.match(/\d+\.\d+\.\d+/);
261
+ if (!reported || !wanted || reported[0] !== wanted[0]) {
262
+ logger_1.default.error((0, texts_1.LOG_AGENT_UPDATE_VERSION_MISMATCH)(wanted ? wanted[0] : expectedVersion, reported ? reported[0] : String(stdout || '').trim()));
263
+ return resolve(false);
264
+ }
265
+ resolve(true);
266
+ });
267
+ }
268
+ catch {
269
+ // execFile throws synchronously rather than calling back when the file cannot be
270
+ // executed at all - ENOEXEC on a wrong-architecture or truncated download, which
271
+ // is the case this check exists for.
272
+ resolve(false);
273
+ }
274
+ });
275
+ }
276
+ // Written after the swap and read by the process the service starts next, so the
277
+ // attempt count survives a restart loop - each failed start is a new process and
278
+ // could not otherwise know how many came before it.
279
+ beginUpdateProbation(from, to) {
280
+ this.writeUpdateState({ from, to, attempts: 0, startedAt: Date.now() });
281
+ }
282
+ writeUpdateState(state) {
283
+ (0, node_fs_1.writeFileSync)(this.getUpdateStatePath(), JSON.stringify(state), {
284
+ encoding: 'utf-8',
285
+ });
286
+ try {
287
+ (0, node_fs_1.chmodSync)(this.getUpdateStatePath(), 0o666);
288
+ }
289
+ catch {
290
+ // do nothing
291
+ }
292
+ }
293
+ readUpdateState() {
294
+ try {
295
+ return JSON.parse((0, node_fs_1.readFileSync)(this.getUpdateStatePath(), 'utf-8'));
296
+ }
297
+ catch {
298
+ return null;
299
+ }
300
+ }
301
+ loadUpdateProbation() {
302
+ const json = this.readUpdateState();
303
+ if (!json || typeof json.attempts !== 'number')
304
+ return null;
305
+ return {
306
+ ...json,
307
+ // A file written before startedAt existed must not read as long expired
308
+ startedAt: typeof json.startedAt === 'number' ? json.startedAt : Date.now(),
309
+ };
310
+ }
311
+ registerUpdateAttempt() {
312
+ const state = this.loadUpdateProbation();
313
+ if (!state)
314
+ return 0;
315
+ const next = state.attempts + 1;
316
+ try {
317
+ this.writeUpdateState({ ...state, attempts: next });
318
+ }
319
+ catch {
320
+ // Report what is actually stored rather than forcing a rollback: an unwritable
321
+ // state file says nothing about the new binary, and the probation deadline is the
322
+ // backstop for a count that can never advance.
323
+ return state.attempts;
324
+ }
325
+ return next;
326
+ }
327
+ // Left by a rollback so the restored agent can clear the action that caused it. Without
328
+ // it the flag is still set when the old binary comes up, and it would start the same
329
+ // failing update again on its first fetch.
330
+ loadPendingAck() {
331
+ const json = this.readUpdateState();
332
+ if (!json || typeof json.ackPending !== 'string')
333
+ return null;
334
+ return json.ackPending;
335
+ }
336
+ clearPendingAck() {
337
+ (0, node_fs_1.rmSync)(this.getUpdateStatePath(), { force: true });
338
+ }
339
+ commitUpdate() {
340
+ (0, node_fs_1.rmSync)(this.getUpdateStatePath(), { force: true });
341
+ (0, node_fs_1.rmSync)(this.getSystemBinaryBackupPath(), { force: true });
342
+ }
343
+ tryClearUpdateState() {
344
+ try {
345
+ (0, node_fs_1.rmSync)(this.getUpdateStatePath(), { force: true });
346
+ }
347
+ catch (err) {
348
+ logger_1.default.error(err);
349
+ }
350
+ }
351
+ // Nothing in here may throw. It runs from load(), where an exception would surface as
352
+ // an unhandled rejection and take the process down - and the probation file would still
353
+ // be in place, so every restart would reach the same throw. That is a permanent crash
354
+ // loop in the code whose whole job is getting out of one.
355
+ rollbackUpdate(to) {
356
+ const backup = this.getSystemBinaryBackupPath();
357
+ if (!(0, node_fs_1.existsSync)(backup)) {
358
+ // Nothing to restore, so the probation is over either way - leaving it would count
359
+ // attempts against an update that cannot be undone. No ack is needed here: the
360
+ // agent keeps running the new binary, so its version now matches the target and
361
+ // the next update request resolves itself as 'already current'.
362
+ this.tryClearUpdateState();
363
+ return false;
364
+ }
365
+ try {
366
+ (0, node_fs_1.renameSync)(backup, this.getSystemBinaryPath());
367
+ }
368
+ catch (err) {
369
+ // The filesystem is refusing writes, so there is no way back to the old binary.
370
+ // Give the probation up rather than meet this again on every start; the caller
371
+ // keeps running the binary that is installed, which is the only option left.
372
+ logger_1.default.error(err);
373
+ this.tryClearUpdateState();
374
+ return false;
375
+ }
376
+ try {
377
+ this.writeUpdateState({ ackPending: to });
378
+ }
379
+ catch {
380
+ // Better to lose the ack than the rollback - the binary is already restored
381
+ logger_1.default.error(texts_1.LOG_ERROR_SAVING_AGENT_SYSTEM_CONFIG);
382
+ }
383
+ return true;
384
+ }
385
+ // Unlike extractBinaryArchive this never deletes the live binary: it stages the new
386
+ // one next to it and swaps by rename. POSIX keeps the running process on its old
387
+ // inode, and Windows allows renaming a running exe even though it forbids deleting
388
+ // one - so the swap works while the agent is still up, and a crash mid-download
389
+ // leaves a working install behind instead of an empty path the service restarts into.
390
+ async swapBinaryToVersion(version) {
391
+ const tmp = this.getUpdateTempDir();
392
+ const target = this.getSystemBinaryPath();
393
+ const backup = this.getSystemBinaryBackupPath();
394
+ (0, node_fs_1.rmSync)(tmp, { recursive: true, force: true });
395
+ (0, node_fs_1.mkdirSync)(tmp, { recursive: true });
396
+ try {
397
+ await this.downloadBinaryArchive(version);
398
+ await this.extractArchive(this.getBinaryArchivePath(), tmp);
399
+ const staged = path_1.default.join(tmp, path_1.default.basename(target));
400
+ if (!(0, node_fs_1.existsSync)(staged)) {
401
+ throw new Error(`Archive did not contain '${path_1.default.basename(target)}'`);
402
+ }
403
+ (0, node_fs_1.chmodSync)(staged, 0o777);
404
+ const runs = await this.verifyBinary(staged, version);
405
+ if (!runs)
406
+ return false;
407
+ // Last check before touching the live binary. The download and the smoke test take
408
+ // long enough for an uninstall to have run in the meantime, and finishing the swap
409
+ // then would put a binary back for an agent that is deliberately gone.
410
+ if (!(0, node_fs_1.existsSync)(this.getSystemConfigPath())) {
411
+ throw new Error(texts_1.LOG_AGENT_UPDATE_UNINSTALLED);
412
+ }
413
+ (0, node_fs_1.rmSync)(backup, { force: true });
414
+ if ((0, node_fs_1.existsSync)(target))
415
+ (0, node_fs_1.renameSync)(target, backup);
416
+ try {
417
+ (0, node_fs_1.renameSync)(staged, target);
418
+ }
419
+ catch (err) {
420
+ // Put the old binary back rather than leaving the service with no target
421
+ if ((0, node_fs_1.existsSync)(backup))
422
+ (0, node_fs_1.renameSync)(backup, target);
423
+ throw err;
424
+ }
425
+ await this.fixBinaryRights();
426
+ return true;
427
+ }
428
+ finally {
429
+ (0, node_fs_1.rmSync)(tmp, { recursive: true, force: true });
430
+ (0, node_fs_1.rmSync)(this.getBinaryArchivePath(), { force: true });
431
+ }
432
+ }
205
433
  killStandaloneProc() {
206
434
  return new Promise((resolve) => {
207
435
  let pid = 0;
@@ -56,6 +56,7 @@ class AgentWindows extends system_1.default {
56
56
  clearSystemFiles() {
57
57
  (0, fs_1.rmSync)(this.getSystemBinaryPath(), { force: true });
58
58
  (0, fs_1.rmSync)(this.getSystemConfigPath(), { force: true });
59
+ this.clearUpdateFiles();
59
60
  (0, fs_1.rmSync)(path_1.default.join(this.getSystemConfigDir(), 'nssm'), {
60
61
  force: true,
61
62
  recursive: true,
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const output_1 = __importDefault(require("../../output"));
7
+ const utils_1 = require("../../utils");
8
+ // Machine-invoked and hidden, like `agent run`. A freshly downloaded binary is executed
9
+ // with this before it is allowed to replace the installed one (AgentSystem.verifyBinary),
10
+ // so it has to stay hermetic: skipPre keeps out the latest-version fetch and the probe of
11
+ // the running agent, leaving exit 0 to mean exactly one thing - this binary runs here.
12
+ // The version it prints is what tells the caller the archive held the release it asked
13
+ // for; nothing else may be written to stdout.
14
+ const commandAgentSelftest = (0, utils_1.newCommand)('selftest');
15
+ commandAgentSelftest.skipPre = true;
16
+ commandAgentSelftest.action(async () => {
17
+ // Not exitNormal(): that exits the moment the write is queued, and stdout is a pipe
18
+ // here, so the version could be lost before it is flushed.
19
+ output_1.default.normal((0, utils_1.getVersion)());
20
+ });
21
+ exports.default = commandAgentSelftest;
@@ -19,6 +19,11 @@ commandAgentUpdate.action(async () => {
19
19
  if (!commandAgentUpdate.agentInstalled) {
20
20
  output_1.default.exitError(texts_1.ERR_AGENT_NOT_INSTALLED);
21
21
  }
22
+ // A remote update is already swapping the binary. Carrying on would stop the service
23
+ // from under it, so bow out instead - the running agent finishes and restarts itself.
24
+ if (commandAgentUpdate.agentStatus?.updating) {
25
+ output_1.default.exitError(texts_1.ERR_AGENT_UPDATE_IN_PROGRESS);
26
+ }
22
27
  output_1.default.normal(texts_1.TXT_UPDATING_AGENT);
23
28
  if (commandAgentUpdate.agentStandalone) {
24
29
  // app
@@ -14,6 +14,7 @@ const uninstall_1 = __importDefault(require("./agent/uninstall"));
14
14
  const version_1 = __importDefault(require("./agent/version"));
15
15
  const texts_1 = require("../texts");
16
16
  const run_1 = __importDefault(require("./agent/run"));
17
+ const selftest_1 = __importDefault(require("./agent/selftest"));
17
18
  const utils_1 = require("../utils");
18
19
  const target_1 = __importDefault(require("./agent/target"));
19
20
  const enable_1 = __importDefault(require("./agent/enable"));
@@ -40,4 +41,5 @@ commandAgent.addCommand(user_1.default);
40
41
  commandAgent.addCommand(version_1.default);
41
42
  commandAgent.addCommand(debug_1.default);
42
43
  commandAgent.addCommand(run_1.default, { hidden: true });
44
+ commandAgent.addCommand(selftest_1.default, { hidden: true });
43
45
  exports.default = commandAgent;
@@ -9,16 +9,16 @@ exports.OPTION_PIPELINE_RUN_TAG = exports.OPTION_PIPELINE_RUN_BRANCH = exports.O
9
9
  exports.OPTION_WHITELIST = exports.OPTION_REST_API_PER_PAGE = exports.OPTION_REST_API_PAGE = exports.OPTION_REST_API_PROJECT = exports.OPTION_REST_API_WORKSPACE = exports.OPTION_FORMAT_JSONL = exports.OPTION_FORMAT = exports.OPTION_VERSION = exports.OPTION_PIPELINE_RUN_NO_FOLLOW = exports.OPTION_PIPELINE_RUN_NO_WAIT = exports.OPTION_PIPELINE_RUN_ACTION = exports.OPTION_REST_API_TOKEN = exports.OPTION_ARTIFACT_DOWNLOAD_REPLACE = exports.OPTION_ARTIFACT_DOWNLOAD_MERGE = exports.OPTION_ARTIFACT_PUBLISH_OVERWRITE_VERSION = exports.OPTION_ARTIFACT_VERSION_AGENT_NOTE = exports.OPTION_ARTIFACT_VERSION_NOTE = exports.OPTION_ARTIFACT_VERSION_FROM = exports.OPTION_ARTIFACT_PUBLISH_CREATE = exports.OPTION_ARTIFACT_ID = exports.OPTION_ARTIFACT_DOWNLOAD_PATH = exports.OPTION_ARTIFACT_PUBLISH_PATH = exports.OPTION_PIPELINE_RUN_ACTION_ID = exports.OPTION_PIPELINE_RUN_ID = exports.OPTION_PIPELINE_YAML = exports.TXT_PIPELINE_DELETED = exports.TXT_PIPELINE_DELETE_CONFIRM = exports.TXT_PIPELINE_UPDATED = exports.TXT_PIPELINE_CREATED = exports.OPTION_PIPELINE_NAME = exports.OPTION_PIPELINE_IDENTIFIER = exports.OPTION_PIPELINE_RUN_ARTIFACT = exports.OPTION_PIPELINE_RUN_ENVIRONMENT = exports.OPTION_PIPELINE_RUN_DELAY = exports.OPTION_PIPELINE_RUN_PAYLOAD = exports.ERR_RUN_PAYLOAD_TOO_MANY_FILES = exports.ERR_RUN_PAYLOAD_NOT_UPLOADED = exports.ERR_RUN_PAYLOAD_TOO_LARGE = exports.ERR_RUN_PAYLOAD_NO_ENTRIES = exports.ERR_RUN_VAR_FILE_INVALID = exports.ERR_RUN_VAR_FILE_NOT_FOUND = exports.OPTION_RUN_SINGLE_VAR_FILE = exports.OPTION_RUN_VAR_FILE = exports.OPTION_RUN_VAR = exports.OPTION_PIPELINE_RUN_PRIORITY = exports.OPTION_PIPELINE_RUN_CLEAR_CACHE = exports.OPTION_PIPELINE_RUN_REFRESH = exports.OPTION_PIPELINE_RUN_COMMENT = exports.OPTION_PIPELINE_RUN_PULL_REQUEST = exports.OPTION_PIPELINE_RUN_REVISION = void 0;
10
10
  exports.OPTION_COMPARE_COOKIE = exports.OPTION_COMPARE_IGNORE = exports.OPTION_COMPARE_IGNORE_URLS = exports.OPTION_COMPARE_DRY_RUN = exports.OPTION_COMPARE_URLS_FILE = exports.OPTION_COMPARE_SITEMAP = exports.OPTION_COMPARE_URLS = exports.OPTION_COMPARE_RESPECT_ROBOTS = exports.OPTION_COMPARE_FOLLOW = exports.OPTION_EXEC_PARALLEL = exports.OPTION_EXEC_ONE_BY_ONE = exports.OPTION_EXEC_SKIP_DISCOVERY = exports.OPTION_EXEC_COMMAND = exports.OPTION_AGENT_DEBUG = exports.OPTION_AGENT_PORT = exports.OPTION_AGENT_TAG = exports.OPTION_AGENT_TUNNELING = exports.OPTION_AGENT_PROXY = exports.OPTION_AGENT_TARGET = exports.OPTION_PASS = exports.OPTION_APP = exports.OPTION_USER = exports.OPTION_AGENT_TOKEN = exports.OPTION_AGENT_START = exports.OPTION_AGENT_ID = exports.OPTION_ID = exports.OPTION_NAME = exports.OPTION_TARGET = exports.OPTION_TLS_TERMINATE = exports.OPTION_TLS_CA = exports.OPTION_TLS_CERT = exports.OPTION_TLS_KEY = exports.OPTION_HTTP_CIRCUIT_BREAKER = exports.OPTION_HTTP_COMPRESSION = exports.OPTION_HTTP_2 = exports.OPTION_HTTP_VERIFY = exports.OPTION_HTTP_LOG = exports.OPTION_HTTP_AUTH_BUDDY = exports.OPTION_HTTP_AUTH = exports.OPTION_HTTP_HOST = exports.OPTION_CONFIRM_DOMAIN_BUY = exports.OPTION_CONFIRM_FORCE = exports.OPTION_FORCE = exports.OPTION_TOKEN = exports.OPTION_TIMEOUT = exports.OPTION_FOLLOW = exports.OPTION_SERVE = exports.OPTION_HEADER_USER_AGENT = exports.OPTION_RESPONSE_HEADER = exports.OPTION_HEADER = void 0;
11
11
  exports.LOG_DISABLING_AGENT_TUNNELING = exports.LOG_DISABLING_AGENT_PROXY = exports.LOG_DISABLING_AGENT_TARGET = exports.LOG_REMOVING_TUNNEL = exports.LOG_TUNNEL_REGISTERED = exports.LOG_ERROR_WHILE_REFRESHING_AGENT = exports.LOG_REGISTERING_TUNNEL = exports.LOG_GETTING_AGENT = exports.LOG_UNREGISTERING_AGENT = exports.LOG_REGION_DETECTED = exports.LOG_AGENT_REGISTERED = exports.LOG_SOCKET_DISCONNECTED = exports.LOG_SOCKET_CONNECTED = exports.LOG_AGENT_NSSM_CLEARING = exports.LOG_AGENT_NSSM_EXTRACTING = exports.LOG_AGENT_NSSM_DOWNLOADING = exports.LOG_AGENT_ENABLED = exports.LOG_AGENT_STARTING_SYSTEM = exports.LOG_AGENT_STOPPING_SYSTEM = exports.LOG_AGENT_ENABLING_SYSTEM = exports.LOG_AGENT_SYSTEM_SERVICE_CONFIG = exports.LOG_AGENT_EXTRACTING_ARCHIVE = exports.LOG_AGENT_DOWNLOADING_ARCHIVE = exports.LOG_AGENT_SYSTEM_DIR = exports.LOG_ERROR_SAVING_AGENT_LOCAL_CONFIG = exports.LOG_ERROR_REMOVING_AGENT_STANDALONE_LOCK_FILE = exports.LOG_ERROR_SAVING_AGENT_STANDALONE_CONFIG = exports.LOG_ERROR_SAVING_AGENT_SYSTEM_CONFIG = exports.LOG_SAVING_AGENT_LOCAL_CONFIG = exports.LOG_REMOVING_AGENT_PROC_ID = exports.LOG_SAVING_AGENT_PROC_ID = exports.LOG_SAVING_AGENT_SYSTEM_CONFIG = exports.LOG_REGISTERING_AGENT = exports.OPTION_CRAWL_OUTPUT_TYPES = exports.OPTION_CRAWL_OUTPUT_DIR = exports.OPTION_CRAWL_DELAY = exports.OPTION_CRAWL_LOCAL_STORAGE = exports.OPTION_CRAWL_DEVICES = exports.OPTION_CRAWL_BROWSERS = exports.OPTION_CRAWL_COLOR_SCHEME = exports.OPTION_CRAWL_XPATH_SELECTOR = exports.OPTION_CRAWL_CSS_SELECTOR = exports.OPTION_CRAWL_FULL_PAGE = exports.OPTION_CRAWL_QUALITY = exports.OPTION_CRAWL_OUTPUT_TYPE = exports.OPTION_CRAWL_FOLLOW = exports.OPTION_CRAWL_URL = exports.OPTION_COMPARE_WAIT_FOR = exports.OPTION_COMPARE_DELAY = exports.OPTION_COMPARE_HEADER = void 0;
12
- exports.DEBUG_WAIT_FOR_IDLE = exports.DEBUG_RESOURCE_DISCOVERY_TIMEOUT = exports.DEBUG_AUTO_WIDTH = exports.DEBUG_AUTO_SCROLL = exports.DEBUG_RESOURCE_CRAWLING_URL = exports.DEBUG_SNAPSHOT_PROCESSING = exports.DEBUG_SNAPSHOTS_PROCESSING = exports.DEBUG_EXEC_COMMAND = exports.DEBUG_EXEC_TEST_COMMAND = exports.LOG_INSTALLED_BROWSER = exports.LOG_SESSION_LINK = exports.LOG_SENDING_DATA = exports.LOG_SENDING_REQUEST = exports.LOG_PROCESSING_SNAPSHOTS = exports.LOG_RUNNING_EXEC_COMMAND = exports.LOG_TUNNEL_SSH_STREAM = exports.LOG_TUNNEL_TLS_AGENT_STREAM = exports.LOG_TUNNEL_TLS_REGION_STREAM = exports.LOG_TUNNEL_TLS_TARGET_STREAM = exports.LOG_TUNNEL_HTTP2_STREAM = exports.LOG_TUNNEL_HTTP1_STREAM = exports.LOG_TUNNEL_TCP_STREAM = exports.LOG_TUNNEL_HTTP_WRONG_USER_AGENTS = exports.LOG_TUNNEL_HTTP_CIRCUIT_BREAKER_OPEN = exports.LOG_TUNNEL_HTTP_MAX_INFLIGHT = exports.LOG_TUNNEL_HTTP_RATE_LIMIT = exports.LOG_TUNNEL_HTTP_WRON_AUTH = exports.LOG_TUNNEL_IDENTIFIED = exports.LOG_TUNNEL_DISCONNECTED = exports.LOG_TUNNEL_FAILED = exports.LOG_TUNNEL_CONNECTED = exports.LOG_AGENT_STARTED = exports.LOG_AGENT_SERVER_STARTED = exports.LOG_ERROR_STARTING_AGENT_SERVER = exports.LOG_SSH_CONNECTION = exports.LOG_LATE_TARGET_ERROR = exports.LOG_LATE_CHANNEL_ERROR = exports.LOG_HANDSHAKE_TIMEOUT = exports.LOG_WRONG_STREAM = exports.LOG_DETECTED_STREAM = exports.LOG_HTTP2_REQUEST = exports.LOG_HTTP2_CONNECTION = exports.LOG_HTTP1_REQUEST = exports.LOG_HTTP1_CONNECTION = exports.LOG_ERROR = exports.LOG_STOPPING_TUNNEL = exports.LOG_STARTING_TUNNEL = exports.LOG_ENABLING_AGENT_TUNNELING = exports.LOG_ENABLING_AGENT_PROXY = exports.LOG_ENABLING_AGENT_TARGET = void 0;
13
- exports.ERR_SANDBOX_STOP_FAILED = exports.ERR_SANDBOX_SSH_MISSING = exports.ERR_SANDBOX_SSH_NO_ACCESS = exports.ERR_SANDBOX_NOT_RUNNING = exports.ERR_SANDBOX_NO_COMMANDS = exports.ERR_SANDBOX_RUNNING_FAILED = exports.ERR_SANDBOX_STOP_TIMEOUT = exports.ERR_SANDBOX_SNAPSHOT_TIMEOUT = exports.ERR_SANDBOX_RUNNING_TIMEOUT = exports.ERR_SANDBOX_APPS_TIMEOUT = exports.ERR_SANDBOX_SETUP_TIMEOUT = exports.ERR_SANDBOX_APP_FAILED = exports.ERR_SANDBOX_SETUP_FAILED = exports.ERR_SANDBOX_INVALID_RESOURCES = exports.ERR_SANDBOX_APP_NOT_FOUND = exports.ERR_SANDBOX_NOT_FOUND = exports.OPTION_SANDBOX_SSH_PRINT = exports.OPTION_SANDBOX_SSH_IDENTITY = exports.OPTION_SANDBOX_SSH_ARGS = exports.OPTION_SANDBOX_RUNTIME = exports.OPTION_SANDBOX_TIMEOUT = exports.OPTION_SANDBOX_FETCH = exports.OPTION_SANDBOX_APP_DIR = exports.OPTION_SANDBOX_APP_COMMAND = exports.OPTION_SANDBOX_YAML = exports.OPTION_SANDBOX_TAGS = exports.OPTION_SANDBOX_INSTALL_SCRIPT = exports.OPTION_SANDBOX_INSTALL_COMMANDS = exports.OPTION_SANDBOX_RESOURCES = exports.OPTION_SANDBOX_OS = exports.OPTION_SANDBOX_AGENT_NOTE = exports.OPTION_SANDBOX_NOTE = exports.OPTION_SANDBOX_NAME = exports.OPTION_SANDBOX_IDENTIFIER = exports.DESC_COMMAND_SANDBOX_SSH = exports.DESC_COMMAND_SANDBOX_APP = exports.DESC_COMMAND_SANDBOX_EXEC = exports.DESC_COMMAND_SANDBOX_STATUS = exports.DESC_COMMAND_SANDBOX_LOGS = exports.DESC_COMMAND_SANDBOX_RESTART = exports.DESC_COMMAND_SANDBOX_STOP = exports.DESC_COMMAND_SANDBOX_START = exports.DESC_COMMAND_SANDBOX_DESTROY = exports.DESC_COMMAND_SANDBOX_GET = exports.DESC_COMMAND_SANDBOX_LIST = exports.DESC_COMMAND_SANDBOX_UPDATE = exports.DESC_COMMAND_SANDBOX_GET_YAML = exports.DESC_COMMAND_SANDBOX_CREATE = exports.DESC_COMMAND_SANDBOX = exports.DEBUG_WAIT_FOR_IDLE_TIMEOUT = void 0;
14
- exports.DESC_COMMAND_SANDBOX_ENDPOINT = exports.ERR_SANDBOX_SNAPSHOTS_NOT_FOUND = exports.ERR_SANDBOX_SNAPSHOT_NOT_FOUND = exports.ERR_SANDBOX_SNAPSHOT_FAILED = exports.TXT_SANDBOX_SNAPSHOT_WAITING = exports.TXT_SANDBOX_SNAPSHOT_DELETE_CONFIRM = exports.TXT_SANDBOX_SNAPSHOT_DELETED = exports.TXT_SANDBOX_SNAPSHOT_CREATED = exports.OPTION_SANDBOX_FROM_SNAPSHOT = exports.OPTION_SANDBOX_SNAPSHOT_NAME_ARG = exports.OPTION_SANDBOX_SNAPSHOT_NAME = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_DELETE = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_GET = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_CREATE = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_LIST = exports.DESC_COMMAND_SANDBOX_SNAPSHOT = exports.TXT_SANDBOX_COMMAND_KILLED = exports.OPTION_SANDBOX_COMMAND_KILL_CONFIRM = exports.OPTION_SANDBOX_LOGS_LIMIT = exports.OPTION_SANDBOX_APP_ID = exports.OPTION_SANDBOX_COMMAND_ID = exports.DESC_COMMAND_SANDBOX_EXEC_KILL = exports.DESC_COMMAND_SANDBOX_EXEC_LOGS = exports.DESC_COMMAND_SANDBOX_APP_START = exports.DESC_COMMAND_SANDBOX_APP_STOP = exports.DESC_COMMAND_SANDBOX_APP_STATUS = exports.DESC_COMMAND_SANDBOX_APP_LOGS = exports.DESC_COMMAND_SANDBOX_EXEC_STATUS = exports.DESC_COMMAND_SANDBOX_EXEC_LIST = exports.DESC_COMMAND_SANDBOX_APP_REMOVE = exports.DESC_COMMAND_SANDBOX_APP_ADD = exports.DESC_COMMAND_SANDBOX_APP_LIST = exports.TXT_SANDBOX_WAITING_START = exports.TXT_SANDBOX_WAITING_STOP = exports.TXT_SANDBOX_WAITING_APPS = exports.TXT_SANDBOX_WAITING_SETUP = exports.TXT_SANDBOX_WAITING_RUNNING = exports.TXT_SANDBOX_STOPPED = exports.TXT_SANDBOX_STARTED = exports.TXT_SANDBOX_DESTROYED = exports.TXT_SANDBOX_DESTROY_CONFIRM = exports.TXT_SANDBOX_UPDATED = exports.TXT_SANDBOX_CREATED = exports.TXT_SANDBOX_CREATING = exports.TXT_SANDBOX_APP_STARTED = exports.TXT_SANDBOX_APP_STOPPED = exports.OPTION_SANDBOX_WAIT = exports.OPTION_SANDBOX_WAIT_APPS = exports.OPTION_SANDBOX_WAIT_CONFIGURED = exports.OPTION_SANDBOX_WAIT_RUNNING = void 0;
15
- exports.DESC_COMMAND_API_POST = exports.DESC_COMMAND_API_LIST = exports.DESC_COMMAND_API = exports.ERR_WHOAMI_LOGOUT = exports.TXT_WHOAMI_NO_WORKSPACE = exports.DESC_COMMAND_WHOAMI = exports.TXT_SANDBOX_EXEC_FAILED = exports.TXT_SANDBOX_EXEC_INPROGRESS = exports.TXT_SANDBOX_EXEC_SUCCESS = exports.TXT_SANDBOX_EXEC_BACKGROUND = exports.TXT_SANDBOX_EXEC_ID = exports.ERR_SANDBOX_CP_INVALID_SOURCE = exports.ERR_SANDBOX_CP_INVALID_DEST = exports.ERR_SANDBOX_CP_REPLACE = exports.ERR_SANDBOX_CP_MKDIR = exports.ERR_SANDBOX_CP_PATH_EXISTS = exports.ERR_SANDBOX_CP_NOT_EMPTY_DIR = exports.ERR_SANDBOX_CP_READDIR = exports.ERR_SANDBOX_CP_DEST_NOT_FOLDER = exports.ERR_SANDBOX_CP_SOURCE_NOT_FOUND = exports.TXT_SANDBOX_CP_DONE = exports.TXT_SANDBOX_CP_PROGRESS = exports.TXT_SANDBOX_UNZIPPING_COUNT = exports.TXT_SANDBOX_UNZIP_DONE = exports.TXT_SANDBOX_UNZIP = exports.TXT_SANDBOX_CP_DOWNLOAD_DONE = exports.TXT_SANDBOX_CP_DOWNLOAD = exports.OPTION_SANDBOX_CP_IGNORE = exports.OPTION_SANDBOX_CP_USER = exports.OPTION_SANDBOX_CP_DOWNLOAD_REPLACE = exports.OPTION_SANDBOX_CP_DOWNLOAD_MERGE = exports.OPTION_SANDBOX_CP_DEST = exports.OPTION_SANDBOX_CP_SOURCE = exports.DESC_COMMAND_SANDBOX_CP = exports.ERR_SANDBOX_ENDPOINTS_NOT_FOUND = exports.ERR_SANDBOX_ENDPOINT_NOT_FOUND = exports.ERR_SANDBOX_ENDPOINT_EXISTS = exports.TXT_SANDBOX_ENDPOINT_DELETED = exports.TXT_SANDBOX_ENDPOINT_DELETE_CONFIRM = exports.TXT_SANDBOX_ENDPOINT_ADDED = exports.TXT_SANDBOX_APP_REMOVED = exports.TXT_SANDBOX_APP_ADDED = exports.OPTION_SANDBOX_ENDPOINT_TYPE = exports.OPTION_SANDBOX_ENDPOINT_PORT = exports.OPTION_SANDBOX_ENDPOINT_NAME_ARG = exports.OPTION_SANDBOX_ENDPOINT_NAME = exports.DESC_COMMAND_SANDBOX_ENDPOINT_DELETE = exports.DESC_COMMAND_SANDBOX_ENDPOINT_ADD = exports.DESC_COMMAND_SANDBOX_ENDPOINT_GET = exports.DESC_COMMAND_SANDBOX_ENDPOINT_LIST = void 0;
16
- exports.DESC_COMMAND_WORKSPACE_SET = exports.DESC_COMMAND_WORKSPACE_LIST = exports.DESC_COMMAND_WORKSPACE = exports.TXT_COMMAND_REGISTER_PROVIDE_NAME = exports.TXT_COMMAND_REGISTER_PROVIDE_EMAIL = exports.ERR_COMMAND_REGISTER_INVALID_NAME = exports.ERR_COMMAND_REGISTER_INVALID_EMAIL = exports.OPT_COMMAND_REGISTER_NAME = exports.OPT_COMMAND_REGISTER_EMAIL = exports.DESC_COMMAND_REGISTER = exports.TXT_LOGOUT_SUCCESS = exports.DESC_COMMAND_LOGOUT = exports.DESC_COMMAND_LOGIN = exports.HELP_COMMAND_MCP = exports.ERR_MCP_TOOL_FILTERED = exports.ERR_MCP_TOOLS_CATEGORY = exports.OPT_COMMAND_MCP_TOOLS = exports.ERR_MCP_REFRESH_FAILED = exports.ERR_MCP_URL_INVALID = exports.ERR_MCP_ENDPOINT = exports.DESC_COMMAND_MCP = exports.ERR_API_MEDIA_TYPE_NOT_IMPLEMENTED = exports.ERR_API_PARAMETER_NOT_REPLACED = exports.TXT_API_ENDPOINT_REQUIRED_SCOPES = exports.ERR_API_ENDPOINT_NOT_FOUND = exports.ERR_API_WRONG_METHOD = exports.ERR_SCHEMA_FETCH_FAILED = exports.OPT_COMMAND_API_INFO_URL = exports.OPT_COMMAND_API_INFO_SCHEMA = exports.OPT_COMMAND_API_INFO_METHOD = exports.OPT_COMMAND_API_LIST_SEARCH = exports.OPT_COMMAND_API_LIST_METHOD = exports.ERR_API_REQUEST_BODY_VALUE = exports.ERR_API_REQUEST_QUERY_VALUE = exports.ERR_API_REQUEST_INVALID_JSON = exports.ERR_API_REQUEST_FILE_ERROR = exports.ERR_API_REQUEST_OUTPUT_EXISTS = exports.DESC_COMMAND_API_INFO = exports.DESC_COMMAND_API_FORM = exports.DESC_COMMAND_API_JSON = exports.DESC_COMMAND_API_DATA = exports.DESC_COMMAND_API_OUTPUT = exports.DESC_COMMAND_API_REQUEST_QUERY = exports.DESC_COMMAND_API_PROJECT = exports.DESC_COMMAND_API_WORKSPACE = exports.DESC_COMMAND_API_REQUEST_URL = exports.DESC_COMMAND_API_GET = exports.DESC_COMMAND_API_PATCH = exports.DESC_COMMAND_API_DELETE = exports.DESC_COMMAND_API_PUT = void 0;
17
- exports.OPT_COMMAND_DISTRO_NOTE = exports.OPT_COMMAND_DISTRO_NAME = exports.OPT_COMMAND_ROUTE_TARGET = exports.OPT_COMMAND_ROUTE_AGENT_NOTE = exports.OPT_COMMAND_ROUTE_NOTE = exports.OPT_COMMAND_ROUTE_PATH = exports.OPT_COMMAND_ROUTE_DOMAIN = exports.OPT_COMMAND_ROUTE_SUBDOMAIN = exports.OPT_COMMAND_ROUTE_TYPE = exports.OPT_COMMAND_ROUTE_ID = exports.OPT_COMMAND_DISTRO_IDENTIFIER = exports.OPT_COMMAND_SCOPE = exports.OPT_COMMAND_AGENT_NOTE = exports.OPT_COMMAND_NOTE = exports.DESC_COMMAND_ROUTE = exports.DESC_COMMAND_ROUTE_UPDATE = exports.DESC_COMMAND_ROUTE_DELETE = exports.DESC_COMMAND_ROUTE_GET = exports.DESC_COMMAND_DISTRO_UPDATE = exports.DESC_COMMAND_DISTRO_GET = exports.DESC_COMMAND_ROUTE_LIST = exports.DESC_COMMAND_DISTRO_LIST = exports.DESC_COMMAND_DISTRO_DELETE = exports.DESC_COMMAND_ROUTE_CREATE = exports.DESC_COMMAND_DISTRO_CREATE = exports.DESC_COMMAND_DISTRO = exports.ERR_API_MESSAGE_REPLACER = exports.ERR_LOGIN_INVALID_BASE_URL = exports.ERR_LOGIN_NO_WORKSPACE_FOUND = exports.ERR_LOGIN_NO_WORKSPACES = exports.ERR_REGISTER_HTTP_CANCEL = exports.ERR_LOGIN_HTTP_CANCEL = exports.ERR_LOGIN_HTTP_FAILED = exports.ERR_LOGIN_HTTP_SERVER_PORT_TAKEN = exports.TXT_REGISTER_SUCCESS = exports.TXT_LOGIN_SUCCESS = exports.TXT_LOGIN_SELECT_WORKSPACE = exports.TXT_LOGIN_ENTER_BASE_URL = exports.TXT_LOGIN_PROVIDE_CODE = exports.TXT_REGISTER_OPEN_URL = exports.TXT_LOGIN_OPEN_URL = exports.TXT_REGISTER_OPENING_STAR = exports.TXT_LOGIN_OPENING_STAR = exports.TXT_REGISTER_OPENING = exports.TXT_LOGIN_OPENING = exports.TXT_LOGIN_SELECT_REGION = exports.TXT_WORKSPACE_NONE = exports.TXT_WORKSPACE_SET_SUCCESS = exports.ARG_COMMAND_WORKSPACE = exports.DESC_COMMAND_WORKSPACE_GET = void 0;
18
- exports.TXT_ARTIFACT_DELETE_CONFIRM = exports.DESC_COMMAND_ARTIFACT_DELETE = exports.ERR_COMMAND_ARTIFACT_NO_PROJECTS = exports.DESC_COMMAND_ARTIFACT_VERSION_GET = exports.DESC_COMMAND_ARTIFACT_VERSION_LIST = exports.DESC_COMMAND_ARTIFACT_VERSION_DELETE = exports.DESC_COMMAND_ARTIFACT_DOCKER_LOGIN = exports.DESC_COMMAND_ARTIFACT_LIST = exports.DESC_COMMAND_ARTIFACT_VERSION = exports.ERR_COMMAND_DOMAIN_UNAVAILABLE = exports.OPTION_COMMAND_DOMAIN_IDENTIFIER = exports.ERR_COMMAND_DOMAIN_NO_DOMAINS = exports.TXT_COMMAND_DOMAIN_PROMPT_REQUIRED = exports.TXT_COMMAND_DOMAIN_BUY_SELECT_DOMAIN = exports.TXT_COMMAND_DOMAIN_PROVIDE_PROMPT = exports.ERR_COMMAND_DOMAIN_NOT_FOUND = exports.OPT_COMMAND_DOMAIN_ONLY_AVAILABLE = exports.OPT_COMMAND_DOMAIN_SORT = exports.OPT_COMMAND_DOMAIN_PHRASE = exports.OPT_COMMAND_DOMAIN_BUY_OWNER = exports.OPT_COMMAND_DOMAIN_BUY_TLD = exports.DESC_COMMAND_DOMAIN_GET = exports.DESC_COMMAND_DOMAIN_LIST = exports.DESC_COMMAND_DOMAIN_SEARCH = exports.DESC_COMMAND_DOMAIN_BUY = exports.DESC_COMMAND_DOMAIN = exports.ERR_ROUTE_NO_DEFAULT = exports.ERR_WRONG_ROUTE_TARGET = exports.ERR_COMMAND_ROUTE_NO_TARGET = exports.ERR_COMMAND_ROUTE_TYPE = exports.TXT_COMMAND_ROUTES_NOT_FOUND = exports.TXT_COMMAND_DISTROS_NOT_FOUND = exports.TXT_COMMAND_ROUTE_DELETED = exports.TXT_COMMAND_DISTRO_DELETED = exports.TXT_COMMAND_ROUTE_DELETE_CONFIRM = exports.TXT_COMMAND_DISTRO_DELETE_CONFIRM = exports.ERR_COMMAND_DISTRO_ENABLE_DISABLE = exports.ERR_COMMAND_DISTRO_NO_UPDATE = exports.ERR_COMMAND_ROUTE_NO_UPDATE = exports.ERR_COMMAND_DISTRO_NOT_FOUND = exports.ERR_COMMAND_SCOPE = exports.TXT_COMMAND_DISTRO_UPDATED = exports.TXT_COMMAND_ROUTE_UPDATED = exports.TXT_ROUTE_SERVE = exports.TXT_COMMAND_ROUTE_CREATED = exports.TXT_COMMAND_DISTRO_CREATED = exports.ERR_COMMAND_SCOPE_NO_PROJECT = exports.OPT_COMMAND_DISTRO_DISABLE = exports.OPT_COMMAND_DISTRO_ENABLE = exports.OPT_COMMAND_DISTRO_AGENT_NOTE = void 0;
19
- exports.EXAMPLE_DISTRO_DELETE = exports.EXAMPLE_ROUTE_GET = exports.EXAMPLE_DISTRO_UPDATE = exports.EXAMPLE_DISTRO_GET = exports.EXAMPLE_DISTRO_LIST = exports.EXAMPLE_SANDBOX_CP = exports.ERR_PROJECT_NO_PROJECTS = exports.TXT_LOGIN_SELECT_PROJECT = exports.TXT_COMMAND_PROJECT_CREATED = exports.TXT_COMMAND_PROJECT_LINK_NOT_FOUND = exports.TXT_COMMAND_PROJECT_LINK_NAME = exports.TXT_COMMAND_PROJECT_LINK_SELECT_PROJECT = exports.TXT_COMMAND_PROJECT_LINK_TO = exports.TXT_COMMAND_PROJECT_LINK_EXISTING_DESC = exports.TXT_COMMAND_PROJECT_LINK_EXISTING = exports.TXT_COMMAND_PROJECT_LINK_CREATE_NEW_DESC = exports.TXT_COMMAND_PROJECT_LINK_CREATE_NEW = exports.ERR_COMMAND_PROJECT_LINK_DIR_NOT_DIR = exports.TXT_COMMAND_PROJECT_LINK_GIT_REPO_INITIALIZED = exports.TXT_COMMAND_PROJECT_LINK_GIT_REPO = exports.TXT_COMMAND_PROJECT_LINK_DIR_CONFIRM = exports.TXT_COMMAND_PROJECT_LINK_DIR_LINKED = exports.ERR_COMMAND_PROJECT_LINK_DIR_CREATE = exports.OPT_COMMAND_PROJECT_LINK_TRY_NOW = exports.OPT_COMMAND_PROJECT_LINK_SET_GIT_REMOTE = exports.OPT_COMMAND_PROJECT_LINK_HAS_REMOTE = exports.OPT_COMMAND_PROJECT_LINK_DIRECTORY = exports.OPT_COMMAND_PROJECT_LINK_GIT = exports.OPT_COMMAND_PROJECT_LINK_RELINK = exports.DESC_COMMAND_PROJECT_LINK = exports.DESC_COMMAND_PROJECT_LIST = exports.DESC_COMMAND_PROJECT_GIT = exports.DESC_COMMAND_PROJECT_GIT_CREDENTIAL = exports.DESC_COMMAND_PROJECT = exports.TXT_ARTIFACT_VERSION_DOWNLOAD = exports.TXT_ARTIFACT_PUBLISH = exports.TXT_ARTIFACT_CREATED = exports.TXT_ARTIFACT_VERSION_DELETED = exports.TXT_ARTIFACT_DELETED = exports.ERR_COMMAND_ARTIFACT_TYPE = exports.OPT_COMMAND_ARTIFACT_VERSION = exports.OPT_COMMAND_ARTIFACT_IDENTIFIER = exports.OPT_COMMAND_ARTIFACT_CREATE_IDENTIFIER = exports.OPT_COMMAND_ARTIFACT_NAME = exports.OPT_COMMAND_ARTIFACT_TYPE = exports.DESC_COMMAND_ARTIFACT_CREATE = exports.DESC_COMMAND_ARTIFACT_GET = exports.TXT_ARTIFACT_DOCKER_LOGIN_FAILED = exports.TXT_ARTIFACT_DOCKER_LOGIN_SUCCESS = exports.TXT_ARTIFACT_VERSION_DELETE_CONFIRM = void 0;
20
- exports.EXAMPLE_ARTIFACT_VERSION_CREATE = exports.EXAMPLE_PIPELINE_RUN_RETRY = exports.EXAMPLE_PIPELINE_RUN_LIST = exports.EXAMPLE_PIPELINE_LIST = exports.EXAMPLE_PIPELINE_YML = exports.EXAMPLE_PIPELINE_GET = exports.EXAMPLE_PIPELINE_UPDATE = exports.EXAMPLE_PIPELINE_DELETE = exports.EXAMPLE_PIPELINE_CREATE = exports.EXAMPLE_PIPELINE_RUN_CANCEL = exports.EXAMPLE_PIPELINE_RUN_APPLY = exports.EXAMPLE_PIPELINE_RUN_LOGS = exports.EXAMPLE_PIPELINE_RUN_JSONL = exports.EXAMPLE_PIPELINE_RUN_STATUS = exports.EXAMPLE_PIPELINE_RUN_START = exports.EXAMPLE_SANDBOX_ENDPOINT_LIST = exports.EXAMPLE_SANDBOX_ENDPOINT_GET = exports.EXAMPLE_SANDBOX_ENDPOINT_DELETE = exports.EXAMPLE_SANDBOX_ENDPOINT_CREATE = exports.EXAMPLE_SANDBOX_SNAPSHOT_LIST = exports.EXAMPLE_SANDBOX_SNAPSHOT_GET = exports.EXAMPLE_SANDBOX_SNAPSHOT_DELETE = exports.EXAMPLE_SANDBOX_SNAPSHOT_CREATE = exports.EXAMPLE_SANDBOX_EXEC_STATUS = exports.EXAMPLE_SANDBOX_EXEC_LOGS = exports.EXAMPLE_SANDBOX_APP_STATUS = exports.EXAMPLE_SANDBOX_APP_STOP = exports.EXAMPLE_SANDBOX_APP_REMOVE = exports.EXAMPLE_SANDBOX_APP_ADD = exports.EXAMPLE_SANDBOX_APP_START = exports.EXAMPLE_SANDBOX_APP_LOGS = exports.EXAMPLE_SANDBOX_EXEC_LIST = exports.EXAMPLE_SANDBOX_APP_LIST = exports.EXAMPLE_SANDBOX_EXEC_KILL = exports.EXAMPLE_SANDBOX_SSH = exports.EXAMPLE_SANDBOX_EXEC_COMMAND = exports.EXAMPLE_TUNNEL_START = exports.EXAMPLE_TUNNEL_TCP = exports.EXAMPLE_TUNNEL_TLS = exports.EXAMPLE_AGENT_TUNNEL_START = exports.EXAMPLE_AGENT_TUNNEL_STATUS = exports.EXAMPLE_AGENT_TUNNEL_REMOVE = exports.EXAMPLE_AGENT_TUNNEL_LIST = exports.EXAMPLE_TUNNEL_HTTP = exports.EXAMPLE_SANDBOX_CREATE = exports.EXAMPLE_DISTRO_CREATE = exports.EXAMPLE_ROUTE_CREATE = exports.EXAMPLE_ROUTE_LIST = exports.EXAMPLE_ROUTE_UPDATE = exports.EXAMPLE_ROUTE_DELETE = void 0;
21
- exports.EXAMPLE_CRAWL_LINK = exports.EXAMPLE_CRAWL_RUN = exports.EXAMPLE_TESTS_CAPTURE = exports.EXAMPLE_TESTS_VISUAL_SESSION_CLOSE = exports.EXAMPLE_TESTS_VISUAL_SESSION_CREATE = exports.EXAMPLE_TESTS_VISUAL_LINK = exports.EXAMPLE_TESTS_VISUAL_UPLOAD = exports.EXAMPLE_TESTS_VISUAL_SETUP = exports.EXAMPLE_TESTS_UNIT_LINK = exports.EXAMPLE_TESTS_UNIT_UPLOAD = exports.EXAMPLE_ARTIFACT_VERSION_DELETE = exports.EXAMPLE_ARTIFACT_VERSION_GET = exports.EXAMPLE_ARTIFACT_VERSION_LIST = exports.EXAMPLE_ARTIFACT_CREATE = exports.EXAMPLE_ARTIFACT_DELETE = exports.EXAMPLE_ARTIFACT_DOWNLOAD = exports.EXAMPLE_ARTIFACT_PUBLISH = void 0;
12
+ exports.LOG_TUNNEL_SSH_STREAM = exports.LOG_TUNNEL_TLS_AGENT_STREAM = exports.LOG_TUNNEL_TLS_REGION_STREAM = exports.LOG_TUNNEL_TLS_TARGET_STREAM = exports.LOG_TUNNEL_HTTP2_STREAM = exports.LOG_TUNNEL_HTTP1_STREAM = exports.LOG_TUNNEL_TCP_STREAM = exports.LOG_TUNNEL_HTTP_WRONG_USER_AGENTS = exports.LOG_TUNNEL_HTTP_CIRCUIT_BREAKER_OPEN = exports.LOG_TUNNEL_HTTP_MAX_INFLIGHT = exports.LOG_TUNNEL_HTTP_RATE_LIMIT = exports.LOG_TUNNEL_HTTP_WRON_AUTH = exports.LOG_TUNNEL_IDENTIFIED = exports.LOG_TUNNEL_DISCONNECTED = exports.LOG_TUNNEL_FAILED = exports.LOG_TUNNEL_CONNECTED = exports.LOG_AGENT_STARTED = exports.LOG_AGENT_UPDATE_ROLLBACK_MISSING = exports.LOG_AGENT_UPDATE_ROLLBACK_ACKED = exports.LOG_AGENT_UPDATE_ROLLED_BACK = exports.LOG_AGENT_UPDATE_ATTEMPT = exports.LOG_AGENT_UPDATE_COMMITTED = exports.LOG_AGENT_UPDATE_BINARY_INVALID = exports.ERR_AGENT_UPDATE_IN_PROGRESS = exports.LOG_AGENT_UPDATE_UNINSTALLED = exports.LOG_AGENT_UPDATE_VERSION_MISMATCH = exports.LOG_AGENT_UPDATE_FAILED = exports.LOG_AGENT_UPDATE_SWAPPED = exports.LOG_AGENT_UPDATE_NOT_NEEDED = exports.LOG_AGENT_UPDATE_NO_ADMIN = exports.LOG_AGENT_UPDATE_STANDALONE = exports.LOG_AGENT_UPDATE_REQUESTED = exports.LOG_AGENT_SERVER_STARTED = exports.LOG_ERROR_STARTING_AGENT_SERVER = exports.LOG_SSH_CONNECTION = exports.LOG_LATE_TARGET_ERROR = exports.LOG_LATE_CHANNEL_ERROR = exports.LOG_HANDSHAKE_TIMEOUT = exports.LOG_WRONG_STREAM = exports.LOG_DETECTED_STREAM = exports.LOG_HTTP2_REQUEST = exports.LOG_HTTP2_CONNECTION = exports.LOG_HTTP1_REQUEST = exports.LOG_HTTP1_CONNECTION = exports.LOG_ERROR = exports.LOG_STOPPING_TUNNEL = exports.LOG_STARTING_TUNNEL = exports.LOG_ENABLING_AGENT_TUNNELING = exports.LOG_ENABLING_AGENT_PROXY = exports.LOG_ENABLING_AGENT_TARGET = void 0;
13
+ exports.ERR_SANDBOX_NOT_FOUND = exports.OPTION_SANDBOX_SSH_PRINT = exports.OPTION_SANDBOX_SSH_IDENTITY = exports.OPTION_SANDBOX_SSH_ARGS = exports.OPTION_SANDBOX_RUNTIME = exports.OPTION_SANDBOX_TIMEOUT = exports.OPTION_SANDBOX_FETCH = exports.OPTION_SANDBOX_APP_DIR = exports.OPTION_SANDBOX_APP_COMMAND = exports.OPTION_SANDBOX_YAML = exports.OPTION_SANDBOX_TAGS = exports.OPTION_SANDBOX_INSTALL_SCRIPT = exports.OPTION_SANDBOX_INSTALL_COMMANDS = exports.OPTION_SANDBOX_RESOURCES = exports.OPTION_SANDBOX_OS = exports.OPTION_SANDBOX_AGENT_NOTE = exports.OPTION_SANDBOX_NOTE = exports.OPTION_SANDBOX_NAME = exports.OPTION_SANDBOX_IDENTIFIER = exports.DESC_COMMAND_SANDBOX_SSH = exports.DESC_COMMAND_SANDBOX_APP = exports.DESC_COMMAND_SANDBOX_EXEC = exports.DESC_COMMAND_SANDBOX_STATUS = exports.DESC_COMMAND_SANDBOX_LOGS = exports.DESC_COMMAND_SANDBOX_RESTART = exports.DESC_COMMAND_SANDBOX_STOP = exports.DESC_COMMAND_SANDBOX_START = exports.DESC_COMMAND_SANDBOX_DESTROY = exports.DESC_COMMAND_SANDBOX_GET = exports.DESC_COMMAND_SANDBOX_LIST = exports.DESC_COMMAND_SANDBOX_UPDATE = exports.DESC_COMMAND_SANDBOX_GET_YAML = exports.DESC_COMMAND_SANDBOX_CREATE = exports.DESC_COMMAND_SANDBOX = exports.DEBUG_WAIT_FOR_IDLE_TIMEOUT = exports.DEBUG_WAIT_FOR_IDLE = exports.DEBUG_RESOURCE_DISCOVERY_TIMEOUT = exports.DEBUG_AUTO_WIDTH = exports.DEBUG_AUTO_SCROLL = exports.DEBUG_RESOURCE_CRAWLING_URL = exports.DEBUG_SNAPSHOT_PROCESSING = exports.DEBUG_SNAPSHOTS_PROCESSING = exports.DEBUG_EXEC_COMMAND = exports.DEBUG_EXEC_TEST_COMMAND = exports.LOG_INSTALLED_BROWSER = exports.LOG_SESSION_LINK = exports.LOG_SENDING_DATA = exports.LOG_SENDING_REQUEST = exports.LOG_PROCESSING_SNAPSHOTS = exports.LOG_RUNNING_EXEC_COMMAND = void 0;
14
+ exports.DESC_COMMAND_SANDBOX_SNAPSHOT = exports.TXT_SANDBOX_COMMAND_KILLED = exports.OPTION_SANDBOX_COMMAND_KILL_CONFIRM = exports.OPTION_SANDBOX_LOGS_LIMIT = exports.OPTION_SANDBOX_APP_ID = exports.OPTION_SANDBOX_COMMAND_ID = exports.DESC_COMMAND_SANDBOX_EXEC_KILL = exports.DESC_COMMAND_SANDBOX_EXEC_LOGS = exports.DESC_COMMAND_SANDBOX_APP_START = exports.DESC_COMMAND_SANDBOX_APP_STOP = exports.DESC_COMMAND_SANDBOX_APP_STATUS = exports.DESC_COMMAND_SANDBOX_APP_LOGS = exports.DESC_COMMAND_SANDBOX_EXEC_STATUS = exports.DESC_COMMAND_SANDBOX_EXEC_LIST = exports.DESC_COMMAND_SANDBOX_APP_REMOVE = exports.DESC_COMMAND_SANDBOX_APP_ADD = exports.DESC_COMMAND_SANDBOX_APP_LIST = exports.TXT_SANDBOX_WAITING_START = exports.TXT_SANDBOX_WAITING_STOP = exports.TXT_SANDBOX_WAITING_APPS = exports.TXT_SANDBOX_WAITING_SETUP = exports.TXT_SANDBOX_WAITING_RUNNING = exports.TXT_SANDBOX_STOPPED = exports.TXT_SANDBOX_STARTED = exports.TXT_SANDBOX_DESTROYED = exports.TXT_SANDBOX_DESTROY_CONFIRM = exports.TXT_SANDBOX_UPDATED = exports.TXT_SANDBOX_CREATED = exports.TXT_SANDBOX_CREATING = exports.TXT_SANDBOX_APP_STARTED = exports.TXT_SANDBOX_APP_STOPPED = exports.OPTION_SANDBOX_WAIT = exports.OPTION_SANDBOX_WAIT_APPS = exports.OPTION_SANDBOX_WAIT_CONFIGURED = exports.OPTION_SANDBOX_WAIT_RUNNING = exports.ERR_SANDBOX_STOP_FAILED = exports.ERR_SANDBOX_SSH_MISSING = exports.ERR_SANDBOX_SSH_NO_ACCESS = exports.ERR_SANDBOX_NOT_RUNNING = exports.ERR_SANDBOX_NO_COMMANDS = exports.ERR_SANDBOX_RUNNING_FAILED = exports.ERR_SANDBOX_STOP_TIMEOUT = exports.ERR_SANDBOX_SNAPSHOT_TIMEOUT = exports.ERR_SANDBOX_RUNNING_TIMEOUT = exports.ERR_SANDBOX_APPS_TIMEOUT = exports.ERR_SANDBOX_SETUP_TIMEOUT = exports.ERR_SANDBOX_APP_FAILED = exports.ERR_SANDBOX_SETUP_FAILED = exports.ERR_SANDBOX_INVALID_RESOURCES = exports.ERR_SANDBOX_APP_NOT_FOUND = void 0;
15
+ exports.ERR_SANDBOX_CP_PATH_EXISTS = exports.ERR_SANDBOX_CP_NOT_EMPTY_DIR = exports.ERR_SANDBOX_CP_READDIR = exports.ERR_SANDBOX_CP_DEST_NOT_FOLDER = exports.ERR_SANDBOX_CP_SOURCE_NOT_FOUND = exports.TXT_SANDBOX_CP_DONE = exports.TXT_SANDBOX_CP_PROGRESS = exports.TXT_SANDBOX_UNZIPPING_COUNT = exports.TXT_SANDBOX_UNZIP_DONE = exports.TXT_SANDBOX_UNZIP = exports.TXT_SANDBOX_CP_DOWNLOAD_DONE = exports.TXT_SANDBOX_CP_DOWNLOAD = exports.OPTION_SANDBOX_CP_IGNORE = exports.OPTION_SANDBOX_CP_USER = exports.OPTION_SANDBOX_CP_DOWNLOAD_REPLACE = exports.OPTION_SANDBOX_CP_DOWNLOAD_MERGE = exports.OPTION_SANDBOX_CP_DEST = exports.OPTION_SANDBOX_CP_SOURCE = exports.DESC_COMMAND_SANDBOX_CP = exports.ERR_SANDBOX_ENDPOINTS_NOT_FOUND = exports.ERR_SANDBOX_ENDPOINT_NOT_FOUND = exports.ERR_SANDBOX_ENDPOINT_EXISTS = exports.TXT_SANDBOX_ENDPOINT_DELETED = exports.TXT_SANDBOX_ENDPOINT_DELETE_CONFIRM = exports.TXT_SANDBOX_ENDPOINT_ADDED = exports.TXT_SANDBOX_APP_REMOVED = exports.TXT_SANDBOX_APP_ADDED = exports.OPTION_SANDBOX_ENDPOINT_TYPE = exports.OPTION_SANDBOX_ENDPOINT_PORT = exports.OPTION_SANDBOX_ENDPOINT_NAME_ARG = exports.OPTION_SANDBOX_ENDPOINT_NAME = exports.DESC_COMMAND_SANDBOX_ENDPOINT_DELETE = exports.DESC_COMMAND_SANDBOX_ENDPOINT_ADD = exports.DESC_COMMAND_SANDBOX_ENDPOINT_GET = exports.DESC_COMMAND_SANDBOX_ENDPOINT_LIST = exports.DESC_COMMAND_SANDBOX_ENDPOINT = exports.ERR_SANDBOX_SNAPSHOTS_NOT_FOUND = exports.ERR_SANDBOX_SNAPSHOT_NOT_FOUND = exports.ERR_SANDBOX_SNAPSHOT_FAILED = exports.TXT_SANDBOX_SNAPSHOT_WAITING = exports.TXT_SANDBOX_SNAPSHOT_DELETE_CONFIRM = exports.TXT_SANDBOX_SNAPSHOT_DELETED = exports.TXT_SANDBOX_SNAPSHOT_CREATED = exports.OPTION_SANDBOX_FROM_SNAPSHOT = exports.OPTION_SANDBOX_SNAPSHOT_NAME_ARG = exports.OPTION_SANDBOX_SNAPSHOT_NAME = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_DELETE = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_GET = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_CREATE = exports.DESC_COMMAND_SANDBOX_SNAPSHOT_LIST = void 0;
16
+ exports.ERR_MCP_TOOLS_CATEGORY = exports.OPT_COMMAND_MCP_TOOLS = exports.ERR_MCP_REFRESH_FAILED = exports.ERR_MCP_URL_INVALID = exports.ERR_MCP_ENDPOINT = exports.DESC_COMMAND_MCP = exports.ERR_API_MEDIA_TYPE_NOT_IMPLEMENTED = exports.ERR_API_PARAMETER_NOT_REPLACED = exports.TXT_API_ENDPOINT_REQUIRED_SCOPES = exports.ERR_API_ENDPOINT_NOT_FOUND = exports.ERR_API_WRONG_METHOD = exports.ERR_SCHEMA_FETCH_FAILED = exports.OPT_COMMAND_API_INFO_URL = exports.OPT_COMMAND_API_INFO_SCHEMA = exports.OPT_COMMAND_API_INFO_METHOD = exports.OPT_COMMAND_API_LIST_SEARCH = exports.OPT_COMMAND_API_LIST_METHOD = exports.ERR_API_REQUEST_BODY_VALUE = exports.ERR_API_REQUEST_QUERY_VALUE = exports.ERR_API_REQUEST_INVALID_JSON = exports.ERR_API_REQUEST_FILE_ERROR = exports.ERR_API_REQUEST_OUTPUT_EXISTS = exports.DESC_COMMAND_API_INFO = exports.DESC_COMMAND_API_FORM = exports.DESC_COMMAND_API_JSON = exports.DESC_COMMAND_API_DATA = exports.DESC_COMMAND_API_OUTPUT = exports.DESC_COMMAND_API_REQUEST_QUERY = exports.DESC_COMMAND_API_PROJECT = exports.DESC_COMMAND_API_WORKSPACE = exports.DESC_COMMAND_API_REQUEST_URL = exports.DESC_COMMAND_API_GET = exports.DESC_COMMAND_API_PATCH = exports.DESC_COMMAND_API_DELETE = exports.DESC_COMMAND_API_PUT = exports.DESC_COMMAND_API_POST = exports.DESC_COMMAND_API_LIST = exports.DESC_COMMAND_API = exports.ERR_WHOAMI_LOGOUT = exports.TXT_WHOAMI_NO_WORKSPACE = exports.DESC_COMMAND_WHOAMI = exports.TXT_SANDBOX_EXEC_FAILED = exports.TXT_SANDBOX_EXEC_INPROGRESS = exports.TXT_SANDBOX_EXEC_SUCCESS = exports.TXT_SANDBOX_EXEC_BACKGROUND = exports.TXT_SANDBOX_EXEC_ID = exports.ERR_SANDBOX_CP_INVALID_SOURCE = exports.ERR_SANDBOX_CP_INVALID_DEST = exports.ERR_SANDBOX_CP_REPLACE = exports.ERR_SANDBOX_CP_MKDIR = void 0;
17
+ exports.DESC_COMMAND_ROUTE_UPDATE = exports.DESC_COMMAND_ROUTE_DELETE = exports.DESC_COMMAND_ROUTE_GET = exports.DESC_COMMAND_DISTRO_UPDATE = exports.DESC_COMMAND_DISTRO_GET = exports.DESC_COMMAND_ROUTE_LIST = exports.DESC_COMMAND_DISTRO_LIST = exports.DESC_COMMAND_DISTRO_DELETE = exports.DESC_COMMAND_ROUTE_CREATE = exports.DESC_COMMAND_DISTRO_CREATE = exports.DESC_COMMAND_DISTRO = exports.ERR_API_MESSAGE_REPLACER = exports.ERR_LOGIN_INVALID_BASE_URL = exports.ERR_LOGIN_NO_WORKSPACE_FOUND = exports.ERR_LOGIN_NO_WORKSPACES = exports.ERR_REGISTER_HTTP_CANCEL = exports.ERR_LOGIN_HTTP_CANCEL = exports.ERR_LOGIN_HTTP_FAILED = exports.ERR_LOGIN_HTTP_SERVER_PORT_TAKEN = exports.TXT_REGISTER_SUCCESS = exports.TXT_LOGIN_SUCCESS = exports.TXT_LOGIN_SELECT_WORKSPACE = exports.TXT_LOGIN_ENTER_BASE_URL = exports.TXT_LOGIN_PROVIDE_CODE = exports.TXT_REGISTER_OPEN_URL = exports.TXT_LOGIN_OPEN_URL = exports.TXT_REGISTER_OPENING_STAR = exports.TXT_LOGIN_OPENING_STAR = exports.TXT_REGISTER_OPENING = exports.TXT_LOGIN_OPENING = exports.TXT_LOGIN_SELECT_REGION = exports.TXT_WORKSPACE_NONE = exports.TXT_WORKSPACE_SET_SUCCESS = exports.ARG_COMMAND_WORKSPACE = exports.DESC_COMMAND_WORKSPACE_GET = exports.DESC_COMMAND_WORKSPACE_SET = exports.DESC_COMMAND_WORKSPACE_LIST = exports.DESC_COMMAND_WORKSPACE = exports.TXT_COMMAND_REGISTER_PROVIDE_NAME = exports.TXT_COMMAND_REGISTER_PROVIDE_EMAIL = exports.ERR_COMMAND_REGISTER_INVALID_NAME = exports.ERR_COMMAND_REGISTER_INVALID_EMAIL = exports.OPT_COMMAND_REGISTER_NAME = exports.OPT_COMMAND_REGISTER_EMAIL = exports.DESC_COMMAND_REGISTER = exports.TXT_LOGOUT_SUCCESS = exports.DESC_COMMAND_LOGOUT = exports.DESC_COMMAND_LOGIN = exports.HELP_COMMAND_MCP = exports.ERR_MCP_TOOL_FILTERED = void 0;
18
+ exports.ERR_COMMAND_DOMAIN_NOT_FOUND = exports.OPT_COMMAND_DOMAIN_ONLY_AVAILABLE = exports.OPT_COMMAND_DOMAIN_SORT = exports.OPT_COMMAND_DOMAIN_PHRASE = exports.OPT_COMMAND_DOMAIN_BUY_OWNER = exports.OPT_COMMAND_DOMAIN_BUY_TLD = exports.DESC_COMMAND_DOMAIN_GET = exports.DESC_COMMAND_DOMAIN_LIST = exports.DESC_COMMAND_DOMAIN_SEARCH = exports.DESC_COMMAND_DOMAIN_BUY = exports.DESC_COMMAND_DOMAIN = exports.ERR_ROUTE_NO_DEFAULT = exports.ERR_WRONG_ROUTE_TARGET = exports.ERR_COMMAND_ROUTE_NO_TARGET = exports.ERR_COMMAND_ROUTE_TYPE = exports.TXT_COMMAND_ROUTES_NOT_FOUND = exports.TXT_COMMAND_DISTROS_NOT_FOUND = exports.TXT_COMMAND_ROUTE_DELETED = exports.TXT_COMMAND_DISTRO_DELETED = exports.TXT_COMMAND_ROUTE_DELETE_CONFIRM = exports.TXT_COMMAND_DISTRO_DELETE_CONFIRM = exports.ERR_COMMAND_DISTRO_ENABLE_DISABLE = exports.ERR_COMMAND_DISTRO_NO_UPDATE = exports.ERR_COMMAND_ROUTE_NO_UPDATE = exports.ERR_COMMAND_DISTRO_NOT_FOUND = exports.ERR_COMMAND_SCOPE = exports.TXT_COMMAND_DISTRO_UPDATED = exports.TXT_COMMAND_ROUTE_UPDATED = exports.TXT_ROUTE_SERVE = exports.TXT_COMMAND_ROUTE_CREATED = exports.TXT_COMMAND_DISTRO_CREATED = exports.ERR_COMMAND_SCOPE_NO_PROJECT = exports.OPT_COMMAND_DISTRO_DISABLE = exports.OPT_COMMAND_DISTRO_ENABLE = exports.OPT_COMMAND_DISTRO_AGENT_NOTE = exports.OPT_COMMAND_DISTRO_NOTE = exports.OPT_COMMAND_DISTRO_NAME = exports.OPT_COMMAND_ROUTE_TARGET = exports.OPT_COMMAND_ROUTE_AGENT_NOTE = exports.OPT_COMMAND_ROUTE_NOTE = exports.OPT_COMMAND_ROUTE_PATH = exports.OPT_COMMAND_ROUTE_DOMAIN = exports.OPT_COMMAND_ROUTE_SUBDOMAIN = exports.OPT_COMMAND_ROUTE_TYPE = exports.OPT_COMMAND_ROUTE_ID = exports.OPT_COMMAND_DISTRO_IDENTIFIER = exports.OPT_COMMAND_SCOPE = exports.OPT_COMMAND_AGENT_NOTE = exports.OPT_COMMAND_NOTE = exports.DESC_COMMAND_ROUTE = void 0;
19
+ exports.TXT_COMMAND_PROJECT_LINK_CREATE_NEW_DESC = exports.TXT_COMMAND_PROJECT_LINK_CREATE_NEW = exports.ERR_COMMAND_PROJECT_LINK_DIR_NOT_DIR = exports.TXT_COMMAND_PROJECT_LINK_GIT_REPO_INITIALIZED = exports.TXT_COMMAND_PROJECT_LINK_GIT_REPO = exports.TXT_COMMAND_PROJECT_LINK_DIR_CONFIRM = exports.TXT_COMMAND_PROJECT_LINK_DIR_LINKED = exports.ERR_COMMAND_PROJECT_LINK_DIR_CREATE = exports.OPT_COMMAND_PROJECT_LINK_TRY_NOW = exports.OPT_COMMAND_PROJECT_LINK_SET_GIT_REMOTE = exports.OPT_COMMAND_PROJECT_LINK_HAS_REMOTE = exports.OPT_COMMAND_PROJECT_LINK_DIRECTORY = exports.OPT_COMMAND_PROJECT_LINK_GIT = exports.OPT_COMMAND_PROJECT_LINK_RELINK = exports.DESC_COMMAND_PROJECT_LINK = exports.DESC_COMMAND_PROJECT_LIST = exports.DESC_COMMAND_PROJECT_GIT = exports.DESC_COMMAND_PROJECT_GIT_CREDENTIAL = exports.DESC_COMMAND_PROJECT = exports.TXT_ARTIFACT_VERSION_DOWNLOAD = exports.TXT_ARTIFACT_PUBLISH = exports.TXT_ARTIFACT_CREATED = exports.TXT_ARTIFACT_VERSION_DELETED = exports.TXT_ARTIFACT_DELETED = exports.ERR_COMMAND_ARTIFACT_TYPE = exports.OPT_COMMAND_ARTIFACT_VERSION = exports.OPT_COMMAND_ARTIFACT_IDENTIFIER = exports.OPT_COMMAND_ARTIFACT_CREATE_IDENTIFIER = exports.OPT_COMMAND_ARTIFACT_NAME = exports.OPT_COMMAND_ARTIFACT_TYPE = exports.DESC_COMMAND_ARTIFACT_CREATE = exports.DESC_COMMAND_ARTIFACT_GET = exports.TXT_ARTIFACT_DOCKER_LOGIN_FAILED = exports.TXT_ARTIFACT_DOCKER_LOGIN_SUCCESS = exports.TXT_ARTIFACT_VERSION_DELETE_CONFIRM = exports.TXT_ARTIFACT_DELETE_CONFIRM = exports.DESC_COMMAND_ARTIFACT_DELETE = exports.ERR_COMMAND_ARTIFACT_NO_PROJECTS = exports.DESC_COMMAND_ARTIFACT_VERSION_GET = exports.DESC_COMMAND_ARTIFACT_VERSION_LIST = exports.DESC_COMMAND_ARTIFACT_VERSION_DELETE = exports.DESC_COMMAND_ARTIFACT_DOCKER_LOGIN = exports.DESC_COMMAND_ARTIFACT_LIST = exports.DESC_COMMAND_ARTIFACT_VERSION = exports.ERR_COMMAND_DOMAIN_UNAVAILABLE = exports.OPTION_COMMAND_DOMAIN_IDENTIFIER = exports.ERR_COMMAND_DOMAIN_NO_DOMAINS = exports.TXT_COMMAND_DOMAIN_PROMPT_REQUIRED = exports.TXT_COMMAND_DOMAIN_BUY_SELECT_DOMAIN = exports.TXT_COMMAND_DOMAIN_PROVIDE_PROMPT = void 0;
20
+ exports.EXAMPLE_SANDBOX_ENDPOINT_LIST = exports.EXAMPLE_SANDBOX_ENDPOINT_GET = exports.EXAMPLE_SANDBOX_ENDPOINT_DELETE = exports.EXAMPLE_SANDBOX_ENDPOINT_CREATE = exports.EXAMPLE_SANDBOX_SNAPSHOT_LIST = exports.EXAMPLE_SANDBOX_SNAPSHOT_GET = exports.EXAMPLE_SANDBOX_SNAPSHOT_DELETE = exports.EXAMPLE_SANDBOX_SNAPSHOT_CREATE = exports.EXAMPLE_SANDBOX_EXEC_STATUS = exports.EXAMPLE_SANDBOX_EXEC_LOGS = exports.EXAMPLE_SANDBOX_APP_STATUS = exports.EXAMPLE_SANDBOX_APP_STOP = exports.EXAMPLE_SANDBOX_APP_REMOVE = exports.EXAMPLE_SANDBOX_APP_ADD = exports.EXAMPLE_SANDBOX_APP_START = exports.EXAMPLE_SANDBOX_APP_LOGS = exports.EXAMPLE_SANDBOX_EXEC_LIST = exports.EXAMPLE_SANDBOX_APP_LIST = exports.EXAMPLE_SANDBOX_EXEC_KILL = exports.EXAMPLE_SANDBOX_SSH = exports.EXAMPLE_SANDBOX_EXEC_COMMAND = exports.EXAMPLE_TUNNEL_START = exports.EXAMPLE_TUNNEL_TCP = exports.EXAMPLE_TUNNEL_TLS = exports.EXAMPLE_AGENT_TUNNEL_START = exports.EXAMPLE_AGENT_TUNNEL_STATUS = exports.EXAMPLE_AGENT_TUNNEL_REMOVE = exports.EXAMPLE_AGENT_TUNNEL_LIST = exports.EXAMPLE_TUNNEL_HTTP = exports.EXAMPLE_SANDBOX_CREATE = exports.EXAMPLE_DISTRO_CREATE = exports.EXAMPLE_ROUTE_CREATE = exports.EXAMPLE_ROUTE_LIST = exports.EXAMPLE_ROUTE_UPDATE = exports.EXAMPLE_ROUTE_DELETE = exports.EXAMPLE_DISTRO_DELETE = exports.EXAMPLE_ROUTE_GET = exports.EXAMPLE_DISTRO_UPDATE = exports.EXAMPLE_DISTRO_GET = exports.EXAMPLE_DISTRO_LIST = exports.EXAMPLE_SANDBOX_CP = exports.ERR_PROJECT_NO_PROJECTS = exports.TXT_LOGIN_SELECT_PROJECT = exports.TXT_COMMAND_PROJECT_CREATED = exports.TXT_COMMAND_PROJECT_LINK_NOT_FOUND = exports.TXT_COMMAND_PROJECT_LINK_NAME = exports.TXT_COMMAND_PROJECT_LINK_SELECT_PROJECT = exports.TXT_COMMAND_PROJECT_LINK_TO = exports.TXT_COMMAND_PROJECT_LINK_EXISTING_DESC = exports.TXT_COMMAND_PROJECT_LINK_EXISTING = void 0;
21
+ exports.EXAMPLE_CRAWL_LINK = exports.EXAMPLE_CRAWL_RUN = exports.EXAMPLE_TESTS_CAPTURE = exports.EXAMPLE_TESTS_VISUAL_SESSION_CLOSE = exports.EXAMPLE_TESTS_VISUAL_SESSION_CREATE = exports.EXAMPLE_TESTS_VISUAL_LINK = exports.EXAMPLE_TESTS_VISUAL_UPLOAD = exports.EXAMPLE_TESTS_VISUAL_SETUP = exports.EXAMPLE_TESTS_UNIT_LINK = exports.EXAMPLE_TESTS_UNIT_UPLOAD = exports.EXAMPLE_ARTIFACT_VERSION_DELETE = exports.EXAMPLE_ARTIFACT_VERSION_GET = exports.EXAMPLE_ARTIFACT_VERSION_LIST = exports.EXAMPLE_ARTIFACT_CREATE = exports.EXAMPLE_ARTIFACT_DELETE = exports.EXAMPLE_ARTIFACT_DOWNLOAD = exports.EXAMPLE_ARTIFACT_PUBLISH = exports.EXAMPLE_ARTIFACT_VERSION_CREATE = exports.EXAMPLE_PIPELINE_RUN_RETRY = exports.EXAMPLE_PIPELINE_RUN_LIST = exports.EXAMPLE_PIPELINE_LIST = exports.EXAMPLE_PIPELINE_YML = exports.EXAMPLE_PIPELINE_GET = exports.EXAMPLE_PIPELINE_UPDATE = exports.EXAMPLE_PIPELINE_DELETE = exports.EXAMPLE_PIPELINE_CREATE = exports.EXAMPLE_PIPELINE_RUN_CANCEL = exports.EXAMPLE_PIPELINE_RUN_APPLY = exports.EXAMPLE_PIPELINE_RUN_LOGS = exports.EXAMPLE_PIPELINE_RUN_JSONL = exports.EXAMPLE_PIPELINE_RUN_STATUS = exports.EXAMPLE_PIPELINE_RUN_START = void 0;
22
22
  const utils_1 = require("./utils");
23
23
  exports.ERR_CANCELLED = 'Cancelled';
24
24
  exports.ERR_REST_API_GENERAL_ERROR = 'Something went wrong';
@@ -554,8 +554,33 @@ exports.LOG_HANDSHAKE_TIMEOUT = 'Stream handshake timed out';
554
554
  exports.LOG_LATE_CHANNEL_ERROR = 'Late error on an already closed channel, ignored';
555
555
  exports.LOG_LATE_TARGET_ERROR = 'Late error on a torn down target request, ignored';
556
556
  exports.LOG_SSH_CONNECTION = 'New SSH TCP connection';
557
- exports.LOG_ERROR_STARTING_AGENT_SERVER = 'Error while starting agent API server';
557
+ const LOG_ERROR_STARTING_AGENT_SERVER = (port) => `Error while starting agent API server: port ${port} is already in use`;
558
+ exports.LOG_ERROR_STARTING_AGENT_SERVER = LOG_ERROR_STARTING_AGENT_SERVER;
558
559
  exports.LOG_AGENT_SERVER_STARTED = 'Agent server started';
560
+ const LOG_AGENT_UPDATE_REQUESTED = (from, to) => `Remote update requested, updating agent from '${from}' to '${to}'`;
561
+ exports.LOG_AGENT_UPDATE_REQUESTED = LOG_AGENT_UPDATE_REQUESTED;
562
+ exports.LOG_AGENT_UPDATE_STANDALONE = 'Remote update is not supported for a standalone agent: nothing supervises the process, so it would not come back after exiting. Update the cli and run `bdy agent update`';
563
+ exports.LOG_AGENT_UPDATE_NO_ADMIN = 'Remote update needs admin rights, the agent is running without them';
564
+ const LOG_AGENT_UPDATE_NOT_NEEDED = (version) => `Remote update skipped, agent already runs the latest version '${version}'`;
565
+ exports.LOG_AGENT_UPDATE_NOT_NEEDED = LOG_AGENT_UPDATE_NOT_NEEDED;
566
+ const LOG_AGENT_UPDATE_SWAPPED = (version) => `Agent binary replaced with '${version}', exiting so the service starts it`;
567
+ exports.LOG_AGENT_UPDATE_SWAPPED = LOG_AGENT_UPDATE_SWAPPED;
568
+ exports.LOG_AGENT_UPDATE_FAILED = 'Remote update of the agent failed';
569
+ const LOG_AGENT_UPDATE_VERSION_MISMATCH = (wanted, got) => `Downloaded archive reports version '${got}' but '${wanted}' was requested, keeping the current binary`;
570
+ exports.LOG_AGENT_UPDATE_VERSION_MISMATCH = LOG_AGENT_UPDATE_VERSION_MISMATCH;
571
+ exports.LOG_AGENT_UPDATE_UNINSTALLED = 'Agent was uninstalled while the update was downloading, leaving the binary alone';
572
+ exports.ERR_AGENT_UPDATE_IN_PROGRESS = 'The agent is already updating itself after a remote request. Wait for it to finish and check `bdy agent status`';
573
+ const LOG_AGENT_UPDATE_BINARY_INVALID = (version) => `Downloaded binary '${version}' does not run on this machine, keeping the current one`;
574
+ exports.LOG_AGENT_UPDATE_BINARY_INVALID = LOG_AGENT_UPDATE_BINARY_INVALID;
575
+ const LOG_AGENT_UPDATE_COMMITTED = (version) => `Updated agent '${version}' connected, previous binary removed`;
576
+ exports.LOG_AGENT_UPDATE_COMMITTED = LOG_AGENT_UPDATE_COMMITTED;
577
+ const LOG_AGENT_UPDATE_ATTEMPT = (attempt, max) => `Updated agent did not connect yet, start ${attempt} of ${max} after the update`;
578
+ exports.LOG_AGENT_UPDATE_ATTEMPT = LOG_AGENT_UPDATE_ATTEMPT;
579
+ const LOG_AGENT_UPDATE_ROLLED_BACK = (from, to) => `Updated agent '${to}' kept restarting, rolled back to '${from}' and exiting so the service starts it`;
580
+ exports.LOG_AGENT_UPDATE_ROLLED_BACK = LOG_AGENT_UPDATE_ROLLED_BACK;
581
+ const LOG_AGENT_UPDATE_ROLLBACK_ACKED = (version) => `Update to '${version}' was rolled back, clearing the request so it is not retried`;
582
+ exports.LOG_AGENT_UPDATE_ROLLBACK_ACKED = LOG_AGENT_UPDATE_ROLLBACK_ACKED;
583
+ exports.LOG_AGENT_UPDATE_ROLLBACK_MISSING = 'Updated agent kept restarting but the previous binary is gone, nothing to roll back to';
559
584
  exports.LOG_AGENT_STARTED = 'Agent started';
560
585
  const LOG_TUNNEL_CONNECTED = (id, port) => `Tunnel '${id}' connected. Forwarding port '${port}'`;
561
586
  exports.LOG_TUNNEL_CONNECTED = LOG_TUNNEL_CONNECTED;
@@ -136,4 +136,5 @@ var TUNNEL_AGENT_STATUS;
136
136
  var TUNNEL_AGENT_ACTION;
137
137
  (function (TUNNEL_AGENT_ACTION) {
138
138
  TUNNEL_AGENT_ACTION["DELETE"] = "DELETE";
139
+ TUNNEL_AGENT_ACTION["UPDATE"] = "UPDATE";
139
140
  })(TUNNEL_AGENT_ACTION || (exports.TUNNEL_AGENT_ACTION = TUNNEL_AGENT_ACTION = {}));
@@ -36,8 +36,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
36
36
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.tryGetEmail = exports.execLocally = exports.getHomeDirectory = exports.isDomainAvailable = exports.newCommand = exports.formatBytes = exports.formatHelp = exports.getPlatform = exports.getHostname = exports.isStringRegExp = exports.getWorkingDir = exports.getRootDir = exports.TARGET_ONLY_PORT_REGEX = exports.TARGET_HTTP_REGEX = exports.TARGET_TCP_TLS_REGEX = exports.ApiErrorTunnelsDisabled = exports.ApiErrorWorkspaceFlagged = exports.ApiErrorTunnelLimitReached = exports.ApiErrorAgentLimitReached = exports.ApiErrorDomainRestricted = exports.ApiErrorTargetInvalid = exports.ApiErrorWrongToken = exports.ApiErrorFailedToConnect = exports.ApiErrorAgentNotFound = exports.ARTIFACT_AUTH_TYPE = exports.ARTIFACT_TYPE = exports.SANDBOX_SNAPSHOT_STATUS = exports.SANDBOX_APP_STATUS = exports.SANDBOX_SETUP_STATUS = exports.SANDBOX_EXEC_STATUS = exports.SANDBOX_EXEC_RUNTIME = exports.SANDBOX_STATUS = exports.REST_API_ENDPOINT = exports.REST_API_REGION = exports.DEFAULT_SANDBOX_CP_USER = exports.ARTIFACT_DEFAULT_VERSION = exports.SUGGESTED_BROWSER_VERSION = exports.AGENT_FETCH_RETRY_MAX = exports.AGENT_FETCH_RETRY_MIN = exports.SSH_HANDSHAKE_TIMEOUT = exports.DEFAULT_TIMEOUT = exports.TUNNEL_HTTP_RETRY_AFTER = exports.TUNNEL_HTTP_MAX_INFLIGHT = exports.TUNNEL_HTTP_CB_MIN_REQUESTS = exports.TUNNEL_HTTP_CB_WINDOW = exports.TUNNEL_MAX_REQUEST_SIZE_TO_SYNC = exports.TUNNEL_HTTP_LOG_MAX_REQUESTS = exports.TUNNEL_HTTP_LOG_MAX_BODY = exports.TUNNEL_HTTP_RATE_WINDOW = exports.TUNNEL_HTTP_RATE_LIMIT = void 0;
40
- exports.getGitName = exports.getGitEmail = exports.MCP_TOOL_CATEGORIES = exports.getBasicCommandTls = exports.getBasicCommandHttp = exports.getBasicCommandSandboxEndpoint = exports.getBasicCommandTcp = exports.getCurrentUser = exports.getServiceUser = exports.getRealTargetHost = exports.isWindows = exports.isLinux = exports.isOsx = exports.isDocker = exports.sleep = exports.getLatestVersion = exports.getVersionEnv = exports.getCurrentVersionWithoutEnv = exports.getVersionWithoutEnv = exports.getVersion = exports.isInstalledByChoco = exports.isInstalledByApt = exports.isInstalledByBrew = exports.isInstalledByNpm = void 0;
39
+ exports.getHomeDirectory = exports.isDomainAvailable = exports.newCommand = exports.formatBytes = exports.formatHelp = exports.getPlatform = exports.getHostname = exports.isStringRegExp = exports.getWorkingDir = exports.getRootDir = exports.TARGET_ONLY_PORT_REGEX = exports.TARGET_HTTP_REGEX = exports.TARGET_TCP_TLS_REGEX = exports.ApiErrorTunnelsDisabled = exports.ApiErrorWorkspaceFlagged = exports.ApiErrorTunnelLimitReached = exports.ApiErrorAgentLimitReached = exports.ApiErrorDomainRestricted = exports.ApiErrorTargetInvalid = exports.ApiErrorWrongToken = exports.ApiErrorFailedToConnect = exports.ApiErrorAgentNotFound = exports.ARTIFACT_AUTH_TYPE = exports.ARTIFACT_TYPE = exports.SANDBOX_SNAPSHOT_STATUS = exports.SANDBOX_APP_STATUS = exports.SANDBOX_SETUP_STATUS = exports.SANDBOX_EXEC_STATUS = exports.SANDBOX_EXEC_RUNTIME = exports.SANDBOX_STATUS = exports.REST_API_ENDPOINT = exports.REST_API_REGION = exports.DEFAULT_SANDBOX_CP_USER = exports.ARTIFACT_DEFAULT_VERSION = exports.SUGGESTED_BROWSER_VERSION = exports.AGENT_UPDATE_PROBATION_MS = exports.AGENT_UPDATE_MAX_ATTEMPTS = exports.AGENT_FETCH_RETRY_MAX = exports.AGENT_FETCH_RETRY_MIN = exports.SSH_HANDSHAKE_TIMEOUT = exports.DEFAULT_TIMEOUT = exports.TUNNEL_HTTP_RETRY_AFTER = exports.TUNNEL_HTTP_MAX_INFLIGHT = exports.TUNNEL_HTTP_CB_MIN_REQUESTS = exports.TUNNEL_HTTP_CB_WINDOW = exports.TUNNEL_MAX_REQUEST_SIZE_TO_SYNC = exports.TUNNEL_HTTP_LOG_MAX_REQUESTS = exports.TUNNEL_HTTP_LOG_MAX_BODY = exports.TUNNEL_HTTP_RATE_WINDOW = exports.TUNNEL_HTTP_RATE_LIMIT = void 0;
40
+ exports.getGitName = exports.getGitEmail = exports.MCP_TOOL_CATEGORIES = exports.getBasicCommandTls = exports.getBasicCommandHttp = exports.getBasicCommandSandboxEndpoint = exports.getBasicCommandTcp = exports.getCurrentUser = exports.getServiceUser = exports.getRealTargetHost = exports.isWindows = exports.isLinux = exports.isOsx = exports.isDocker = exports.sleep = exports.getLatestVersion = exports.getVersionEnv = exports.getCurrentVersionWithoutEnv = exports.getVersionWithoutEnv = exports.getVersion = exports.isInstalledByChoco = exports.isInstalledByApt = exports.isInstalledByBrew = exports.isInstalledByNpm = exports.tryGetEmail = exports.execLocally = void 0;
41
41
  exports.apiErrorCodeToClass = apiErrorCodeToClass;
42
42
  exports.isFile = isFile;
43
43
  exports.getAppWorkspaceUrl = getAppWorkspaceUrl;
@@ -82,6 +82,16 @@ exports.DEFAULT_TIMEOUT = 30;
82
82
  exports.SSH_HANDSHAKE_TIMEOUT = 10000;
83
83
  exports.AGENT_FETCH_RETRY_MIN = 3000;
84
84
  exports.AGENT_FETCH_RETRY_MAX = 60000;
85
+ // How many times a freshly updated agent may be started before the update is treated as
86
+ // broken and rolled back. Counted per process start rather than per failed fetch: a
87
+ // healthy binary does not restart, while an api outage would otherwise look identical to
88
+ // a bad binary and revert every agent in the fleet at once.
89
+ exports.AGENT_UPDATE_MAX_ATTEMPTS = 3;
90
+ // Backstop for the attempt counter above. The counter needs a write on every start, and a
91
+ // filesystem that has gone read-only would keep the count at zero forever - a deadline
92
+ // only has to be read. Generous on purpose: it is only ever reached when the counter
93
+ // cannot be persisted, so it must not fire on an agent that is merely slow to come up.
94
+ exports.AGENT_UPDATE_PROBATION_MS = 30 * 60 * 1000;
85
95
  exports.SUGGESTED_BROWSER_VERSION = '130.0.6723.69';
86
96
  exports.ARTIFACT_DEFAULT_VERSION = 'latest';
87
97
  exports.DEFAULT_SANDBOX_CP_USER = 'buddy';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "bdy",
3
3
  "preferGlobal": false,
4
- "version": "1.22.99-stage",
4
+ "version": "1.23.0-dev",
5
5
  "type": "commonjs",
6
6
  "license": "MIT",
7
7
  "homepage": "https://buddy.works/docs/cli",
@@ -26,7 +26,8 @@
26
26
  "e2e:pipeline": "vitest run --config e2e/vitest.config.ts e2e/modules/pipeline/",
27
27
  "e2e:tunnel": "vitest run --config e2e/vitest.config.ts e2e/modules/tunnel/",
28
28
  "e2e:agent": "vitest run --config e2e/vitest.config.ts e2e/modules/agent/",
29
- "e2e:distro": "vitest run --config e2e/vitest.config.ts e2e/modules/distro/"
29
+ "e2e:distro": "vitest run --config e2e/vitest.config.ts e2e/modules/distro/",
30
+ "unit": "vitest run --config vitest.config.ts"
30
31
  },
31
32
  "files": [
32
33
  "distTs"