sync-omo-config 1.0.1 → 1.3.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/dist/index.js +91 -7
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4,9 +4,53 @@ import { homedir } from "os";
|
|
|
4
4
|
import { existsSync } from "fs";
|
|
5
5
|
import { mkdir } from "fs/promises";
|
|
6
6
|
import path from "path";
|
|
7
|
+
function notifyDesktop(title, message) {
|
|
8
|
+
const platform = process.platform;
|
|
9
|
+
const esc = (value) => value.replaceAll(`
|
|
10
|
+
`, " ").replaceAll('"', "\\\"");
|
|
11
|
+
const escps = (value) => value.replaceAll(`
|
|
12
|
+
`, " ").replaceAll("'", "''");
|
|
13
|
+
if (platform === "darwin") {
|
|
14
|
+
const script = [
|
|
15
|
+
`display notification "${esc(message)}" with title "${esc(title)}"`,
|
|
16
|
+
`display alert "${esc(title)}" message "${esc(message)}" giving up after 10`
|
|
17
|
+
].join(`
|
|
18
|
+
`);
|
|
19
|
+
const proc = Bun.spawn(["/usr/bin/osascript", "-e", script], { stdout: "ignore", stderr: "ignore" });
|
|
20
|
+
proc.exited.catch(() => {
|
|
21
|
+
return;
|
|
22
|
+
});
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
if (platform === "linux") {
|
|
26
|
+
const proc = Bun.spawn(["/usr/bin/env", "notify-send", "--urgency=critical", title, message], { stdout: "ignore", stderr: "ignore" });
|
|
27
|
+
proc.exited.catch(() => {
|
|
28
|
+
return;
|
|
29
|
+
});
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
if (platform === "win32") {
|
|
33
|
+
const script = [
|
|
34
|
+
"Add-Type -AssemblyName System.Windows.Forms",
|
|
35
|
+
`[System.Windows.Forms.MessageBox]::Show('${escps(message)}','${escps(title)}','OK','Error') | Out-Null`
|
|
36
|
+
].join("; ");
|
|
37
|
+
const proc = Bun.spawn(["powershell", "-NoProfile", "-Command", script], {
|
|
38
|
+
stdout: "ignore",
|
|
39
|
+
stderr: "ignore"
|
|
40
|
+
});
|
|
41
|
+
proc.exited.catch(() => {
|
|
42
|
+
return;
|
|
43
|
+
});
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
console.warn(`[sync-omo-config] Desktop notify not supported on ${platform}`);
|
|
47
|
+
}
|
|
7
48
|
function getDataDir() {
|
|
8
49
|
const home = homedir();
|
|
9
|
-
const xdgData = process.env.XDG_DATA_HOME || path.join(home, ".local", "share");
|
|
50
|
+
const xdgData = process.env.XDG_DATA_HOME || (home ? path.join(home, ".local", "share") : undefined);
|
|
51
|
+
if (!xdgData) {
|
|
52
|
+
throw new Error("[sync-omo-config] Cannot determine data directory: HOME is not set");
|
|
53
|
+
}
|
|
10
54
|
return path.join(xdgData, "opencode");
|
|
11
55
|
}
|
|
12
56
|
function getConfigDir() {
|
|
@@ -58,23 +102,24 @@ async function syncOmoConfig() {
|
|
|
58
102
|
const authFile = Bun.file(authPath);
|
|
59
103
|
if (!await authFile.exists()) {
|
|
60
104
|
console.log(`${LOG_PREFIX} auth.json not found at ${authPath}, skipping sync`);
|
|
61
|
-
return;
|
|
105
|
+
return [];
|
|
62
106
|
}
|
|
63
107
|
let auth;
|
|
64
108
|
try {
|
|
65
109
|
auth = await authFile.json();
|
|
66
110
|
} catch (e) {
|
|
67
111
|
console.error(`${LOG_PREFIX} Failed to parse auth.json:`, e);
|
|
68
|
-
return;
|
|
112
|
+
return [];
|
|
69
113
|
}
|
|
70
114
|
const omoConfigs = [];
|
|
115
|
+
const expiredServers = [];
|
|
71
116
|
for (const [serverUrl, authInfo] of Object.entries(auth)) {
|
|
72
117
|
if (!isWellKnownAuth(authInfo)) {
|
|
73
118
|
continue;
|
|
74
119
|
}
|
|
75
120
|
console.log(`${LOG_PREFIX} Fetching config from ${serverUrl}`);
|
|
76
121
|
try {
|
|
77
|
-
const wellKnownUrl = `${serverUrl}/.well-known/opencode`;
|
|
122
|
+
const wellKnownUrl = serverUrl.includes("/.well-known/opencode") ? serverUrl : `${serverUrl}/.well-known/opencode`;
|
|
78
123
|
const response = await fetch(wellKnownUrl, {
|
|
79
124
|
headers: {
|
|
80
125
|
Accept: "application/json"
|
|
@@ -85,6 +130,15 @@ async function syncOmoConfig() {
|
|
|
85
130
|
continue;
|
|
86
131
|
}
|
|
87
132
|
const data = await response.json();
|
|
133
|
+
if (data.auth_status === "invalid" || data.auth_status === "reauth_required") {
|
|
134
|
+
console.warn(`${LOG_PREFIX} Auth expired for ${serverUrl}, will notify via TUI toast`);
|
|
135
|
+
notifyDesktop("OpenCode: \u6388\u6743\u5DF2\u5931\u6548", `\u670D\u52A1\u5668 ${serverUrl} \u7684\u6388\u6743\u5DF2\u8FC7\u671F\uFF0C\u5DF2\u81EA\u52A8\u6E05\u9664\u51ED\u8BC1\u3002\u8BF7\u91CD\u65B0\u767B\u5F55\u8BA4\u8BC1\u3002`);
|
|
136
|
+
expiredServers.push(serverUrl);
|
|
137
|
+
delete auth[serverUrl];
|
|
138
|
+
await Bun.write(authPath, JSON.stringify(auth, null, 2), { mode: 384 });
|
|
139
|
+
console.log(`${LOG_PREFIX} Removed expired credential for ${serverUrl} from auth.json`);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
88
142
|
if (data.omo && typeof data.omo === "object") {
|
|
89
143
|
console.log(`${LOG_PREFIX} Found omo config from ${serverUrl}`);
|
|
90
144
|
omoConfigs.push(data.omo);
|
|
@@ -96,7 +150,7 @@ async function syncOmoConfig() {
|
|
|
96
150
|
}
|
|
97
151
|
if (omoConfigs.length === 0) {
|
|
98
152
|
console.log(`${LOG_PREFIX} No omo configs found, skipping write`);
|
|
99
|
-
return;
|
|
153
|
+
return expiredServers;
|
|
100
154
|
}
|
|
101
155
|
console.log(`${LOG_PREFIX} Found ${omoConfigs.length} omo config(s)`);
|
|
102
156
|
const configDir = getConfigDir();
|
|
@@ -119,12 +173,42 @@ async function syncOmoConfig() {
|
|
|
119
173
|
}
|
|
120
174
|
await Bun.write(omoPath, JSON.stringify(mergedConfig, null, 2));
|
|
121
175
|
console.log(`${LOG_PREFIX} Successfully wrote oh-my-opencode.json to ${omoPath}`);
|
|
176
|
+
return expiredServers;
|
|
122
177
|
} catch (error) {
|
|
123
178
|
console.error(`${LOG_PREFIX} Unexpected error during sync:`, error);
|
|
179
|
+
return [];
|
|
124
180
|
}
|
|
125
181
|
}
|
|
126
|
-
var SyncOmoConfigPlugin = async function SyncOmoConfigPlugin2() {
|
|
127
|
-
await syncOmoConfig();
|
|
182
|
+
var SyncOmoConfigPlugin = async function SyncOmoConfigPlugin2(input) {
|
|
183
|
+
const expiredServers = await syncOmoConfig();
|
|
184
|
+
if (expiredServers.length === 0)
|
|
185
|
+
return {};
|
|
186
|
+
const pending = new Set(expiredServers);
|
|
187
|
+
const delays = [2000, 4000, 8000, 15000];
|
|
188
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
189
|
+
const notify = async () => {
|
|
190
|
+
for (const delay of delays) {
|
|
191
|
+
if (pending.size === 0)
|
|
192
|
+
return;
|
|
193
|
+
await sleep(delay);
|
|
194
|
+
for (const server of [...pending]) {
|
|
195
|
+
const ok = await input.client.tui.showToast({
|
|
196
|
+
body: {
|
|
197
|
+
title: "\u26A0 \u6388\u6743\u5DF2\u5931\u6548",
|
|
198
|
+
message: `\u670D\u52A1\u5668 ${server} \u7684\u6388\u6743\u5DF2\u8FC7\u671F\uFF0C\u5DF2\u81EA\u52A8\u6E05\u9664\u51ED\u8BC1\u3002\u8BF7\u91CD\u65B0\u767B\u5F55\u8BA4\u8BC1\u3002`,
|
|
199
|
+
variant: "error",
|
|
200
|
+
duration: 30000
|
|
201
|
+
}
|
|
202
|
+
}).then(() => true).catch((e) => {
|
|
203
|
+
console.error("[sync-omo-config] Failed to show toast:", e);
|
|
204
|
+
return false;
|
|
205
|
+
});
|
|
206
|
+
if (ok)
|
|
207
|
+
pending.delete(server);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
notify();
|
|
128
212
|
return {};
|
|
129
213
|
};
|
|
130
214
|
var src_default = SyncOmoConfigPlugin;
|