@markus-global/cli 0.7.3-rc.1 → 0.7.3-rc.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/dist/markus.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env -S node --disable-warning=ExperimentalWarning
2
- import { createRequire } from 'module';
3
- const require = createRequire(import.meta.url);
2
+ import { createRequire as _createRequire } from 'module';
3
+ const require = _createRequire(import.meta.url);
4
4
  var __create = Object.create;
5
5
  var __defProp = Object.defineProperty;
6
6
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -56416,7 +56416,7 @@ async function runMcpTest() {
56416
56416
  let requestId = 1;
56417
56417
  const pending = /* @__PURE__ */ new Map();
56418
56418
  let cleaned = false;
56419
- const cleanup2 = () => {
56419
+ const cleanup = () => {
56420
56420
  if (cleaned)
56421
56421
  return;
56422
56422
  cleaned = true;
@@ -56426,13 +56426,13 @@ async function runMcpTest() {
56426
56426
  }
56427
56427
  };
56428
56428
  const timeout = setTimeout(() => {
56429
- cleanup2();
56429
+ cleanup();
56430
56430
  const stderr = stderrChunks.join("").slice(0, 300);
56431
56431
  rejectTest(new Error(`MCP test timed out after 60s${stderr ? ` (stderr: ${stderr})` : ""}`));
56432
56432
  }, 6e4);
56433
56433
  proc.on("error", (err) => {
56434
56434
  clearTimeout(timeout);
56435
- cleanup2();
56435
+ cleanup();
56436
56436
  rejectTest(err);
56437
56437
  });
56438
56438
  proc.stderr?.on("data", (data) => {
@@ -56498,11 +56498,11 @@ async function runMcpTest() {
56498
56498
  const text = navResult?.content?.[0]?.text ?? "";
56499
56499
  const navigated = !text.toLowerCase().includes("error");
56500
56500
  clearTimeout(timeout);
56501
- cleanup2();
56501
+ cleanup();
56502
56502
  resolveTest({ navigated, title: navigated ? "example.com" : void 0 });
56503
56503
  } catch (err) {
56504
56504
  clearTimeout(timeout);
56505
- cleanup2();
56505
+ cleanup();
56506
56506
  rejectTest(err instanceof Error ? err : new Error(String(err)));
56507
56507
  }
56508
56508
  })();
@@ -83415,7 +83415,7 @@ ${cleanText}`,
83415
83415
  }
83416
83416
  if (action === "message") {
83417
83417
  const body = await this.readBody(req);
83418
- const stream2 = body["stream"];
83418
+ const stream = body["stream"];
83419
83419
  const senderId = authUser.userId;
83420
83420
  const sessionId = body["sessionId"] ?? void 0;
83421
83421
  const images = body["images"]?.filter(Boolean);
@@ -83449,7 +83449,7 @@ ${cleanText}`,
83449
83449
  }
83450
83450
  return dbSessId;
83451
83451
  };
83452
- if (stream2) {
83452
+ if (stream) {
83453
83453
  const sseHandler = new SSEHandler({
83454
83454
  agentId: agentId2,
83455
83455
  agent,
@@ -86072,8 +86072,8 @@ EXPLANATION_END`;
86072
86072
  const senderInfo = this.orgService.resolveHumanIdentity(senderId);
86073
86073
  const agent = this.orgService.getAgentManager().getAgent(targetAgentId);
86074
86074
  this.ws.broadcastAgentUpdate(targetAgentId, "working");
86075
- const stream2 = body["stream"];
86076
- if (stream2) {
86075
+ const stream = body["stream"];
86076
+ if (stream) {
86077
86077
  const userText = body["text"];
86078
86078
  const sseHandler = new SSEHandler({
86079
86079
  agentId: targetAgentId,
@@ -98985,135 +98985,22 @@ var init_init = __esm({
98985
98985
  }
98986
98986
  });
98987
98987
 
98988
- // ../../node_modules/.pnpm/node-datachannel@0.12.0/node_modules/node-datachannel/lib/node-datachannel.js
98989
- import { createRequire } from "module";
98990
- var require2, nodeDataChannel, node_datachannel_default;
98991
- var init_node_datachannel = __esm({
98992
- "../../node_modules/.pnpm/node-datachannel@0.12.0/node_modules/node-datachannel/lib/node-datachannel.js"() {
98993
- require2 = createRequire(import.meta.url);
98994
- nodeDataChannel = require2("../build/Release/node_datachannel.node");
98995
- node_datachannel_default = nodeDataChannel;
98996
- }
98997
- });
98998
-
98999
- // ../../node_modules/.pnpm/node-datachannel@0.12.0/node_modules/node-datachannel/lib/datachannel-stream.js
99000
- import stream from "stream";
99001
- var DataChannelStream;
99002
- var init_datachannel_stream = __esm({
99003
- "../../node_modules/.pnpm/node-datachannel@0.12.0/node_modules/node-datachannel/lib/datachannel-stream.js"() {
99004
- DataChannelStream = class extends stream.Duplex {
99005
- constructor(rawChannel, streamOptions) {
99006
- super({
99007
- allowHalfOpen: false,
99008
- // Default to autoclose on end().
99009
- ...streamOptions,
99010
- objectMode: true
99011
- // Preserve the string/buffer distinction (WebRTC treats them differently)
99012
- });
99013
- this._rawChannel = rawChannel;
99014
- this._readActive = true;
99015
- rawChannel.onMessage((msg) => {
99016
- if (!this._readActive) return;
99017
- this._readActive = this.push(msg);
99018
- });
99019
- rawChannel.onClosed(() => {
99020
- this.push(null);
99021
- this.destroy();
99022
- });
99023
- rawChannel.onError((errMsg) => {
99024
- this.destroy(new Error(`DataChannel error: ${errMsg}`));
99025
- });
99026
- if (!rawChannel.isOpen()) {
99027
- this.cork();
99028
- rawChannel.onOpen(() => this.uncork());
99029
- }
99030
- }
99031
- _read() {
99032
- this._readActive = true;
99033
- }
99034
- _write(chunk, encoding, callback) {
99035
- let sentOk;
99036
- try {
99037
- if (Buffer.isBuffer(chunk)) {
99038
- sentOk = this._rawChannel.sendMessageBinary(chunk);
99039
- } else if (typeof chunk === "string") {
99040
- sentOk = this._rawChannel.sendMessage(chunk);
99041
- } else {
99042
- const typeName = chunk.constructor.name || typeof chunk;
99043
- throw new Error(`Cannot write ${typeName} to DataChannel stream`);
99044
- }
99045
- } catch (err) {
99046
- return callback(err);
99047
- }
99048
- if (sentOk) {
99049
- callback(null);
99050
- } else {
99051
- callback(new Error("Failed to write to DataChannel"));
99052
- }
99053
- }
99054
- _final(callback) {
99055
- if (!this.allowHalfOpen) this.destroy();
99056
- callback(null);
99057
- }
99058
- _destroy(maybeErr, callback) {
99059
- this._rawChannel.close();
99060
- callback(maybeErr);
99061
- }
99062
- get label() {
99063
- return this._rawChannel.getLabel();
99064
- }
99065
- get id() {
99066
- return this._rawChannel.getId();
99067
- }
99068
- get protocol() {
99069
- return this._rawChannel.getProtocol();
99070
- }
99071
- };
99072
- }
99073
- });
99074
-
99075
- // ../../node_modules/.pnpm/node-datachannel@0.12.0/node_modules/node-datachannel/lib/websocket-server.js
99076
- var init_websocket_server = __esm({
99077
- "../../node_modules/.pnpm/node-datachannel@0.12.0/node_modules/node-datachannel/lib/websocket-server.js"() {
99078
- init_node_datachannel();
99079
- }
99080
- });
99081
-
99082
- // ../../node_modules/.pnpm/node-datachannel@0.12.0/node_modules/node-datachannel/lib/index.js
99083
- var initLogger, cleanup, preload, setSctpSettings, RtcpReceivingSession, Track, Video, Audio, DataChannel, PeerConnection, WebSocket2, DescriptionType;
99084
- var init_lib = __esm({
99085
- "../../node_modules/.pnpm/node-datachannel@0.12.0/node_modules/node-datachannel/lib/index.js"() {
99086
- init_node_datachannel();
99087
- init_datachannel_stream();
99088
- init_websocket_server();
99089
- ({
99090
- initLogger,
99091
- cleanup,
99092
- preload,
99093
- setSctpSettings,
99094
- RtcpReceivingSession,
99095
- Track,
99096
- Video,
99097
- Audio,
99098
- DataChannel,
99099
- PeerConnection,
99100
- WebSocket: WebSocket2
99101
- } = node_datachannel_default);
99102
- DescriptionType = {
99103
- Unspec: "unspec",
99104
- Offer: "offer",
99105
- Answer: "answer",
99106
- Pranswer: "pranswer",
99107
- Rollback: "rollback"
99108
- };
99109
- }
99110
- });
99111
-
99112
98988
  // ../remote/dist/agent.js
99113
- import { WebSocket as WebSocket3 } from "ws";
98989
+ import { WebSocket as WebSocket2 } from "ws";
99114
98990
  import { request as httpRequest } from "node:http";
99115
98991
  import { request as httpsRequest } from "node:https";
99116
98992
  import { createHmac as createHmac2 } from "node:crypto";
98993
+ async function loadRtcModule() {
98994
+ if (!_rtcModule) {
98995
+ _rtcModule = await import("node-datachannel");
98996
+ }
98997
+ return _rtcModule;
98998
+ }
98999
+ function getRtcModule() {
99000
+ if (!_rtcModule)
99001
+ throw new Error("node-datachannel not loaded \u2014 call loadRtcModule() first");
99002
+ return _rtcModule;
99003
+ }
99117
99004
  function base64url(buf) {
99118
99005
  return buf.toString("base64").replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
99119
99006
  }
@@ -99123,13 +99010,13 @@ function signJwt(payload, secret) {
99123
99010
  const sig = base64url(createHmac2("sha256", secret).update(`${header}.${body}`).digest());
99124
99011
  return `${header}.${body}.${sig}`;
99125
99012
  }
99126
- var log86, STUN_SERVERS, RECONNECT_BASE_MS, RECONNECT_MAX_MS, HEARTBEAT_INTERVAL_MS, PEER_PING_INTERVAL_MS, PEER_PING_TIMEOUT_MS, RELAY_INACTIVITY_TIMEOUT_MS, RemoteAccessAgent;
99013
+ var log86, _rtcModule, STUN_SERVERS, RECONNECT_BASE_MS, RECONNECT_MAX_MS, HEARTBEAT_INTERVAL_MS, PEER_PING_INTERVAL_MS, PEER_PING_TIMEOUT_MS, RELAY_INACTIVITY_TIMEOUT_MS, RemoteAccessAgent;
99127
99014
  var init_agent3 = __esm({
99128
99015
  "../remote/dist/agent.js"() {
99129
99016
  "use strict";
99130
99017
  init_dist();
99131
- init_lib();
99132
99018
  log86 = createLogger("remote");
99019
+ _rtcModule = null;
99133
99020
  STUN_SERVERS = [
99134
99021
  "stun:stun.l.google.com:19302",
99135
99022
  "stun:stun.cloudflare.com:3478"
@@ -99153,12 +99040,13 @@ var init_agent3 = __esm({
99153
99040
  statusListeners = /* @__PURE__ */ new Set();
99154
99041
  constructor(config) {
99155
99042
  this.config = config;
99156
- initLogger("Warning");
99157
99043
  }
99158
99044
  // ── Public API ────────────────────────────────────────────────────────────
99159
99045
  async start() {
99160
99046
  this.destroyed = false;
99161
99047
  log86.info("Starting remote access agent...");
99048
+ const rtc = await loadRtcModule();
99049
+ rtc.initLogger("Warning");
99162
99050
  await this.discoverLocalOwner();
99163
99051
  try {
99164
99052
  this.registration = await this.registerInstance();
@@ -99231,7 +99119,7 @@ var init_agent3 = __esm({
99231
99119
  log86.info("Remote access agent stopped");
99232
99120
  }
99233
99121
  getStatus() {
99234
- const wsOpen = this.ws?.readyState === WebSocket3.OPEN;
99122
+ const wsOpen = this.ws?.readyState === WebSocket2.OPEN;
99235
99123
  let state = "idle";
99236
99124
  if (!this.destroyed) {
99237
99125
  if (wsOpen)
@@ -99338,7 +99226,7 @@ var init_agent3 = __esm({
99338
99226
  const { signalUrl, signalingToken } = this.registration;
99339
99227
  const wsUrl = `${signalUrl}?token=${encodeURIComponent(signalingToken)}`;
99340
99228
  log86.info("Connecting to signal server...", { signalUrl });
99341
- const ws = new WebSocket3(wsUrl);
99229
+ const ws = new WebSocket2(wsUrl);
99342
99230
  this.ws = ws;
99343
99231
  ws.on("open", () => {
99344
99232
  log86.info("Signal server connected");
@@ -99430,7 +99318,7 @@ var init_agent3 = __esm({
99430
99318
  } else {
99431
99319
  log86.info("Received offer for existing peer (ICE restart)", { peerId });
99432
99320
  }
99433
- session.pc.setRemoteDescription(sdp, DescriptionType.Offer);
99321
+ session.pc.setRemoteDescription(sdp, getRtcModule().DescriptionType.Offer);
99434
99322
  }
99435
99323
  handleIce(peerId, candidate, mid) {
99436
99324
  const session = this.peers.get(peerId);
@@ -99466,6 +99354,7 @@ var init_agent3 = __esm({
99466
99354
  }
99467
99355
  }
99468
99356
  }
99357
+ const { PeerConnection } = getRtcModule();
99469
99358
  const pc = new PeerConnection(`markus-${peerId}`, {
99470
99359
  iceServers
99471
99360
  });
@@ -99731,7 +99620,7 @@ var init_agent3 = __esm({
99731
99620
  if (session?.markusToken) {
99732
99621
  headers["cookie"] = `markus_token=${session.markusToken}`;
99733
99622
  }
99734
- const ws = new WebSocket3(wsUrl, { headers });
99623
+ const ws = new WebSocket2(wsUrl, { headers });
99735
99624
  const key2 = `${peerId}:${wsId}`;
99736
99625
  ws.on("open", () => {
99737
99626
  this.wsConnections.set(key2, ws);
@@ -99757,7 +99646,7 @@ var init_agent3 = __esm({
99757
99646
  const wsId = msg.wsId;
99758
99647
  const key2 = `${peerId}:${wsId}`;
99759
99648
  const ws = this.wsConnections.get(key2);
99760
- if (ws?.readyState === WebSocket3.OPEN) {
99649
+ if (ws?.readyState === WebSocket2.OPEN) {
99761
99650
  ws.send(msg.data);
99762
99651
  }
99763
99652
  }
@@ -99805,14 +99694,14 @@ var init_agent3 = __esm({
99805
99694
  log86.warn("DataChannel send failed, falling back to relay", { peerId, error: String(err) });
99806
99695
  }
99807
99696
  }
99808
- if (this.ws?.readyState === WebSocket3.OPEN) {
99697
+ if (this.ws?.readyState === WebSocket2.OPEN) {
99809
99698
  this.send({ type: "relay_frame", peerId, data });
99810
99699
  return;
99811
99700
  }
99812
99701
  log86.warn("No transport available for peer", { peerId });
99813
99702
  }
99814
99703
  send(msg) {
99815
- if (this.ws?.readyState === WebSocket3.OPEN) {
99704
+ if (this.ws?.readyState === WebSocket2.OPEN) {
99816
99705
  this.ws.send(JSON.stringify(msg));
99817
99706
  }
99818
99707
  }
package/dist/tray.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Cross-platform system tray controller for Markus.
3
- * Provides start/stop controls and quick access to the Web UI.
3
+ * Launches the server on start, provides "Open Console" and "Quit" controls.
4
4
  */
5
5
  export {};
6
6
  //# sourceMappingURL=tray.d.ts.map
package/dist/tray.js CHANGED
@@ -1,9 +1,9 @@
1
1
  /**
2
2
  * Cross-platform system tray controller for Markus.
3
- * Provides start/stop controls and quick access to the Web UI.
3
+ * Launches the server on start, provides "Open Console" and "Quit" controls.
4
4
  */
5
5
  import { spawn, exec, execSync } from 'node:child_process';
6
- import { readFileSync, existsSync, mkdirSync, appendFileSync } from 'node:fs';
6
+ import { readFileSync, existsSync, mkdirSync, appendFileSync, openSync } from 'node:fs';
7
7
  import { get as httpGet } from 'node:http';
8
8
  import { createConnection } from 'node:net';
9
9
  import { resolve, dirname, join } from 'node:path';
@@ -18,39 +18,18 @@ const BIN_DIR = __dirname;
18
18
  const APP_DIR = resolve(BIN_DIR, '..');
19
19
  const LOG_DIR = resolve(homedir(), '.markus', 'logs');
20
20
  const LOG_FILE = join(LOG_DIR, 'tray-stderr.log');
21
- // Resolve the markus command: prefer the symlink in /usr/local/bin,
22
- // then fall back to the bundled wrapper script, then to direct node invocation.
23
- function resolveMarkusCommand() {
24
- const symlink = '/usr/local/bin/markus';
25
- if (existsSync(symlink)) {
26
- return { cmd: symlink, args: ['start'] };
27
- }
28
- const wrapper = resolve(APP_DIR, 'markus');
29
- if (existsSync(wrapper)) {
30
- return { cmd: wrapper, args: ['start'] };
31
- }
32
- const nodeBin = resolve(BIN_DIR, platform() === 'win32' ? 'node.exe' : 'node');
33
- const markusMjs = resolve(BIN_DIR, 'markus.mjs');
34
- return { cmd: nodeBin, args: [markusMjs, 'start'] };
35
- }
36
21
  const STRINGS = {
37
22
  en: {
38
- openUI: 'Open Web UI',
39
- startServer: 'Start Server',
40
- stopServer: 'Stop Server',
23
+ openUI: 'Open Console',
41
24
  quit: 'Quit Markus',
42
- tooltipRunning: 'Markus (running)',
43
- tooltipStopped: 'Markus (stopped)',
25
+ tooltip: 'Markus',
44
26
  portConflictTitle: 'Markus',
45
27
  portConflictMsg: (port, occupant) => `Port ${port} is already in use by "${occupant}".\\nMarkus cannot start.\\n\\nFree the port or change it in ~/.markus/markus.json`,
46
28
  },
47
29
  zh: {
48
30
  openUI: '打开控制台',
49
- startServer: '启动服务',
50
- stopServer: '停止服务',
51
31
  quit: '退出 Markus',
52
- tooltipRunning: 'Markus (运行中)',
53
- tooltipStopped: 'Markus (已停止)',
32
+ tooltip: 'Markus',
54
33
  portConflictTitle: 'Markus',
55
34
  portConflictMsg: (port, occupant) => `端口 ${port} 已被 "${occupant}" 占用。\\nMarkus 无法启动。\\n\\n请释放端口或在 ~/.markus/markus.json 中修改端口`,
56
35
  },
@@ -79,7 +58,6 @@ function trayLog(msg) {
79
58
  appendFileSync(LOG_FILE, line);
80
59
  }
81
60
  catch { /* ignore */ }
82
- console.error(line.trimEnd());
83
61
  }
84
62
  // ── Helpers ───────────────────────────────────────────────────────────────────
85
63
  function loadIconBase64() {
@@ -135,135 +113,143 @@ function waitForHealth(url, intervalMs = 500, maxMs = 30000) {
135
113
  check();
136
114
  });
137
115
  }
116
+ function resolveMarkusCommand() {
117
+ const symlink = '/usr/local/bin/markus';
118
+ if (existsSync(symlink))
119
+ return { cmd: symlink, args: ['start'] };
120
+ const wrapper = resolve(APP_DIR, 'markus');
121
+ if (existsSync(wrapper))
122
+ return { cmd: wrapper, args: ['start'] };
123
+ const nodeBin = resolve(BIN_DIR, platform() === 'win32' ? 'node.exe' : 'node');
124
+ const markusMjs = resolve(BIN_DIR, 'markus.mjs');
125
+ return { cmd: nodeBin, args: [markusMjs, 'start'] };
126
+ }
138
127
  // ── Server process management ────────────────────────────────────────────────
139
128
  let serverProcess = null;
140
- let serverRunning = false;
141
- async function startServer() {
142
- if (serverRunning)
143
- return;
129
+ async function ensureServerRunning() {
144
130
  if (await isPortListening(WEB_UI_PORT)) {
145
131
  const isMarkus = await checkHealthOnce(`${WEB_UI_URL}/api/health`);
146
132
  if (isMarkus) {
147
- trayLog(`Port ${WEB_UI_PORT} is Markus — opening browser`);
148
- serverRunning = true;
149
- updateTrayMenu();
133
+ trayLog(`Server already running on port ${WEB_UI_PORT}`);
150
134
  openBrowser(WEB_UI_URL);
151
135
  return;
152
136
  }
153
- // Port occupied by something else
137
+ // Port occupied by a non-Markus process
154
138
  let occupant = 'unknown';
155
139
  try {
156
140
  occupant = execSync(`lsof -i :${WEB_UI_PORT} -sTCP:LISTEN -t 2>/dev/null | head -1 | xargs ps -p -o comm= 2>/dev/null`, { encoding: 'utf-8' }).trim() || 'unknown';
157
141
  }
158
142
  catch { /* ignore */ }
159
- trayLog(`Port ${WEB_UI_PORT} occupied by "${occupant}" — showing conflict dialog`);
143
+ trayLog(`Port ${WEB_UI_PORT} occupied by "${occupant}"`);
160
144
  if (platform() === 'darwin') {
161
145
  exec(`osascript -e 'display dialog "${t.portConflictMsg(WEB_UI_PORT, occupant)}" with title "${t.portConflictTitle}" buttons {"OK"} default button "OK" with icon stop'`, () => { });
162
146
  }
163
147
  return;
164
148
  }
149
+ // Start the server
165
150
  mkdirSync(LOG_DIR, { recursive: true });
166
151
  const { cmd, args } = resolveMarkusCommand();
167
152
  trayLog(`Starting server: ${cmd} ${args.join(' ')}`);
168
- const stdoutLog = join(LOG_DIR, 'stdout.log');
169
- const stderrLog = join(LOG_DIR, 'stderr.log');
170
- const { openSync } = await import('node:fs');
171
- const outFd = openSync(stdoutLog, 'a');
172
- const errFd = openSync(stderrLog, 'a');
153
+ const outFd = openSync(join(LOG_DIR, 'stdout.log'), 'a');
154
+ const errFd = openSync(join(LOG_DIR, 'stderr.log'), 'a');
173
155
  serverProcess = spawn(cmd, args, {
174
156
  stdio: ['ignore', outFd, errFd],
175
157
  detached: false,
176
158
  env: { ...process.env, NO_BROWSER: '1' },
177
159
  });
178
- serverRunning = true;
179
- updateTrayMenu();
180
160
  serverProcess.on('exit', (code) => {
181
- serverRunning = false;
161
+ if (code && code !== 0)
162
+ trayLog(`Server exited with code ${code}`);
182
163
  serverProcess = null;
183
- updateTrayMenu();
184
- if (code && code !== 0) {
185
- trayLog(`Server exited with code ${code} — check ${stderrLog}`);
186
- }
187
164
  });
188
165
  serverProcess.on('error', (err) => {
189
- serverRunning = false;
190
- serverProcess = null;
191
- updateTrayMenu();
192
166
  trayLog(`Failed to spawn server: ${err.message}`);
167
+ serverProcess = null;
193
168
  });
194
- waitForHealth(`${WEB_UI_URL}/api/health`).then((ok) => {
195
- if (ok && serverRunning) {
196
- trayLog('Server healthy — opening browser');
197
- openBrowser(WEB_UI_URL);
198
- }
199
- else if (!ok) {
200
- trayLog(`Server did not become healthy within 30s — check ${stderrLog}`);
201
- }
202
- });
169
+ const healthy = await waitForHealth(`${WEB_UI_URL}/api/health`);
170
+ if (healthy) {
171
+ trayLog('Server healthy — opening browser');
172
+ openBrowser(WEB_UI_URL);
173
+ }
174
+ else {
175
+ trayLog('Server did not become healthy within 30s');
176
+ }
203
177
  }
204
- function stopServer() {
205
- if (!serverProcess)
206
- return;
178
+ /** Stop all Markus server processes and prevent LaunchAgent from restarting. */
179
+ function killServer() {
207
180
  trayLog('Stopping server...');
208
- serverProcess.kill('SIGTERM');
209
- const forceTimer = setTimeout(() => {
210
- if (serverProcess && !serverProcess.killed) {
211
- serverProcess.kill('SIGKILL');
181
+ // Unload LaunchAgent first so launchd won't auto-restart the process
182
+ if (platform() === 'darwin') {
183
+ try {
184
+ const uid = execSync('id -u', { encoding: 'utf-8' }).trim();
185
+ execSync(`launchctl bootout gui/${uid}/global.markus 2>/dev/null`, { encoding: 'utf-8' });
186
+ trayLog('LaunchAgent unloaded');
212
187
  }
213
- }, 5000);
214
- serverProcess.on('exit', () => clearTimeout(forceTimer));
188
+ catch { /* not loaded or already unloaded */ }
189
+ }
190
+ // Kill the child process we spawned (if any)
191
+ if (serverProcess) {
192
+ serverProcess.kill('SIGTERM');
193
+ serverProcess = null;
194
+ }
195
+ // Also find and kill any Markus process on the port (may have been started
196
+ // externally, by LaunchAgent, or a previous tray session)
197
+ const killByPort = (signal) => {
198
+ try {
199
+ const pids = execSync(`lsof -i :${WEB_UI_PORT} -sTCP:LISTEN -t 2>/dev/null`, { encoding: 'utf-8' }).trim();
200
+ if (!pids)
201
+ return;
202
+ for (const pid of pids.split('\n')) {
203
+ const p = pid.trim();
204
+ if (p && p !== String(process.pid)) {
205
+ trayLog(`Sending ${signal} to server process ${p}`);
206
+ process.kill(Number(p), signal);
207
+ }
208
+ }
209
+ }
210
+ catch { /* no process on port */ }
211
+ };
212
+ killByPort('SIGTERM');
213
+ // Force kill after 3 seconds if still alive
214
+ setTimeout(() => killByPort('SIGKILL'), 3000);
215
215
  }
216
216
  // ── Tray setup ───────────────────────────────────────────────────────────────
217
- const SEPARATOR = { title: '<SEPARATOR>', tooltip: '', enabled: true };
218
217
  let tray = null;
219
- function buildMenu() {
220
- return {
221
- icon: loadIconBase64(),
222
- title: '',
223
- tooltip: serverRunning ? t.tooltipRunning : t.tooltipStopped,
224
- items: [
225
- { title: t.openUI, tooltip: t.openUI, enabled: serverRunning },
226
- SEPARATOR,
227
- { title: t.startServer, tooltip: t.startServer, enabled: !serverRunning },
228
- { title: t.stopServer, tooltip: t.stopServer, enabled: serverRunning },
229
- SEPARATOR,
230
- { title: t.quit, tooltip: t.quit, enabled: true },
231
- ],
232
- };
233
- }
234
- function updateTrayMenu() {
235
- if (!tray)
236
- return;
237
- tray.sendAction({ type: 'update-menu', menu: buildMenu() });
238
- }
239
218
  async function main() {
240
219
  trayLog(`Tray starting (locale=${detectLocale()}, pid=${process.pid})`);
241
- tray = new SysTray({ menu: buildMenu(), copyDir: false });
220
+ tray = new SysTray({
221
+ menu: {
222
+ icon: loadIconBase64(),
223
+ title: '',
224
+ tooltip: t.tooltip,
225
+ items: [
226
+ { title: t.openUI, tooltip: t.openUI, enabled: true },
227
+ { title: '<SEPARATOR>', tooltip: '', enabled: true },
228
+ { title: t.quit, tooltip: t.quit, enabled: true },
229
+ ],
230
+ },
231
+ copyDir: false,
232
+ });
242
233
  await tray.ready();
243
234
  tray.onClick(async (action) => {
244
235
  const title = action.item.title;
245
236
  if (title === t.openUI) {
246
237
  openBrowser(WEB_UI_URL);
247
238
  }
248
- else if (title === t.startServer) {
249
- await startServer();
250
- }
251
- else if (title === t.stopServer) {
252
- stopServer();
253
- }
254
239
  else if (title === t.quit) {
255
- stopServer();
240
+ trayLog('Quit requested');
241
+ killServer();
256
242
  setTimeout(async () => {
257
243
  if (tray)
258
244
  await tray.kill(false);
259
245
  process.exit(0);
260
- }, 1000);
246
+ }, 4000);
261
247
  }
262
248
  });
263
249
  tray.onError((err) => {
264
250
  trayLog(`Tray error: ${err.message}`);
265
251
  });
266
- await startServer();
252
+ await ensureServerRunning();
267
253
  }
268
254
  main().catch((err) => {
269
255
  trayLog(`Tray failed to start: ${err}`);
package/dist/tray.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"tray.js","sourceRoot":"","sources":["../src/tray.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tray.js","sourceRoot":"","sources":["../src/tray.ts"],"names":[],"mappings":"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"}