tide-commander 1.159.0 → 1.159.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.
- package/CHANGELOG.md +10 -0
- package/dist/assets/{BossLogsModal-B1efaCOD.js → BossLogsModal-D7DRbxuN.js} +1 -1
- package/dist/assets/{BossSpawnModal-CsEylDz3.js → BossSpawnModal-qWqV6cXb.js} +1 -1
- package/dist/assets/{ControlsModal-VoXduUsZ.js → ControlsModal-Dx4Sd-zd.js} +1 -1
- package/dist/assets/{DockerLogsModal-C6sMnLBl.js → DockerLogsModal-DnBm69YT.js} +1 -1
- package/dist/assets/{EmbeddedEditor-Cph0We_D.js → EmbeddedEditor-egK0IcwH.js} +1 -1
- package/dist/assets/{GmailOAuthSetup-BLRlfaUq.js → GmailOAuthSetup-Bi51Jkf8.js} +1 -1
- package/dist/assets/{GoogleOAuthSetup-D3QpuVDO.js → GoogleOAuthSetup-BAREZ_c-.js} +1 -1
- package/dist/assets/{IframeModal-85pHW-pq.js → IframeModal-Rh1yC6CF.js} +1 -1
- package/dist/assets/{IntegrationsPanel-CD67Zpbe.js → IntegrationsPanel-BPmG30Kf.js} +2 -2
- package/dist/assets/{LogViewerModal-BwxMq9Ut.js → LogViewerModal-V3LGKLOd.js} +1 -1
- package/dist/assets/{MonitoringModal-CMEOZ95G.js → MonitoringModal-D5ObJhXH.js} +1 -1
- package/dist/assets/{PM2LogsModal-B8U7Twg5.js → PM2LogsModal-DyNAmc5D.js} +1 -1
- package/dist/assets/{RestoreArchivedAreaModal-Djc-HI0I.js → RestoreArchivedAreaModal-C1afIOVX.js} +1 -1
- package/dist/assets/{Scene2DCanvas-3ELgvFj7.js → Scene2DCanvas-C7weuP-e.js} +1 -1
- package/dist/assets/{SceneManager-DGDAQjiM.js → SceneManager-Cub1EW5Y.js} +1 -1
- package/dist/assets/{SkillsPanel-C_VJxYq6.js → SkillsPanel-C3PG0A6A.js} +1 -1
- package/dist/assets/{SlackMultiInstanceSetup-CU_ciZt8.js → SlackMultiInstanceSetup-vq1FipyR.js} +1 -1
- package/dist/assets/{SpawnModal-4UWGDXA5.js → SpawnModal-Df2Vp-HA.js} +1 -1
- package/dist/assets/{StatisticsModal-t3BmlLeA.js → StatisticsModal-D0yo2rbm.js} +1 -1
- package/dist/assets/{SubordinateAssignmentModal-DadewDiC.js → SubordinateAssignmentModal-BHQS1Xc_.js} +1 -1
- package/dist/assets/{TriggerManagerPanel-CsRxQshw.js → TriggerManagerPanel-CEVMReTJ.js} +1 -1
- package/dist/assets/{WorkflowEditorPanel-D8HdloWl.js → WorkflowEditorPanel-BQbr0HYZ.js} +1 -1
- package/dist/assets/{area-logos-DT0p0ZNy.js → area-logos-CbdG7b49.js} +1 -1
- package/dist/assets/{index-DZ1dDpMc.js → index--FFJ9DPS.js} +1 -1
- package/dist/assets/{index-DxzEz7Wq.js → index-B4PPDHAS.js} +1 -1
- package/dist/assets/{index-CXV0mjYb.js → index-BvEk2Spw.js} +3 -3
- package/dist/assets/{index-CNb62smT.js → index-C57r58R1.js} +1 -1
- package/dist/assets/{index-COzjdZHI.js → index-CxUhEi9L.js} +1 -1
- package/dist/assets/{index-BeP_1e9F.js → index-DN1jWADn.js} +1 -1
- package/dist/assets/{index-BWeUgDS_.js → index-EAqEvdMn.js} +2 -2
- package/dist/assets/{index-sqLiegdk.js → index-Vee1Cpl9.js} +1 -1
- package/dist/assets/{index-pnFcxt52.js → index-fFR_58oB.js} +1 -1
- package/dist/assets/{main-DM6oMRZH.js → main-Btdl34Y5.js} +8 -8
- package/dist/assets/{web-bc8PmuWG.js → web-Brq808vy.js} +1 -1
- package/dist/assets/{web-UIwBVJek.js → web-CACmzQOn.js} +1 -1
- package/dist/assets/{web-63aqCy2N.js → web-DPUDmaxp.js} +1 -1
- package/dist/build-info.json +1 -1
- package/dist/index.html +1 -1
- package/dist/src/packages/server/cli.js +22 -1
- package/dist/src/packages/server/services/self-update-service.js +50 -8
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{df as a}from"./main-
|
|
1
|
+
import{df as a}from"./main-Btdl34Y5.js";import{ImpactStyle as i,NotificationType as r}from"./index-EAqEvdMn.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class h extends a{constructor(){super(...arguments),this.selectionStarted=!1}async impact(t){const e=this.patternForImpact(t==null?void 0:t.style);this.vibrateWithPattern(e)}async notification(t){const e=this.patternForNotification(t==null?void 0:t.type);this.vibrateWithPattern(e)}async vibrate(t){const e=(t==null?void 0:t.duration)||300;this.vibrateWithPattern([e])}async selectionStart(){this.selectionStarted=!0}async selectionChanged(){this.selectionStarted&&this.vibrateWithPattern([70])}async selectionEnd(){this.selectionStarted=!1}patternForImpact(t=i.Heavy){return t===i.Medium?[43]:t===i.Light?[20]:[61]}patternForNotification(t=r.Success){return t===r.Warning?[30,40,30,50,60]:t===r.Error?[27,45,50]:[35,65,21]}vibrateWithPattern(t){if(navigator.vibrate)navigator.vibrate(t);else throw this.unavailable("Browser does not support the vibrate API")}}export{h as HapticsWeb};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{df as s}from"./main-
|
|
1
|
+
import{df as s}from"./main-Btdl34Y5.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class l extends s{constructor(){super(...arguments),this.pending=[],this.deliveredNotifications=[],this.hasNotificationSupport=()=>{if(!("Notification"in window)||!Notification.requestPermission)return!1;if(Notification.permission!=="granted")try{new Notification("")}catch(i){if(i instanceof Error&&i.name==="TypeError")return!1}return!0}}async getDeliveredNotifications(){const i=[];for(const t of this.deliveredNotifications){const e={title:t.title,id:parseInt(t.tag),body:t.body};i.push(e)}return{notifications:i}}async removeDeliveredNotifications(i){for(const t of i.notifications){const e=this.deliveredNotifications.find(n=>n.tag===String(t.id));e==null||e.close(),this.deliveredNotifications=this.deliveredNotifications.filter(()=>!e)}}async removeAllDeliveredNotifications(){for(const i of this.deliveredNotifications)i.close();this.deliveredNotifications=[]}async createChannel(){throw this.unimplemented("Not implemented on web.")}async deleteChannel(){throw this.unimplemented("Not implemented on web.")}async listChannels(){throw this.unimplemented("Not implemented on web.")}async schedule(i){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");for(const t of i.notifications)this.sendNotification(t);return{notifications:i.notifications.map(t=>({id:t.id}))}}async getPending(){return{notifications:this.pending}}async registerActionTypes(){throw this.unimplemented("Not implemented on web.")}async cancel(i){this.pending=this.pending.filter(t=>!i.notifications.find(e=>e.id===t.id))}async areEnabled(){const{display:i}=await this.checkPermissions();return{value:i==="granted"}}async changeExactNotificationSetting(){throw this.unimplemented("Not implemented on web.")}async checkExactNotificationSetting(){throw this.unimplemented("Not implemented on web.")}async requestPermissions(){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");return{display:this.transformNotificationPermission(await Notification.requestPermission())}}async checkPermissions(){if(!this.hasNotificationSupport())throw this.unavailable("Notifications not supported in this browser.");return{display:this.transformNotificationPermission(Notification.permission)}}transformNotificationPermission(i){switch(i){case"granted":return"granted";case"denied":return"denied";default:return"prompt"}}sendPending(){var i;const t=[],e=new Date().getTime();for(const n of this.pending)!((i=n.schedule)===null||i===void 0)&&i.at&&n.schedule.at.getTime()<=e&&(this.buildNotification(n),t.push(n));this.pending=this.pending.filter(n=>!t.find(o=>o===n))}sendNotification(i){var t;if(!((t=i.schedule)===null||t===void 0)&&t.at){const e=i.schedule.at.getTime()-new Date().getTime();this.pending.push(i),setTimeout(()=>{this.sendPending()},e);return}this.buildNotification(i)}buildNotification(i){const t=new Notification(i.title,{body:i.body,tag:String(i.id)});return t.addEventListener("click",this.onClick.bind(this,i),!1),t.addEventListener("show",this.onShow.bind(this,i),!1),t.addEventListener("close",()=>{this.deliveredNotifications=this.deliveredNotifications.filter(()=>!this)},!1),this.deliveredNotifications.push(t),t}onClick(i){const t={actionId:"tap",notification:i};this.notifyListeners("localNotificationActionPerformed",t)}onShow(i){this.notifyListeners("localNotificationReceived",i)}}export{l as LocalNotificationsWeb};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{df as t}from"./main-
|
|
1
|
+
import{df as t}from"./main-Btdl34Y5.js";import"./vendor-react--Eh9ivFN.js";import"./vendor-three-Chj50gSY.js";class o extends t{constructor(){super(),this.handleVisibilityChange=()=>{const e={isActive:document.hidden!==!0};this.notifyListeners("appStateChange",e),document.hidden?this.notifyListeners("pause",null):this.notifyListeners("resume",null)},document.addEventListener("visibilitychange",this.handleVisibilityChange,!1)}exitApp(){throw this.unimplemented("Not implemented on web.")}async getInfo(){throw this.unimplemented("Not implemented on web.")}async getLaunchUrl(){return{url:""}}async getState(){return{isActive:document.hidden!==!0}}async minimizeApp(){throw this.unimplemented("Not implemented on web.")}async toggleBackButtonHandler(){throw this.unimplemented("Not implemented on web.")}async getAppLanguage(){return{value:navigator.language.split("-")[0].toLowerCase()}}}export{o as AppWeb};
|
package/dist/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":"1.159.
|
|
1
|
+
{"version":"1.159.2"}
|
package/dist/index.html
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
<link rel="icon" type="image/png" sizes="16x16" href="/assets/icons/favicon-16x16.png" />
|
|
23
23
|
<link rel="apple-touch-icon" sizes="180x180" href="/assets/icons/apple-touch-icon.png" />
|
|
24
24
|
<title>Tide Commander</title>
|
|
25
|
-
<script type="module" crossorigin src="/assets/main-
|
|
25
|
+
<script type="module" crossorigin src="/assets/main-Btdl34Y5.js"></script>
|
|
26
26
|
<link rel="modulepreload" crossorigin href="/assets/vendor-react--Eh9ivFN.js">
|
|
27
27
|
<link rel="modulepreload" crossorigin href="/assets/vendor-three-Chj50gSY.js">
|
|
28
28
|
<link rel="stylesheet" crossorigin href="/assets/main-BZcOdtO_.css">
|
|
@@ -318,14 +318,35 @@ function readPidFile() {
|
|
|
318
318
|
return null;
|
|
319
319
|
}
|
|
320
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* True only if `pid` is a *live* process. A bare `kill(pid, 0)` probe is not
|
|
323
|
+
* enough: on Linux a zombie (State: Z — exited but not yet reaped by its parent)
|
|
324
|
+
* still occupies the process table, so the probe succeeds for it too. In
|
|
325
|
+
* containers whose PID 1 doesn't reap children, an unreaped launcher would then
|
|
326
|
+
* be mistaken for a running server — the startup guard waits on it forever, the
|
|
327
|
+
* follow-up SIGKILL no-ops, and the launch crash-loops. Treat zombies as dead by
|
|
328
|
+
* inspecting /proc/<pid>/stat; if /proc is unavailable (non-Linux) or the read
|
|
329
|
+
* races, fall back to trusting the signal probe.
|
|
330
|
+
*/
|
|
321
331
|
function isRunning(pid) {
|
|
322
332
|
try {
|
|
323
333
|
process.kill(pid, 0);
|
|
324
|
-
return true;
|
|
325
334
|
}
|
|
326
335
|
catch {
|
|
327
336
|
return false;
|
|
328
337
|
}
|
|
338
|
+
try {
|
|
339
|
+
const stat = fs.readFileSync(`/proc/${pid}/stat`, 'utf8');
|
|
340
|
+
// Format: "pid (comm) state ...". comm may contain spaces or ')', so key off
|
|
341
|
+
// the final ')' to locate the single-char state field that follows it.
|
|
342
|
+
const state = stat.slice(stat.lastIndexOf(')') + 1).trim()[0];
|
|
343
|
+
if (state === 'Z')
|
|
344
|
+
return false;
|
|
345
|
+
}
|
|
346
|
+
catch {
|
|
347
|
+
// /proc missing (non-Linux) or the process vanished mid-read — trust kill(0).
|
|
348
|
+
}
|
|
349
|
+
return true;
|
|
329
350
|
}
|
|
330
351
|
async function waitForProcessExit(pid, timeoutMs = 8000) {
|
|
331
352
|
const started = Date.now();
|
|
@@ -228,21 +228,63 @@ export function runNpmGlobalUpdate(callbacks = {}) {
|
|
|
228
228
|
});
|
|
229
229
|
});
|
|
230
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* Detect a process supervisor that already restarts us on exit.
|
|
233
|
+
*
|
|
234
|
+
* Under PM2 (the common `tide-commander --foreground` deployment) spawning our
|
|
235
|
+
* own detached relauncher is actively harmful: PM2 ALSO restarts the process the
|
|
236
|
+
* moment the old server exits, so the relauncher's new server and PM2's fresh
|
|
237
|
+
* server race for the same port. The loser dies with EADDRINUSE and — in
|
|
238
|
+
* containers whose PID 1 doesn't reap — lingers as a zombie that then trips the
|
|
239
|
+
* launcher's port guard on the next boot (the multi-day crash loop).
|
|
240
|
+
*
|
|
241
|
+
* PM2 injects pm_id / PM2_HOME into every managed process, and the launcher
|
|
242
|
+
* passes its env straight to the server child, so these are visible here. An
|
|
243
|
+
* explicit TIDE_COMMANDER_SUPERVISED=1 lets other auto-restarting supervisors
|
|
244
|
+
* (systemd Restart=, docker restart-policy) opt into the same behaviour.
|
|
245
|
+
*
|
|
246
|
+
* NOTE: we deliberately do NOT key on TIDE_COMMANDER_FOREGROUND — foreground is
|
|
247
|
+
* not the same as supervised. A bare `--foreground` attached in a terminal has
|
|
248
|
+
* nothing to restart it, so there the detached relauncher must stay.
|
|
249
|
+
*/
|
|
250
|
+
function isSupervisedRestart() {
|
|
251
|
+
return (process.env.pm_id !== undefined ||
|
|
252
|
+
Boolean(process.env.PM2_HOME) ||
|
|
253
|
+
process.env.TIDE_COMMANDER_SUPERVISED === '1');
|
|
254
|
+
}
|
|
231
255
|
/**
|
|
232
256
|
* After a successful global update, bring up the freshly installed binary
|
|
233
257
|
* without the user having to relaunch by hand.
|
|
234
258
|
*
|
|
235
|
-
*
|
|
236
|
-
*
|
|
237
|
-
*
|
|
238
|
-
*
|
|
239
|
-
*
|
|
240
|
-
*
|
|
259
|
+
* When supervised (PM2/systemd/docker — see isSupervisedRestart), we simply exit:
|
|
260
|
+
* the supervisor restarts the process into the already-on-disk new code, and
|
|
261
|
+
* spawning our own relauncher would only race it for the port.
|
|
262
|
+
*
|
|
263
|
+
* Otherwise (standalone install) spawns a fully detached
|
|
264
|
+
* `tide-commander start --restart` that inherits the current server's
|
|
265
|
+
* environment (same PORT/HOST/AUTH_TOKEN/HTTPS). That process SIGTERMs the
|
|
266
|
+
* still-running old server (triggering its graceful shutdown so the port is
|
|
267
|
+
* released), waits for it to exit, then starts the new server and rewrites the
|
|
268
|
+
* PID file. The caller MUST NOT exit — the relauncher (or, when supervised, our
|
|
269
|
+
* own scheduled exit) drives the handoff.
|
|
241
270
|
*
|
|
242
|
-
* Returns true if
|
|
243
|
-
* (in which case the caller should fall
|
|
271
|
+
* Returns true if a restart was scheduled (relauncher spawned, or supervised
|
|
272
|
+
* exit queued), false if it could not be (in which case the caller should fall
|
|
273
|
+
* back to exiting for a manual restart).
|
|
244
274
|
*/
|
|
245
275
|
export function schedulePostUpdateRestart(delayMs = 600) {
|
|
276
|
+
// Supervised deployment: don't spawn a competing relauncher. Exit after the
|
|
277
|
+
// same flush grace so any in-flight SSE 'done' frame reaches the client, then
|
|
278
|
+
// let the process manager restart us into the freshly-installed build.
|
|
279
|
+
if (isSupervisedRestart()) {
|
|
280
|
+
log.log('Supervised restart (PM2/systemd/docker) detected — exiting for the process manager to restart into the updated build.');
|
|
281
|
+
const timer = setTimeout(() => {
|
|
282
|
+
log.log('Exiting now; the process manager will restart Tide Commander.');
|
|
283
|
+
process.exit(0);
|
|
284
|
+
}, delayMs);
|
|
285
|
+
timer.unref?.();
|
|
286
|
+
return true;
|
|
287
|
+
}
|
|
246
288
|
let cliPath;
|
|
247
289
|
try {
|
|
248
290
|
// self-update-service.js lives at dist/.../server/services/, the CLI entry
|