finch-ego-lite 0.1.4 → 0.2.0
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/README.md +6 -6
- package/dist/index.js +160 -45
- package/i18n/en-US.json +6 -5
- package/i18n/zh-CN.json +6 -5
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -33,12 +33,12 @@ Task spaces are isolated from your everyday browser windows while still being ab
|
|
|
33
33
|
|
|
34
34
|
## Get started
|
|
35
35
|
|
|
36
|
-
1. Install and launch [Ego Lite](https://lite.ego.app/) on macOS. Ego Lite is a browser designed for collaboration between people and AI Agents, and provides the web environment used by this mini tool.
|
|
37
|
-
2.
|
|
36
|
+
1. Install and launch [Ego Lite](https://lite.ego.app/) on macOS or Windows. Ego Lite is a browser designed for collaboration between people and AI Agents, and provides the web environment used by this mini tool.
|
|
37
|
+
2. Finish Ego Lite's first-time setup so it registers the `ego-browser` command, then enable this mini tool in Finch. If Finch was already running while you installed Ego Lite, restart Finch so it picks up the new command.
|
|
38
38
|
3. Tell Finch which website to visit and what you want done.
|
|
39
39
|
4. Use the Ego button beside the Composer to follow progress, open pages, or take control.
|
|
40
40
|
|
|
41
|
-
> Ego Lite currently
|
|
41
|
+
> Ego Lite currently runs on macOS and Windows. On other platforms, this mini tool explains that the platform is not supported and provides a link to the Ego Lite website.
|
|
42
42
|
|
|
43
43
|
## About Finch
|
|
44
44
|
|
|
@@ -83,12 +83,12 @@ Finch 会在 Ego Lite 的独立任务空间中打开网页。你不需要学习
|
|
|
83
83
|
|
|
84
84
|
## 开始使用
|
|
85
85
|
|
|
86
|
-
1. 在 macOS 上安装并启动 [Ego Lite](https://lite.ego.app/)。Ego Lite 是专为人与 AI Agent 协作设计的浏览器,也是本小工具连接网页的运行环境。
|
|
87
|
-
2.
|
|
86
|
+
1. 在 macOS 或 Windows 上安装并启动 [Ego Lite](https://lite.ego.app/)。Ego Lite 是专为人与 AI Agent 协作设计的浏览器,也是本小工具连接网页的运行环境。
|
|
87
|
+
2. 完成 Ego Lite 的首次引导,让它注册 `ego-browser` 命令,然后在 Finch 中启用本小工具。如果安装 Ego Lite 时 Finch 已经开着,重启一次 Finch 才能读到新命令。
|
|
88
88
|
3. 直接告诉 Finch 想访问的网站和要完成的事情。
|
|
89
89
|
4. 通过输入框旁的 Ego 按钮查看进度、打开页面或接管操作。
|
|
90
90
|
|
|
91
|
-
> Ego Lite
|
|
91
|
+
> Ego Lite 目前可在 macOS 和 Windows 上运行。其他平台上,本小工具会提示平台暂不支持,并提供 Ego Lite 官网入口。
|
|
92
92
|
|
|
93
93
|
## 关于 Finch
|
|
94
94
|
|
package/dist/index.js
CHANGED
|
@@ -2,21 +2,59 @@
|
|
|
2
2
|
import { execFile } from "node:child_process";
|
|
3
3
|
import { existsSync, readFileSync } from "node:fs";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
|
-
import { join } from "node:path";
|
|
5
|
+
import { delimiter, join } from "node:path";
|
|
6
6
|
import { promisify } from "node:util";
|
|
7
7
|
var execFileAsync = promisify(execFile);
|
|
8
8
|
var WEBSITE = "https://lite.ego.app/";
|
|
9
9
|
var STATUS_MARKER = "__EGO_STATUS__";
|
|
10
|
+
var OFFLINE_CONFIRMATIONS = 2;
|
|
10
11
|
var commandQueue = Promise.resolve();
|
|
12
|
+
var SUPPORTED_PLATFORMS = /* @__PURE__ */ new Set(["darwin", "win32"]);
|
|
13
|
+
function isSupportedPlatform() {
|
|
14
|
+
return SUPPORTED_PLATFORMS.has(process.platform);
|
|
15
|
+
}
|
|
16
|
+
function localBinDir() {
|
|
17
|
+
return join(homedir(), ".local", "bin");
|
|
18
|
+
}
|
|
11
19
|
function egoBinary() {
|
|
12
|
-
const
|
|
13
|
-
|
|
20
|
+
const names = process.platform === "win32" ? ["ego-browser.exe", "ego-browser"] : ["ego-browser"];
|
|
21
|
+
for (const name of names) {
|
|
22
|
+
const local = join(localBinDir(), name);
|
|
23
|
+
if (existsSync(local)) return local;
|
|
24
|
+
}
|
|
14
25
|
return "ego-browser";
|
|
15
26
|
}
|
|
27
|
+
function egoAppPath() {
|
|
28
|
+
if (process.platform !== "win32") return void 0;
|
|
29
|
+
const env = process.env;
|
|
30
|
+
const roots = [
|
|
31
|
+
env.ProgramFiles,
|
|
32
|
+
env["ProgramFiles(x86)"],
|
|
33
|
+
env.LOCALAPPDATA ? join(env.LOCALAPPDATA, "Programs") : void 0,
|
|
34
|
+
env.LOCALAPPDATA
|
|
35
|
+
].filter((root) => Boolean(root));
|
|
36
|
+
const layouts = [
|
|
37
|
+
["Citro Labs", "ego lite", "Application", "ego.exe"],
|
|
38
|
+
["ego lite", "Application", "ego.exe"],
|
|
39
|
+
["Citro Labs", "ego lite", "ego.exe"],
|
|
40
|
+
["ego lite", "ego.exe"]
|
|
41
|
+
];
|
|
42
|
+
for (const root of roots) {
|
|
43
|
+
for (const layout of layouts) {
|
|
44
|
+
const candidate = join(root, ...layout);
|
|
45
|
+
if (existsSync(candidate)) return candidate;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return void 0;
|
|
49
|
+
}
|
|
16
50
|
async function processRunning() {
|
|
17
|
-
if (
|
|
51
|
+
if (!isSupportedPlatform()) return false;
|
|
18
52
|
const probe = async () => {
|
|
19
53
|
try {
|
|
54
|
+
if (process.platform === "win32") {
|
|
55
|
+
const { stdout } = await execFileAsync("tasklist", ["/FI", "IMAGENAME eq ego.exe", "/NH"], { timeout: 3e3 });
|
|
56
|
+
return /\bego\.exe\b/i.test(stdout);
|
|
57
|
+
}
|
|
20
58
|
await execFileAsync("pgrep", ["-f", "/ego lite.app/Contents/MacOS/ego lite"], { timeout: 2e3 });
|
|
21
59
|
return true;
|
|
22
60
|
} catch {
|
|
@@ -33,7 +71,7 @@ async function runCommand(file, args, timeout = 2e4) {
|
|
|
33
71
|
const child = execFile(file, args, {
|
|
34
72
|
timeout,
|
|
35
73
|
maxBuffer: 10 * 1024 * 1024,
|
|
36
|
-
env: { ...process.env, PATH: `${
|
|
74
|
+
env: { ...process.env, PATH: `${localBinDir()}${delimiter}${process.env.PATH ?? ""}` }
|
|
37
75
|
}, (error, stdout, stderr) => {
|
|
38
76
|
const output = [stdout, stderr].filter(Boolean).join("\n").trim();
|
|
39
77
|
if (error) {
|
|
@@ -56,6 +94,26 @@ async function installedVersion(binary) {
|
|
|
56
94
|
return void 0;
|
|
57
95
|
}
|
|
58
96
|
}
|
|
97
|
+
var VERSION_TTL = 5 * 6e4;
|
|
98
|
+
var cachedVersion;
|
|
99
|
+
async function probeVersion(binary) {
|
|
100
|
+
if (cachedVersion && Date.now() - cachedVersion.at < VERSION_TTL) return cachedVersion.value;
|
|
101
|
+
const value = await installedVersion(binary);
|
|
102
|
+
if (value) cachedVersion = { value, at: Date.now() };
|
|
103
|
+
return value;
|
|
104
|
+
}
|
|
105
|
+
async function probeInstall(binary, running) {
|
|
106
|
+
const version = running && cachedVersion?.value || await probeVersion(binary);
|
|
107
|
+
return { installed: running || Boolean(version), version };
|
|
108
|
+
}
|
|
109
|
+
async function waitForRunning(deadlineMs = 12e3) {
|
|
110
|
+
const until = Date.now() + deadlineMs;
|
|
111
|
+
for (; ; ) {
|
|
112
|
+
if (await processRunning()) return true;
|
|
113
|
+
if (Date.now() >= until) return false;
|
|
114
|
+
await new Promise((resolve) => setTimeout(resolve, 400));
|
|
115
|
+
}
|
|
116
|
+
}
|
|
59
117
|
function statusScript(detailed) {
|
|
60
118
|
return `
|
|
61
119
|
const spaces = await listTaskSpaces();
|
|
@@ -94,15 +152,14 @@ function parseSpaces(output) {
|
|
|
94
152
|
return JSON.parse(json);
|
|
95
153
|
}
|
|
96
154
|
async function getStatus(detailed = false) {
|
|
97
|
-
if (
|
|
155
|
+
if (!isSupportedPlatform()) {
|
|
98
156
|
return { supported: false, installed: false, running: false, spaces: [], pageCount: 0 };
|
|
99
157
|
}
|
|
100
158
|
const binary = egoBinary();
|
|
101
|
-
if (!binary) return { supported: true, installed: false, running: false, spaces: [], pageCount: 0 };
|
|
102
|
-
const version = await installedVersion(binary);
|
|
103
|
-
if (!version) return { supported: true, installed: false, running: false, spaces: [], pageCount: 0 };
|
|
104
159
|
const running = await processRunning();
|
|
105
|
-
|
|
160
|
+
const { installed, version } = await probeInstall(binary, running);
|
|
161
|
+
const base = { supported: true, installed, running, version, spaces: [], pageCount: 0 };
|
|
162
|
+
if (!running || !version) return base;
|
|
106
163
|
try {
|
|
107
164
|
const output = await runCommand(binary, ["nodejs", "-e", statusScript(detailed)], 1e4);
|
|
108
165
|
const spaces = parseSpaces(output);
|
|
@@ -110,27 +167,57 @@ async function getStatus(detailed = false) {
|
|
|
110
167
|
if (space.tabs) return sum + space.tabs.length;
|
|
111
168
|
return sum + (space.recentTabTitles?.length ?? 0);
|
|
112
169
|
}, 0);
|
|
113
|
-
return {
|
|
170
|
+
return { ...base, spaces, pageCount };
|
|
114
171
|
} catch (error) {
|
|
115
172
|
return {
|
|
116
|
-
|
|
117
|
-
installed: true,
|
|
118
|
-
running: true,
|
|
119
|
-
version,
|
|
120
|
-
spaces: [],
|
|
121
|
-
pageCount: 0,
|
|
173
|
+
...base,
|
|
122
174
|
error: error instanceof Error ? error.message : String(error)
|
|
123
175
|
};
|
|
124
176
|
}
|
|
125
177
|
}
|
|
178
|
+
async function probeStatus(previous) {
|
|
179
|
+
if (!isSupportedPlatform()) {
|
|
180
|
+
return { supported: false, installed: false, running: false, spaces: [], pageCount: 0 };
|
|
181
|
+
}
|
|
182
|
+
const running = await processRunning();
|
|
183
|
+
const { installed, version } = await probeInstall(egoBinary(), running);
|
|
184
|
+
return {
|
|
185
|
+
supported: true,
|
|
186
|
+
installed,
|
|
187
|
+
running,
|
|
188
|
+
version: version ?? previous?.version,
|
|
189
|
+
// A cached space list is meaningless once the process is gone.
|
|
190
|
+
spaces: running ? previous?.spaces ?? [] : [],
|
|
191
|
+
pageCount: running ? previous?.pageCount ?? 0 : 0
|
|
192
|
+
};
|
|
193
|
+
}
|
|
126
194
|
async function launchEgo() {
|
|
127
|
-
if (process.platform
|
|
128
|
-
|
|
195
|
+
if (process.platform === "darwin") {
|
|
196
|
+
await execFileAsync("open", ["-a", "ego lite"], { timeout: 5e3 });
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
if (process.platform === "win32") {
|
|
200
|
+
const exe = egoAppPath();
|
|
201
|
+
if (!exe) {
|
|
202
|
+
throw new Error(`The ego lite app was not found on this PC. Open it from the Start menu, or reinstall it from ${WEBSITE}.`);
|
|
203
|
+
}
|
|
204
|
+
await execFileAsync("cmd", ["/c", "start", "", exe], { timeout: 5e3 });
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
throw new Error(`Ego Lite does not run on this platform (${process.platform}).`);
|
|
129
208
|
}
|
|
130
209
|
async function focusEgo() {
|
|
131
|
-
if (process.platform
|
|
132
|
-
|
|
133
|
-
|
|
210
|
+
if (process.platform === "darwin") {
|
|
211
|
+
await execFileAsync("open", ["-a", "ego lite"], { timeout: 5e3 }).catch(() => {
|
|
212
|
+
});
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (process.platform === "win32") {
|
|
216
|
+
const exe = egoAppPath();
|
|
217
|
+
if (!exe) return;
|
|
218
|
+
await execFileAsync("cmd", ["/c", "start", "", exe], { timeout: 5e3 }).catch(() => {
|
|
219
|
+
});
|
|
220
|
+
}
|
|
134
221
|
}
|
|
135
222
|
async function openWebsite() {
|
|
136
223
|
const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "cmd" : "xdg-open";
|
|
@@ -299,19 +386,45 @@ function activate(ctx) {
|
|
|
299
386
|
}
|
|
300
387
|
}));
|
|
301
388
|
let cachedStatus;
|
|
302
|
-
let
|
|
389
|
+
let lastDetailAt = 0;
|
|
390
|
+
let offlineMisses = 0;
|
|
391
|
+
let recheckTimer;
|
|
303
392
|
let refreshInFlight;
|
|
304
393
|
let pendingDetailedRefresh = false;
|
|
394
|
+
const isOnline = (status) => status?.installed === true && status.running === true;
|
|
395
|
+
const publishStatus = (next, detailed) => {
|
|
396
|
+
if (isOnline(cachedStatus) && !isOnline(next) && offlineMisses + 1 < OFFLINE_CONFIRMATIONS) {
|
|
397
|
+
offlineMisses += 1;
|
|
398
|
+
if (!recheckTimer) {
|
|
399
|
+
recheckTimer = setTimeout(() => {
|
|
400
|
+
recheckTimer = void 0;
|
|
401
|
+
void refreshStatus(false);
|
|
402
|
+
}, 600);
|
|
403
|
+
}
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
const previousOnline = isOnline(cachedStatus);
|
|
407
|
+
const same = JSON.stringify(cachedStatus ?? null) === JSON.stringify(next);
|
|
408
|
+
offlineMisses = 0;
|
|
409
|
+
cachedStatus = next;
|
|
410
|
+
if (detailed) lastDetailAt = Date.now();
|
|
411
|
+
if (previousOnline !== isOnline(next)) {
|
|
412
|
+
ctx.logger.info("Ego online state changed", {
|
|
413
|
+
online: isOnline(next),
|
|
414
|
+
running: next.running,
|
|
415
|
+
installed: next.installed,
|
|
416
|
+
version: next.version,
|
|
417
|
+
error: next.error
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
if (!same) action.notifyUpdate();
|
|
421
|
+
};
|
|
305
422
|
const refreshStatus = (detailed = false) => {
|
|
306
423
|
if (refreshInFlight) {
|
|
307
424
|
if (detailed) pendingDetailedRefresh = true;
|
|
308
425
|
return refreshInFlight;
|
|
309
426
|
}
|
|
310
|
-
refreshInFlight = getStatus(
|
|
311
|
-
cachedStatus = status;
|
|
312
|
-
lastRefreshAt = Date.now();
|
|
313
|
-
action.notifyUpdate();
|
|
314
|
-
}).catch((error) => ctx.logger.warn("Ego background status refresh failed", error)).finally(() => {
|
|
427
|
+
refreshInFlight = (detailed ? getStatus(true) : probeStatus(cachedStatus)).then((status) => publishStatus(status, detailed)).catch((error) => ctx.logger.warn("Ego background status refresh failed", error)).finally(() => {
|
|
315
428
|
refreshInFlight = void 0;
|
|
316
429
|
if (pendingDetailedRefresh) {
|
|
317
430
|
pendingDetailedRefresh = false;
|
|
@@ -322,12 +435,11 @@ function activate(ctx) {
|
|
|
322
435
|
};
|
|
323
436
|
const action = ctx.composerActions.register("ego-browser", {
|
|
324
437
|
async getBadge() {
|
|
325
|
-
const online = cachedStatus?.installed === true && cachedStatus.running === true && !cachedStatus.error;
|
|
326
438
|
if (cachedStatus?.supported === false) return { text: t("badge.unsupported"), active: false };
|
|
327
|
-
return
|
|
439
|
+
return isOnline(cachedStatus) ? { text: t("badge.online"), active: true } : { text: t("badge.offline"), active: false };
|
|
328
440
|
},
|
|
329
441
|
async getMenu() {
|
|
330
|
-
if (cachedStatus === void 0 || Date.now() -
|
|
442
|
+
if (cachedStatus === void 0 || Date.now() - lastDetailAt > 3e3) {
|
|
331
443
|
await refreshStatus(true);
|
|
332
444
|
}
|
|
333
445
|
if (!cachedStatus) {
|
|
@@ -394,6 +506,9 @@ function activate(ctx) {
|
|
|
394
506
|
id: "__summary__",
|
|
395
507
|
label: t("menu.summary.spaces", { count: status.spaces.length }),
|
|
396
508
|
description: t("menu.summary.pages", { count: status.pageCount }),
|
|
509
|
+
// When the space read fails while Ego is up, say so here instead of
|
|
510
|
+
// showing an empty list with no explanation.
|
|
511
|
+
hoverText: status.error ? t("status.error", { error: status.error }) : void 0,
|
|
397
512
|
iconName: "ext:ego-browser-icons/compass",
|
|
398
513
|
disabled: true
|
|
399
514
|
}, {
|
|
@@ -472,7 +587,7 @@ ${domainOf(tab.url, t("site.unknown"))}`,
|
|
|
472
587
|
await ctx.ui.showToast({ title: t("toast.launched"), variant: "success", position: "TC" });
|
|
473
588
|
cachedStatus = void 0;
|
|
474
589
|
action.notifyUpdate();
|
|
475
|
-
refreshStatus(true);
|
|
590
|
+
void waitForRunning().then(() => refreshStatus(true));
|
|
476
591
|
return;
|
|
477
592
|
}
|
|
478
593
|
if (itemId.startsWith("resume:")) {
|
|
@@ -497,13 +612,14 @@ ${domainOf(tab.url, t("site.unknown"))}`,
|
|
|
497
612
|
const script = `const result = await completeTaskSpace(${JSON.stringify(spaceId)}, { keep: false }); cliLog(JSON.stringify(result));`;
|
|
498
613
|
await runCommand(binary, ["nodejs", "-e", script], 15e3);
|
|
499
614
|
action.notifyUpdate();
|
|
500
|
-
refreshStatus(
|
|
615
|
+
refreshStatus(false);
|
|
501
616
|
await ctx.ui.showToast({ title: t("toast.closed"), variant: "success", position: "TC" });
|
|
502
617
|
return;
|
|
503
618
|
}
|
|
504
619
|
if (itemId.startsWith("tab:")) {
|
|
505
620
|
const [spaceId, targetId] = unkey(itemId.slice("tab:".length));
|
|
506
621
|
await launchEgo();
|
|
622
|
+
if (!await waitForRunning()) throw new Error(t("error.launchTimeout"));
|
|
507
623
|
const binary = egoBinary();
|
|
508
624
|
const script = `await switchTaskSpace(${JSON.stringify(spaceId)}); await switchTab(${JSON.stringify(targetId)}); cliLog('ok');`;
|
|
509
625
|
await runCommand(binary, ["nodejs", "-e", script], 1e4);
|
|
@@ -566,8 +682,7 @@ Reuse task spaces, respect user ownership, verify meaningful actions, and comple
|
|
|
566
682
|
const actionName = request.action ?? "";
|
|
567
683
|
if (actionName === "status") {
|
|
568
684
|
const status = await getStatus(true);
|
|
569
|
-
|
|
570
|
-
action.notifyUpdate();
|
|
685
|
+
publishStatus(status, true);
|
|
571
686
|
return { content: [{ type: "text", text: statusText(status, t) }], isError: !status.supported || Boolean(status.error) };
|
|
572
687
|
}
|
|
573
688
|
if (!ACTION_STAGES[actionName]) {
|
|
@@ -596,14 +711,14 @@ Reuse task spaces, respect user ownership, verify meaningful actions, and comple
|
|
|
596
711
|
if (actionName === "switch_tab" && !request.target_id) {
|
|
597
712
|
return { content: [{ type: "text", text: "action=switch_tab requires target_id from action=status." }], isError: true };
|
|
598
713
|
}
|
|
599
|
-
if (
|
|
714
|
+
if (!isSupportedPlatform()) {
|
|
600
715
|
return { content: [{ type: "text", text: t("status.unsupported", { platform: process.platform }) }], isError: true };
|
|
601
716
|
}
|
|
602
717
|
const binary = egoBinary();
|
|
603
|
-
const version =
|
|
604
|
-
if (!
|
|
718
|
+
const version = await probeVersion(binary);
|
|
719
|
+
if (!version && !await processRunning()) {
|
|
605
720
|
return {
|
|
606
|
-
content: [{ type: "text", text:
|
|
721
|
+
content: [{ type: "text", text: t("status.notInstalled", { website: WEBSITE }) }],
|
|
607
722
|
isError: true
|
|
608
723
|
};
|
|
609
724
|
}
|
|
@@ -620,7 +735,9 @@ Reuse task spaces, respect user ownership, verify meaningful actions, and comple
|
|
|
620
735
|
if (!await processRunning()) {
|
|
621
736
|
exec.progress.report({ stage: "launching", message: pickProgress(t, "launching") });
|
|
622
737
|
await launchEgo();
|
|
623
|
-
|
|
738
|
+
if (!await waitForRunning()) {
|
|
739
|
+
return { content: [{ type: "text", text: t("error.launchTimeout") }], isError: true };
|
|
740
|
+
}
|
|
624
741
|
} else {
|
|
625
742
|
await focusEgo();
|
|
626
743
|
}
|
|
@@ -629,8 +746,7 @@ Reuse task spaces, respect user ownership, verify meaningful actions, and comple
|
|
|
629
746
|
exec.progress.report({ stage: ACTION_STAGES[actionName], message: pickProgress(t, ACTION_STAGES[actionName] ?? "browsing") });
|
|
630
747
|
try {
|
|
631
748
|
const output = await runCommand(binary, ["nodejs", "-e", script], timeout);
|
|
632
|
-
|
|
633
|
-
refreshStatus(true);
|
|
749
|
+
refreshStatus(false);
|
|
634
750
|
if (actionName === "screenshot") {
|
|
635
751
|
const path = output.split("__EGO_SHOT__").pop()?.split("\n")[0]?.trim();
|
|
636
752
|
if (!path || !existsSync(path)) {
|
|
@@ -646,15 +762,14 @@ Reuse task spaces, respect user ownership, verify meaningful actions, and comple
|
|
|
646
762
|
}
|
|
647
763
|
return { content: [{ type: "text", text: output || "ok" }] };
|
|
648
764
|
} catch (error) {
|
|
649
|
-
|
|
650
|
-
refreshStatus(true);
|
|
765
|
+
refreshStatus(false);
|
|
651
766
|
const message = error instanceof Error ? error.message : String(error);
|
|
652
767
|
return { content: [{ type: "text", text: message }], isError: true };
|
|
653
768
|
}
|
|
654
769
|
}
|
|
655
770
|
}));
|
|
656
771
|
refreshStatus(true);
|
|
657
|
-
const timer = setInterval(() => refreshStatus(
|
|
772
|
+
const timer = setInterval(() => refreshStatus(false), 5e3);
|
|
658
773
|
ctx.subscriptions.push({ dispose: () => clearInterval(timer) });
|
|
659
774
|
ctx.logger.info("ego-browser mini tool activated", { cached: Boolean(cachedStatus) });
|
|
660
775
|
}
|
package/i18n/en-US.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"badge": {
|
|
14
14
|
"online": "Ego online",
|
|
15
15
|
"offline": "Ego offline",
|
|
16
|
-
"unsupported": "
|
|
16
|
+
"unsupported": "Not supported"
|
|
17
17
|
},
|
|
18
18
|
"menu": {
|
|
19
19
|
"checking": {
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"label": "Learn about Ego Lite"
|
|
28
28
|
},
|
|
29
29
|
"unsupported": {
|
|
30
|
-
"label": "Ego Lite
|
|
30
|
+
"label": "Ego Lite needs macOS or Windows",
|
|
31
31
|
"description": "This device is not supported",
|
|
32
|
-
"hover": "Ego Lite currently runs on macOS
|
|
32
|
+
"hover": "Ego Lite currently runs on macOS and Windows. Current platform: {platform}."
|
|
33
33
|
},
|
|
34
34
|
"install": {
|
|
35
35
|
"label": "Install Ego Lite",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"user": "User control"
|
|
73
73
|
},
|
|
74
74
|
"status": {
|
|
75
|
-
"unsupported": "Ego Lite currently supports macOS
|
|
75
|
+
"unsupported": "Ego Lite currently supports macOS and Windows. Current platform: {platform}.",
|
|
76
76
|
"notInstalled": "Ego Lite is not installed. Install it from {website} and finish first-time setup.",
|
|
77
77
|
"notRunning": "Ego Lite {version} is installed but not running.",
|
|
78
78
|
"error": "Ego Lite is running, but its status could not be read: {error}"
|
|
@@ -95,7 +95,8 @@
|
|
|
95
95
|
}
|
|
96
96
|
},
|
|
97
97
|
"error": {
|
|
98
|
-
"notInstalled": "Ego Browser is not installed"
|
|
98
|
+
"notInstalled": "Ego Browser is not installed",
|
|
99
|
+
"launchTimeout": "Ego Lite was launched but is not ready yet. Wait a moment and try again."
|
|
99
100
|
},
|
|
100
101
|
"progress": {
|
|
101
102
|
"launching": "Waking up Ego Browser…|Pouring a coffee for the browser…|Ego is stretching…",
|
package/i18n/zh-CN.json
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"badge": {
|
|
14
14
|
"online": "Ego 在线",
|
|
15
15
|
"offline": "Ego 离线",
|
|
16
|
-
"unsupported": "
|
|
16
|
+
"unsupported": "平台不支持"
|
|
17
17
|
},
|
|
18
18
|
"menu": {
|
|
19
19
|
"checking": {
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
"label": "了解 Ego Lite"
|
|
28
28
|
},
|
|
29
29
|
"unsupported": {
|
|
30
|
-
"label": "Ego Lite
|
|
30
|
+
"label": "Ego Lite 支持 macOS 与 Windows",
|
|
31
31
|
"description": "当前设备暂不可用",
|
|
32
|
-
"hover": "Ego Lite
|
|
32
|
+
"hover": "Ego Lite 目前可在 macOS 和 Windows 上运行。当前平台:{platform}。"
|
|
33
33
|
},
|
|
34
34
|
"install": {
|
|
35
35
|
"label": "安装 Ego Lite",
|
|
@@ -72,7 +72,7 @@
|
|
|
72
72
|
"user": "用户控制"
|
|
73
73
|
},
|
|
74
74
|
"status": {
|
|
75
|
-
"unsupported": "Ego Lite
|
|
75
|
+
"unsupported": "Ego Lite 目前支持 macOS 和 Windows。当前平台:{platform}。",
|
|
76
76
|
"notInstalled": "Ego Lite 未安装。请从 {website} 安装并完成首次引导。",
|
|
77
77
|
"notRunning": "Ego Lite 已安装({version}),当前未运行。",
|
|
78
78
|
"error": "Ego Lite 正在运行,但状态读取失败:{error}"
|
|
@@ -95,7 +95,8 @@
|
|
|
95
95
|
}
|
|
96
96
|
},
|
|
97
97
|
"error": {
|
|
98
|
-
"notInstalled": "Ego Browser 未安装"
|
|
98
|
+
"notInstalled": "Ego Browser 未安装",
|
|
99
|
+
"launchTimeout": "Ego Lite 已启动但还没就绪,请稍等片刻再试。"
|
|
99
100
|
},
|
|
100
101
|
"progress": {
|
|
101
102
|
"launching": "正在唤醒 Ego 浏览器…|给浏览器泡杯咖啡…|Ego 正在伸懒腰…",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "finch-ego-lite",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Let Finch browse the web in isolated Ego Lite task spaces while you follow every page it opens.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "PuterJam",
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"scripts": {
|
|
22
22
|
"build": "esbuild src/index.ts --bundle --platform=node --format=esm --target=node18 --outfile=dist/index.js",
|
|
23
23
|
"typecheck": "tsc --noEmit",
|
|
24
|
+
"smoke": "node tools/smoke.mjs",
|
|
24
25
|
"prepublishOnly": "npm run typecheck && npm run build && npx @finchtoys/minitools doctor ."
|
|
25
26
|
},
|
|
26
27
|
"finch": {
|