@phenx-inc/ctlsurf 0.3.6 → 0.3.8
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/out/headless/index.mjs +276 -56
- package/out/headless/index.mjs.map +3 -3
- package/out/main/index.js +152 -94
- package/out/preload/index.js +3 -0
- package/out/renderer/assets/{cssMode-DQW-brNd.js → cssMode-CYoo4t9f.js} +3 -3
- package/out/renderer/assets/{freemarker2-DxgOckH2.js → freemarker2--UQnPZsn.js} +1 -1
- package/out/renderer/assets/{handlebars-BX1Wpk_3.js → handlebars-DVDrmX0C.js} +1 -1
- package/out/renderer/assets/{html-t-KXioI0.js → html-D1-cXoLy.js} +1 -1
- package/out/renderer/assets/{htmlMode-Dya7iUjr.js → htmlMode-f5nBuprq.js} +3 -3
- package/out/renderer/assets/{index-D6JBcQ20.css → index-65hyKM_8.css} +16 -0
- package/out/renderer/assets/{index-DNqZidnO.js → index-D23nru43.js} +64 -23
- package/out/renderer/assets/{javascript-DZzW2adn.js → javascript-CcarFzBL.js} +2 -2
- package/out/renderer/assets/{jsonMode-D_Wv7XH8.js → jsonMode-BvF-xK9U.js} +3 -3
- package/out/renderer/assets/{liquid-BJAHAm2T.js → liquid-CHLtUKl2.js} +1 -1
- package/out/renderer/assets/{lspLanguageFeatures-BgMd-KJk.js → lspLanguageFeatures-B9aNeatS.js} +1 -1
- package/out/renderer/assets/{mdx-B6Zod3ry.js → mdx-HGDrkifZ.js} +1 -1
- package/out/renderer/assets/{python-Cgt13-KH.js → python-B_dPzjJ6.js} +1 -1
- package/out/renderer/assets/{razor-BcwFJGYS.js → razor-CHheM4ot.js} +1 -1
- package/out/renderer/assets/{tsMode-BTjzM6fl.js → tsMode-CdC3i1gG.js} +1 -1
- package/out/renderer/assets/{typescript-DZYDQEUb.js → typescript-BX6guVRK.js} +1 -1
- package/out/renderer/assets/{xml-CloiUoIW.js → xml-CpS-pOPE.js} +1 -1
- package/out/renderer/assets/{yaml-CdKdpE-z.js → yaml-Du0AjOHW.js} +1 -1
- package/out/renderer/index.html +2 -2
- package/package.json +1 -1
- package/src/main/bridge.ts +9 -3
- package/src/main/headless.ts +35 -2
- package/src/main/index.ts +10 -39
- package/src/main/orchestrator.ts +29 -1
- package/src/main/timeTracker.ts +74 -45
- package/src/main/tui.ts +20 -8
- package/src/main/updateCheck.ts +40 -0
- package/src/preload/index.ts +6 -0
- package/src/renderer/App.tsx +2 -0
- package/src/renderer/components/AgentPicker.tsx +38 -3
- package/src/renderer/styles.css +16 -0
package/out/main/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
const electron = require("electron");
|
|
3
3
|
const path = require("path");
|
|
4
4
|
const fs = require("fs");
|
|
5
|
-
const
|
|
5
|
+
const https = require("https");
|
|
6
6
|
const os = require("os");
|
|
7
7
|
const module$1 = require("module");
|
|
8
8
|
const require$$1 = require("crypto");
|
|
@@ -14,6 +14,47 @@ const require$$0$2 = require("stream");
|
|
|
14
14
|
const require$$7 = require("url");
|
|
15
15
|
const require$$0 = require("zlib");
|
|
16
16
|
const require$$0$1 = require("buffer");
|
|
17
|
+
const NPM_PACKAGE = "@phenx-inc/ctlsurf";
|
|
18
|
+
function compareSemver(a, b2) {
|
|
19
|
+
const pa = a.split(".").map((n) => parseInt(n, 10) || 0);
|
|
20
|
+
const pb = b2.split(".").map((n) => parseInt(n, 10) || 0);
|
|
21
|
+
for (let i = 0; i < 3; i++) {
|
|
22
|
+
const ai = pa[i] || 0;
|
|
23
|
+
const bi = pb[i] || 0;
|
|
24
|
+
if (ai !== bi) return ai - bi;
|
|
25
|
+
}
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
function fetchLatestNpmVersion(timeoutMs = 8e3) {
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
const url = `https://registry.npmjs.org/${encodeURIComponent(NPM_PACKAGE)}/latest`;
|
|
31
|
+
const req = https.get(url, { headers: { "Accept": "application/json" } }, (res) => {
|
|
32
|
+
if (res.statusCode !== 200) {
|
|
33
|
+
res.resume();
|
|
34
|
+
resolve(null);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
let body = "";
|
|
38
|
+
res.setEncoding("utf8");
|
|
39
|
+
res.on("data", (chunk) => {
|
|
40
|
+
body += chunk;
|
|
41
|
+
});
|
|
42
|
+
res.on("end", () => {
|
|
43
|
+
try {
|
|
44
|
+
const json = JSON.parse(body);
|
|
45
|
+
resolve(typeof json?.version === "string" ? json.version : null);
|
|
46
|
+
} catch {
|
|
47
|
+
resolve(null);
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
req.on("error", () => resolve(null));
|
|
52
|
+
req.setTimeout(timeoutMs, () => {
|
|
53
|
+
req.destroy();
|
|
54
|
+
resolve(null);
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
}
|
|
17
58
|
function getShellCommand() {
|
|
18
59
|
if (process.platform === "win32") return "powershell.exe";
|
|
19
60
|
return process.env.SHELL || "/bin/zsh";
|
|
@@ -5689,6 +5730,7 @@ var k = class extends S {
|
|
|
5689
5730
|
class ConversationBridge {
|
|
5690
5731
|
wsClient = null;
|
|
5691
5732
|
sessionActive = false;
|
|
5733
|
+
loggingEnabled = false;
|
|
5692
5734
|
inputBuffer = "";
|
|
5693
5735
|
outputBuffer = "";
|
|
5694
5736
|
outputFlushTimer = null;
|
|
@@ -5698,7 +5740,11 @@ class ConversationBridge {
|
|
|
5698
5740
|
setWsClient(ws) {
|
|
5699
5741
|
this.wsClient = ws;
|
|
5700
5742
|
}
|
|
5743
|
+
setLoggingEnabled(enabled) {
|
|
5744
|
+
this.loggingEnabled = enabled;
|
|
5745
|
+
}
|
|
5701
5746
|
startSession() {
|
|
5747
|
+
if (!this.loggingEnabled) return;
|
|
5702
5748
|
this.clearOutputTimers();
|
|
5703
5749
|
this.outputBuffer = "";
|
|
5704
5750
|
this.inputBuffer = "";
|
|
@@ -5707,13 +5753,13 @@ class ConversationBridge {
|
|
|
5707
5753
|
console.log("[bridge] Session started");
|
|
5708
5754
|
}
|
|
5709
5755
|
feedOutput(data) {
|
|
5710
|
-
if (!this.sessionActive) return;
|
|
5756
|
+
if (!this.sessionActive || !this.loggingEnabled) return;
|
|
5711
5757
|
this.outputBuffer += data;
|
|
5712
5758
|
this.terminalCapture.write(data);
|
|
5713
5759
|
this.scheduleOutputFlush();
|
|
5714
5760
|
}
|
|
5715
5761
|
feedInput(data) {
|
|
5716
|
-
if (!this.sessionActive) return;
|
|
5762
|
+
if (!this.sessionActive || !this.loggingEnabled) return;
|
|
5717
5763
|
this.inputBuffer += data;
|
|
5718
5764
|
if (data.includes("\r") || data.includes("\n")) {
|
|
5719
5765
|
const cleaned = cleanInput(this.inputBuffer);
|
|
@@ -5735,7 +5781,7 @@ class ConversationBridge {
|
|
|
5735
5781
|
this.sendEntry("terminal_output", cleaned);
|
|
5736
5782
|
}
|
|
5737
5783
|
sendEntry(type, content) {
|
|
5738
|
-
if (!this.wsClient) return;
|
|
5784
|
+
if (!this.wsClient || !this.loggingEnabled) return;
|
|
5739
5785
|
this.wsClient.sendChatLog({
|
|
5740
5786
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
5741
5787
|
type,
|
|
@@ -8431,7 +8477,7 @@ function requireWebsocket() {
|
|
|
8431
8477
|
if (hasRequiredWebsocket) return websocket;
|
|
8432
8478
|
hasRequiredWebsocket = 1;
|
|
8433
8479
|
const EventEmitter = require$$0$3;
|
|
8434
|
-
const https =
|
|
8480
|
+
const https$1 = https;
|
|
8435
8481
|
const http = require$$2;
|
|
8436
8482
|
const net = require$$3;
|
|
8437
8483
|
const tls = require$$4;
|
|
@@ -8966,7 +9012,7 @@ function requireWebsocket() {
|
|
|
8966
9012
|
}
|
|
8967
9013
|
const defaultPort = isSecure ? 443 : 80;
|
|
8968
9014
|
const key = randomBytes(16).toString("base64");
|
|
8969
|
-
const request = isSecure ? https.request : http.request;
|
|
9015
|
+
const request = isSecure ? https$1.request : http.request;
|
|
8970
9016
|
const protocolSet = /* @__PURE__ */ new Set();
|
|
8971
9017
|
let perMessageDeflate;
|
|
8972
9018
|
opts.createConnection = opts.createConnection || (isSecure ? tlsConnect : netConnect);
|
|
@@ -10160,55 +10206,68 @@ class TimeTracker {
|
|
|
10160
10206
|
if (this.sessions.has(tabId)) {
|
|
10161
10207
|
await this.endSession(tabId);
|
|
10162
10208
|
}
|
|
10209
|
+
const startedAt = Date.now();
|
|
10210
|
+
const state = {
|
|
10211
|
+
blockId: null,
|
|
10212
|
+
rowId: null,
|
|
10213
|
+
sessionUuid: require$$1.randomUUID(),
|
|
10214
|
+
cwd,
|
|
10215
|
+
agentName,
|
|
10216
|
+
idleTimeoutMin,
|
|
10217
|
+
startedAt,
|
|
10218
|
+
lastActivity: startedAt,
|
|
10219
|
+
activeMs: 0,
|
|
10220
|
+
idleTimeoutMs: Math.max(1, idleTimeoutMin) * 60 * 1e3,
|
|
10221
|
+
firstCheckpointTimer: null,
|
|
10222
|
+
checkpointTimer: null,
|
|
10223
|
+
ended: false
|
|
10224
|
+
};
|
|
10225
|
+
this.sessions.set(tabId, state);
|
|
10226
|
+
await this.tryResolve(tabId);
|
|
10227
|
+
state.firstCheckpointTimer = setTimeout(() => {
|
|
10228
|
+
void this.checkpoint(tabId);
|
|
10229
|
+
const live = this.sessions.get(tabId);
|
|
10230
|
+
if (live && !live.ended) {
|
|
10231
|
+
live.checkpointTimer = setInterval(() => {
|
|
10232
|
+
void this.checkpoint(tabId);
|
|
10233
|
+
}, CHECKPOINT_INTERVAL_MS);
|
|
10234
|
+
}
|
|
10235
|
+
}, FIRST_CHECKPOINT_DELAY_MS);
|
|
10236
|
+
const pending = !state.blockId || !state.rowId;
|
|
10237
|
+
log$2(`Started tracking tab=${tabId} agent="${agentName}" cwd=${cwd}${pending ? " (pending datastore — will retry on each checkpoint)" : ""}`);
|
|
10238
|
+
}
|
|
10239
|
+
/** Attempts to locate (or create) the datastore + add the session row.
|
|
10240
|
+
* Returns true once the session is resolved (blockId + rowId set).
|
|
10241
|
+
* Safe to call repeatedly: re-running while pending will keep retrying;
|
|
10242
|
+
* once resolved it's a no-op. */
|
|
10243
|
+
async tryResolve(tabId) {
|
|
10244
|
+
const s = this.sessions.get(tabId);
|
|
10245
|
+
if (!s) return false;
|
|
10246
|
+
if (s.blockId && s.rowId) return true;
|
|
10163
10247
|
try {
|
|
10164
|
-
const blockId = await this.ensureDatastore(cwd);
|
|
10165
|
-
if (!blockId)
|
|
10166
|
-
log$2(`No "${AGENT_DATASTORE_PAGE_TITLE}" page found for ${cwd} — tracking disabled for this session`);
|
|
10167
|
-
return;
|
|
10168
|
-
}
|
|
10169
|
-
const startedAt = Date.now();
|
|
10170
|
-
const sessionUuid = require$$1.randomUUID();
|
|
10248
|
+
const blockId = await this.ensureDatastore(s.cwd);
|
|
10249
|
+
if (!blockId) return false;
|
|
10171
10250
|
const row = await this.api.addRow(blockId, {
|
|
10172
|
-
Started: formatStarted(startedAt),
|
|
10173
|
-
"Active Time":
|
|
10174
|
-
"Last Updated": new Date(
|
|
10175
|
-
Agent: agentName,
|
|
10251
|
+
Started: formatStarted(s.startedAt),
|
|
10252
|
+
"Active Time": Math.round(s.activeMs / 6e4),
|
|
10253
|
+
"Last Updated": (/* @__PURE__ */ new Date()).toISOString(),
|
|
10254
|
+
Agent: s.agentName,
|
|
10176
10255
|
Worker: os.hostname(),
|
|
10177
|
-
Session: sessionUuid,
|
|
10256
|
+
Session: s.sessionUuid,
|
|
10178
10257
|
Notes: ""
|
|
10179
10258
|
});
|
|
10180
10259
|
const rowId = row?.id;
|
|
10181
10260
|
if (!rowId) {
|
|
10182
|
-
log$2(
|
|
10183
|
-
return;
|
|
10261
|
+
log$2(`addRow returned no id for tab=${tabId}; will retry on next checkpoint`);
|
|
10262
|
+
return false;
|
|
10184
10263
|
}
|
|
10185
|
-
|
|
10186
|
-
|
|
10187
|
-
|
|
10188
|
-
|
|
10189
|
-
agentName,
|
|
10190
|
-
idleTimeoutMin,
|
|
10191
|
-
startedAt,
|
|
10192
|
-
lastActivity: startedAt,
|
|
10193
|
-
activeMs: 0,
|
|
10194
|
-
idleTimeoutMs: Math.max(1, idleTimeoutMin) * 60 * 1e3,
|
|
10195
|
-
firstCheckpointTimer: null,
|
|
10196
|
-
checkpointTimer: null,
|
|
10197
|
-
ended: false
|
|
10198
|
-
};
|
|
10199
|
-
state.firstCheckpointTimer = setTimeout(() => {
|
|
10200
|
-
void this.checkpoint(tabId);
|
|
10201
|
-
const live = this.sessions.get(tabId);
|
|
10202
|
-
if (live && !live.ended) {
|
|
10203
|
-
live.checkpointTimer = setInterval(() => {
|
|
10204
|
-
void this.checkpoint(tabId);
|
|
10205
|
-
}, CHECKPOINT_INTERVAL_MS);
|
|
10206
|
-
}
|
|
10207
|
-
}, FIRST_CHECKPOINT_DELAY_MS);
|
|
10208
|
-
this.sessions.set(tabId, state);
|
|
10209
|
-
log$2(`Started tracking tab=${tabId} agent="${agentName}" cwd=${cwd}`);
|
|
10264
|
+
s.blockId = blockId;
|
|
10265
|
+
s.rowId = rowId;
|
|
10266
|
+
log$2(`Resolved datastore for tab=${tabId} (cwd=${s.cwd})`);
|
|
10267
|
+
return true;
|
|
10210
10268
|
} catch (err) {
|
|
10211
|
-
log$2(`
|
|
10269
|
+
log$2(`tryResolve failed for tab=${tabId}: ${err?.message || err}`);
|
|
10270
|
+
return false;
|
|
10212
10271
|
}
|
|
10213
10272
|
}
|
|
10214
10273
|
isTracking(tabId) {
|
|
@@ -10248,14 +10307,21 @@ class TimeTracker {
|
|
|
10248
10307
|
async endSession(tabId) {
|
|
10249
10308
|
const s = this.sessions.get(tabId);
|
|
10250
10309
|
if (!s || s.ended) return;
|
|
10251
|
-
s.ended = true;
|
|
10252
10310
|
if (s.firstCheckpointTimer) clearTimeout(s.firstCheckpointTimer);
|
|
10253
10311
|
if (s.checkpointTimer) clearInterval(s.checkpointTimer);
|
|
10254
10312
|
try {
|
|
10255
|
-
|
|
10313
|
+
if (!s.blockId || !s.rowId) {
|
|
10314
|
+
await this.tryResolve(tabId);
|
|
10315
|
+
}
|
|
10316
|
+
if (s.blockId && s.rowId) {
|
|
10317
|
+
await this.writeRow(s, Date.now());
|
|
10318
|
+
} else {
|
|
10319
|
+
log$2(`endSession for tab=${tabId}: never resolved datastore; ${Math.round(s.activeMs / 6e4)}min not recorded`);
|
|
10320
|
+
}
|
|
10256
10321
|
} catch (err) {
|
|
10257
10322
|
log$2(`endSession write failed: ${err?.message || err}`);
|
|
10258
10323
|
}
|
|
10324
|
+
s.ended = true;
|
|
10259
10325
|
this.sessions.delete(tabId);
|
|
10260
10326
|
}
|
|
10261
10327
|
async endAll() {
|
|
@@ -10265,13 +10331,16 @@ class TimeTracker {
|
|
|
10265
10331
|
async checkpoint(tabId) {
|
|
10266
10332
|
const s = this.sessions.get(tabId);
|
|
10267
10333
|
if (!s || s.ended) return;
|
|
10334
|
+
if (!s.blockId || !s.rowId) {
|
|
10335
|
+
if (!await this.tryResolve(tabId)) return;
|
|
10336
|
+
}
|
|
10268
10337
|
try {
|
|
10269
10338
|
await this.writeRow(s, Date.now());
|
|
10270
10339
|
} catch (err) {
|
|
10271
10340
|
log$2(`checkpoint failed: ${err?.message || err}; retrying in 2s`);
|
|
10272
10341
|
setTimeout(() => {
|
|
10273
10342
|
const live = this.sessions.get(tabId);
|
|
10274
|
-
if (!live || live.ended) return;
|
|
10343
|
+
if (!live || live.ended || !live.blockId || !live.rowId) return;
|
|
10275
10344
|
this.writeRow(live, Date.now()).catch((err2) => {
|
|
10276
10345
|
log$2(`checkpoint retry failed: ${err2?.message || err2}`);
|
|
10277
10346
|
});
|
|
@@ -10279,6 +10348,7 @@ class TimeTracker {
|
|
|
10279
10348
|
}
|
|
10280
10349
|
}
|
|
10281
10350
|
async writeRow(s, _endTimeMs) {
|
|
10351
|
+
if (!s.blockId || !s.rowId) return;
|
|
10282
10352
|
const activeMin = Math.round(s.activeMs / 6e4);
|
|
10283
10353
|
await this.api.updateRow(s.blockId, s.rowId, {
|
|
10284
10354
|
"Active Time": activeMin,
|
|
@@ -10410,7 +10480,8 @@ class Orchestrator {
|
|
|
10410
10480
|
currentCwd = null;
|
|
10411
10481
|
settings = {
|
|
10412
10482
|
activeProfile: "production",
|
|
10413
|
-
profiles: { ...DEFAULT_PROFILES }
|
|
10483
|
+
profiles: { ...DEFAULT_PROFILES },
|
|
10484
|
+
logChat: false
|
|
10414
10485
|
};
|
|
10415
10486
|
constructor(settingsDir, events) {
|
|
10416
10487
|
this.settingsDir = settingsDir;
|
|
@@ -10445,6 +10516,21 @@ class Orchestrator {
|
|
|
10445
10516
|
}
|
|
10446
10517
|
});
|
|
10447
10518
|
this.bridge.setWsClient(this.workerWs);
|
|
10519
|
+
this.bridge.setLoggingEnabled(!!this.settings.logChat);
|
|
10520
|
+
}
|
|
10521
|
+
// ─── Chat logging ───────────────────────────────
|
|
10522
|
+
get logChatEnabled() {
|
|
10523
|
+
return !!this.settings.logChat;
|
|
10524
|
+
}
|
|
10525
|
+
setLogChat(enabled) {
|
|
10526
|
+
this.settings.logChat = enabled;
|
|
10527
|
+
this.saveSettings();
|
|
10528
|
+
this.bridge.setLoggingEnabled(enabled);
|
|
10529
|
+
if (!enabled) {
|
|
10530
|
+
this.bridge.endSession();
|
|
10531
|
+
} else if (this.activeTabId) {
|
|
10532
|
+
this.bridge.startSession();
|
|
10533
|
+
}
|
|
10448
10534
|
}
|
|
10449
10535
|
// ─── Settings ───────────────────────────────────
|
|
10450
10536
|
getActiveProfile() {
|
|
@@ -10492,7 +10578,8 @@ class Orchestrator {
|
|
|
10492
10578
|
baseUrl: raw.ctlsurfBaseUrl || "https://app.ctlsurf.com",
|
|
10493
10579
|
dataspacePageId: raw.ctlsurfDataspacePageId || ""
|
|
10494
10580
|
}
|
|
10495
|
-
}
|
|
10581
|
+
},
|
|
10582
|
+
logChat: !!raw.logChat
|
|
10496
10583
|
};
|
|
10497
10584
|
this.saveSettings();
|
|
10498
10585
|
log$1("[settings] Migrated legacy settings to profiles");
|
|
@@ -10501,15 +10588,20 @@ class Orchestrator {
|
|
|
10501
10588
|
if (!this.settings.profiles.production) {
|
|
10502
10589
|
this.settings.profiles.production = { ...DEFAULT_PROFILES.production };
|
|
10503
10590
|
}
|
|
10591
|
+
if (this.settings.logChat === void 0) {
|
|
10592
|
+
this.settings.logChat = false;
|
|
10593
|
+
}
|
|
10504
10594
|
}
|
|
10505
10595
|
}
|
|
10506
10596
|
} catch {
|
|
10507
10597
|
this.settings = {
|
|
10508
10598
|
activeProfile: "production",
|
|
10509
|
-
profiles: { ...DEFAULT_PROFILES }
|
|
10599
|
+
profiles: { ...DEFAULT_PROFILES },
|
|
10600
|
+
logChat: false
|
|
10510
10601
|
};
|
|
10511
10602
|
}
|
|
10512
10603
|
this.applyProfile(this.getActiveProfile());
|
|
10604
|
+
this.bridge.setLoggingEnabled(!!this.settings.logChat);
|
|
10513
10605
|
}
|
|
10514
10606
|
saveSettings() {
|
|
10515
10607
|
const settingsPath = path.join(this.settingsDir, "settings.json");
|
|
@@ -10639,7 +10731,9 @@ class Orchestrator {
|
|
|
10639
10731
|
const t = this.tabs.get(tabId);
|
|
10640
10732
|
if (t?.termStreamTimer) clearTimeout(t.termStreamTimer);
|
|
10641
10733
|
});
|
|
10642
|
-
this.
|
|
10734
|
+
if (this.settings.logChat) {
|
|
10735
|
+
this.bridge.startSession();
|
|
10736
|
+
}
|
|
10643
10737
|
const profile = this.getActiveProfile();
|
|
10644
10738
|
const shouldTrack = opts?.trackTime !== void 0 ? opts.trackTime : profile.trackTime !== false;
|
|
10645
10739
|
if (shouldTrack) {
|
|
@@ -10904,7 +10998,6 @@ electron.ipcMain.handle("app:browseCwd", async () => {
|
|
|
10904
10998
|
if (result.canceled || !result.filePaths[0]) return null;
|
|
10905
10999
|
return result.filePaths[0];
|
|
10906
11000
|
});
|
|
10907
|
-
const NPM_PACKAGE = "@phenx-inc/ctlsurf";
|
|
10908
11001
|
const UPDATE_CHECK_INTERVAL_MS = 6 * 60 * 60 * 1e3;
|
|
10909
11002
|
let updateInfo = {
|
|
10910
11003
|
current: electron.app.getVersion(),
|
|
@@ -10912,46 +11005,6 @@ let updateInfo = {
|
|
|
10912
11005
|
hasUpdate: false,
|
|
10913
11006
|
checkedAt: null
|
|
10914
11007
|
};
|
|
10915
|
-
function compareSemver(a, b2) {
|
|
10916
|
-
const pa = a.split(".").map((n) => parseInt(n, 10) || 0);
|
|
10917
|
-
const pb = b2.split(".").map((n) => parseInt(n, 10) || 0);
|
|
10918
|
-
for (let i = 0; i < 3; i++) {
|
|
10919
|
-
const ai = pa[i] || 0;
|
|
10920
|
-
const bi = pb[i] || 0;
|
|
10921
|
-
if (ai !== bi) return ai - bi;
|
|
10922
|
-
}
|
|
10923
|
-
return 0;
|
|
10924
|
-
}
|
|
10925
|
-
function fetchLatestNpmVersion() {
|
|
10926
|
-
return new Promise((resolve) => {
|
|
10927
|
-
const url = `https://registry.npmjs.org/${encodeURIComponent(NPM_PACKAGE)}/latest`;
|
|
10928
|
-
const req = require$$1$1.get(url, { headers: { "Accept": "application/json" } }, (res) => {
|
|
10929
|
-
if (res.statusCode !== 200) {
|
|
10930
|
-
res.resume();
|
|
10931
|
-
resolve(null);
|
|
10932
|
-
return;
|
|
10933
|
-
}
|
|
10934
|
-
let body = "";
|
|
10935
|
-
res.setEncoding("utf8");
|
|
10936
|
-
res.on("data", (chunk) => {
|
|
10937
|
-
body += chunk;
|
|
10938
|
-
});
|
|
10939
|
-
res.on("end", () => {
|
|
10940
|
-
try {
|
|
10941
|
-
const json = JSON.parse(body);
|
|
10942
|
-
resolve(typeof json?.version === "string" ? json.version : null);
|
|
10943
|
-
} catch {
|
|
10944
|
-
resolve(null);
|
|
10945
|
-
}
|
|
10946
|
-
});
|
|
10947
|
-
});
|
|
10948
|
-
req.on("error", () => resolve(null));
|
|
10949
|
-
req.setTimeout(8e3, () => {
|
|
10950
|
-
req.destroy();
|
|
10951
|
-
resolve(null);
|
|
10952
|
-
});
|
|
10953
|
-
});
|
|
10954
|
-
}
|
|
10955
11008
|
async function checkForUpdate() {
|
|
10956
11009
|
const latest = await fetchLatestNpmVersion();
|
|
10957
11010
|
updateInfo = {
|
|
@@ -11077,6 +11130,11 @@ electron.ipcMain.handle("profiles:save", (_event, id, data) => {
|
|
|
11077
11130
|
});
|
|
11078
11131
|
electron.ipcMain.handle("profiles:switch", (_event, id) => orchestrator.switchProfile(id));
|
|
11079
11132
|
electron.ipcMain.handle("profiles:delete", (_event, id) => orchestrator.deleteProfile(id));
|
|
11133
|
+
electron.ipcMain.handle("logchat:get", () => ({ enabled: orchestrator.logChatEnabled }));
|
|
11134
|
+
electron.ipcMain.handle("logchat:set", (_event, enabled) => {
|
|
11135
|
+
orchestrator.setLogChat(!!enabled);
|
|
11136
|
+
return { enabled: orchestrator.logChatEnabled };
|
|
11137
|
+
});
|
|
11080
11138
|
electron.ipcMain.handle("tracking:get", () => ({ active: orchestrator.isActiveTabTracking() }));
|
|
11081
11139
|
electron.ipcMain.handle("tracking:set", async (_event, enabled) => {
|
|
11082
11140
|
await orchestrator.setActiveTabTracking(enabled);
|
package/out/preload/index.js
CHANGED
|
@@ -45,6 +45,9 @@ const api = {
|
|
|
45
45
|
// Tracking (active tab)
|
|
46
46
|
getTracking: () => electron.ipcRenderer.invoke("tracking:get"),
|
|
47
47
|
setTracking: (enabled) => electron.ipcRenderer.invoke("tracking:set", enabled),
|
|
48
|
+
// Chat logging (global)
|
|
49
|
+
getLogChat: () => electron.ipcRenderer.invoke("logchat:get"),
|
|
50
|
+
setLogChat: (enabled) => electron.ipcRenderer.invoke("logchat:set", enabled),
|
|
48
51
|
// Filesystem
|
|
49
52
|
readDir: (dirPath) => electron.ipcRenderer.invoke("fs:readDir", dirPath),
|
|
50
53
|
readFile: (filePath) => electron.ipcRenderer.invoke("fs:readFile", filePath),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as createWebWorker, l as languages } from "./index-
|
|
2
|
-
import { C as CompletionAdapter, H as HoverAdapter, D as DocumentHighlightAdapter, a as DefinitionAdapter, R as ReferenceAdapter, b as DocumentSymbolAdapter, c as RenameAdapter, d as DocumentColorAdapter, F as FoldingRangeAdapter, e as DiagnosticsAdapter, S as SelectionRangeAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider } from "./lspLanguageFeatures-
|
|
3
|
-
import { h, i, j, t, k } from "./lspLanguageFeatures-
|
|
1
|
+
import { c as createWebWorker, l as languages } from "./index-D23nru43.js";
|
|
2
|
+
import { C as CompletionAdapter, H as HoverAdapter, D as DocumentHighlightAdapter, a as DefinitionAdapter, R as ReferenceAdapter, b as DocumentSymbolAdapter, c as RenameAdapter, d as DocumentColorAdapter, F as FoldingRangeAdapter, e as DiagnosticsAdapter, S as SelectionRangeAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider } from "./lspLanguageFeatures-B9aNeatS.js";
|
|
3
|
+
import { h, i, j, t, k } from "./lspLanguageFeatures-B9aNeatS.js";
|
|
4
4
|
const STOP_WHEN_IDLE_FOR = 2 * 60 * 1e3;
|
|
5
5
|
class WorkerManager {
|
|
6
6
|
constructor(defaults) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { c as createWebWorker, l as languages } from "./index-
|
|
2
|
-
import { H as HoverAdapter, D as DocumentHighlightAdapter, h as DocumentLinkAdapter, F as FoldingRangeAdapter, b as DocumentSymbolAdapter, S as SelectionRangeAdapter, c as RenameAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider, C as CompletionAdapter } from "./lspLanguageFeatures-
|
|
3
|
-
import { a, e, d, R, i, j, t, k } from "./lspLanguageFeatures-
|
|
1
|
+
import { c as createWebWorker, l as languages } from "./index-D23nru43.js";
|
|
2
|
+
import { H as HoverAdapter, D as DocumentHighlightAdapter, h as DocumentLinkAdapter, F as FoldingRangeAdapter, b as DocumentSymbolAdapter, S as SelectionRangeAdapter, c as RenameAdapter, f as DocumentFormattingEditProvider, g as DocumentRangeFormattingEditProvider, C as CompletionAdapter } from "./lspLanguageFeatures-B9aNeatS.js";
|
|
3
|
+
import { a, e, d, R, i, j, t, k } from "./lspLanguageFeatures-B9aNeatS.js";
|
|
4
4
|
const STOP_WHEN_IDLE_FOR = 2 * 60 * 1e3;
|
|
5
5
|
class WorkerManager {
|
|
6
6
|
constructor(defaults) {
|
|
@@ -8207,6 +8207,22 @@ html, body, #root {
|
|
|
8207
8207
|
color: #414868;
|
|
8208
8208
|
}
|
|
8209
8209
|
|
|
8210
|
+
.agent-picker-option {
|
|
8211
|
+
margin-top: 16px;
|
|
8212
|
+
display: flex;
|
|
8213
|
+
align-items: center;
|
|
8214
|
+
gap: 8px;
|
|
8215
|
+
font-size: 12px;
|
|
8216
|
+
color: #a9b1d6;
|
|
8217
|
+
cursor: pointer;
|
|
8218
|
+
user-select: none;
|
|
8219
|
+
}
|
|
8220
|
+
|
|
8221
|
+
.agent-picker-option input[type="checkbox"] {
|
|
8222
|
+
cursor: pointer;
|
|
8223
|
+
accent-color: #7aa2f7;
|
|
8224
|
+
}
|
|
8225
|
+
|
|
8210
8226
|
/* Settings dialog */
|
|
8211
8227
|
.settings-overlay {
|
|
8212
8228
|
position: fixed;
|