agent-loft 0.0.0-stage → 0.2.7
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/LICENSE +21 -0
- package/README.md +110 -2
- package/bin/cli.js +52 -0
- package/package.json +64 -4
- package/src/agents/claude/account.ts +122 -0
- package/src/agents/claude/driver.ts +216 -0
- package/src/agents/claude/errors.ts +129 -0
- package/src/agents/claude/permissions.ts +260 -0
- package/src/agents/claude/probe.ts +54 -0
- package/src/agents/claude/session.ts +487 -0
- package/src/agents/codex/account.ts +122 -0
- package/src/agents/codex/app-server.ts +346 -0
- package/src/agents/codex/driver.ts +210 -0
- package/src/agents/codex/errors.ts +158 -0
- package/src/agents/codex/protocol.ts +284 -0
- package/src/agents/codex/refusals.ts +62 -0
- package/src/agents/codex/session.ts +773 -0
- package/src/channels/feishu/bot.ts +669 -0
- package/src/channels/feishu/cards.ts +360 -0
- package/src/channels/feishu/client.ts +185 -0
- package/src/channels/feishu/envelope.ts +117 -0
- package/src/channels/feishu/index.ts +62 -0
- package/src/channels/feishu/message.ts +115 -0
- package/src/channels/feishu/register.ts +171 -0
- package/src/channels/feishu/slash-sync.ts +192 -0
- package/src/channels/feishu/turn-stream.ts +98 -0
- package/src/channels/web/api.ts +645 -0
- package/src/channels/web/auth.ts +204 -0
- package/src/channels/web/http.ts +118 -0
- package/src/channels/web/push.ts +218 -0
- package/src/channels/web/server.ts +446 -0
- package/src/cli/doctor.ts +39 -0
- package/src/cli/import.ts +155 -0
- package/src/cli/pair.ts +35 -0
- package/src/cli/passwd.ts +15 -0
- package/src/cli/service.ts +137 -0
- package/src/core/agent-env.ts +11 -0
- package/src/core/command-catalog.ts +112 -0
- package/src/core/commands.ts +104 -0
- package/src/core/config.ts +285 -0
- package/src/core/dedup.ts +16 -0
- package/src/core/footers.ts +88 -0
- package/src/core/hub.ts +1152 -0
- package/src/core/interactions.ts +273 -0
- package/src/core/pairing.ts +156 -0
- package/src/core/store.ts +178 -0
- package/src/core/types.ts +213 -0
- package/src/core/uploads.ts +200 -0
- package/src/home.ts +43 -0
- package/src/main.ts +68 -0
- package/web/app.js +3731 -0
- package/web/apple-touch-icon.png +0 -0
- package/web/icon-maskable.svg +13 -0
- package/web/icon.svg +12 -0
- package/web/index.html +23 -0
- package/web/manifest.webmanifest +15 -0
- package/web/style.css +2604 -0
- package/web/sw.js +76 -0
package/web/sw.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
// 最小的 Service Worker:让页面能「添加到主屏幕」像 App 一样打开,外加系统通知。
|
|
2
|
+
// 不缓存任何东西 —— 这是一个实时操作本机的工具,离线时显示旧页面只会误导人。
|
|
3
|
+
self.addEventListener("install", () => self.skipWaiting());
|
|
4
|
+
self.addEventListener("activate", (event) => event.waitUntil(self.clients.claim()));
|
|
5
|
+
self.addEventListener("fetch", () => {});
|
|
6
|
+
|
|
7
|
+
// 服务端推来的通知(回复完成、需要授权)。iOS 要求每条推送都必须弹出通知,否则会收回推送权限
|
|
8
|
+
self.addEventListener("push", (event) => {
|
|
9
|
+
let data = {};
|
|
10
|
+
try {
|
|
11
|
+
data = event.data ? event.data.json() : {};
|
|
12
|
+
} catch {
|
|
13
|
+
data = { body: event.data ? event.data.text() : "" };
|
|
14
|
+
}
|
|
15
|
+
event.waitUntil(
|
|
16
|
+
Promise.all([
|
|
17
|
+
self.registration.showNotification(data.title || "Agent Loft", {
|
|
18
|
+
body: data.body || "",
|
|
19
|
+
tag: data.tag,
|
|
20
|
+
icon: "/apple-touch-icon.png",
|
|
21
|
+
badge: "/apple-touch-icon.png",
|
|
22
|
+
data: { url: data.url || "/" },
|
|
23
|
+
}),
|
|
24
|
+
bumpBadge(data.tag).catch(() => {}),
|
|
25
|
+
]),
|
|
26
|
+
);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// ---------- 桌面图标角标(Badging API) ----------
|
|
30
|
+
// 支持:桌面 Chrome / Edge 安装的 PWA、iOS 16.4+ 主屏 App(要有通知权限)。
|
|
31
|
+
// Android Chrome 没有这个 API,桌面红点由启动器根据通知自己显示。
|
|
32
|
+
// 角标数 = 还没看过的通知条数,同一 tag 的通知会互相替换,只算一条;打开页面时由页面清零。
|
|
33
|
+
// Service Worker 里没有 localStorage,计数放在 Cache Storage 里(只存这一个计数,不缓存页面)。
|
|
34
|
+
|
|
35
|
+
const BADGE_CACHE = "aim-badge";
|
|
36
|
+
const BADGE_URL = "/__badge";
|
|
37
|
+
|
|
38
|
+
async function readBadgeTags() {
|
|
39
|
+
try {
|
|
40
|
+
const res = await (await caches.open(BADGE_CACHE)).match(BADGE_URL);
|
|
41
|
+
const tags = res ? await res.json() : [];
|
|
42
|
+
return Array.isArray(tags) ? tags : [];
|
|
43
|
+
} catch {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async function bumpBadge(tag) {
|
|
49
|
+
if (!("setAppBadge" in self.navigator)) return;
|
|
50
|
+
// 用户正看着页面就不加角标
|
|
51
|
+
const windows = await self.clients.matchAll({ type: "window", includeUncontrolled: true });
|
|
52
|
+
if (windows.some((w) => w.visibilityState === "visible")) return;
|
|
53
|
+
const tags = await readBadgeTags();
|
|
54
|
+
const id = tag || `untagged:${Date.now()}:${Math.random()}`;
|
|
55
|
+
if (!tags.includes(id)) tags.push(id);
|
|
56
|
+
await (await caches.open(BADGE_CACHE)).put(BADGE_URL, new Response(JSON.stringify(tags)));
|
|
57
|
+
await self.navigator.setAppBadge(tags.length).catch(() => {});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 点通知:已经开着页面就切过去并跳到那条会话,没开就新开一个
|
|
61
|
+
self.addEventListener("notificationclick", (event) => {
|
|
62
|
+
event.notification.close();
|
|
63
|
+
const url = new URL(event.notification.data?.url || "/", self.location.origin).href;
|
|
64
|
+
event.waitUntil(
|
|
65
|
+
(async () => {
|
|
66
|
+
const windows = await self.clients.matchAll({ type: "window", includeUncontrolled: true });
|
|
67
|
+
const existing = windows.find((w) => new URL(w.url).origin === self.location.origin);
|
|
68
|
+
if (existing) {
|
|
69
|
+
await existing.focus().catch(() => {});
|
|
70
|
+
existing.postMessage({ type: "open", url });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
await self.clients.openWindow(url);
|
|
74
|
+
})(),
|
|
75
|
+
);
|
|
76
|
+
});
|