omp-wechat 1.6.0 → 1.7.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 +73 -21
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2006,13 +2006,20 @@ import { homedir as homedir6 } from "os";
|
|
|
2006
2006
|
import { existsSync as existsSync2, mkdirSync as mkdirSync5, readdirSync as readdirSync2, statSync as statSync3, rmSync } from "fs";
|
|
2007
2007
|
var STATE_DIR4 = join7(homedir6(), ".omp-wechat");
|
|
2008
2008
|
var SESSIONS_DIR = join7(STATE_DIR4, "sessions");
|
|
2009
|
+
var DEFAULT_OUTBOX_BASE = join7(STATE_DIR4, "outbox");
|
|
2009
2010
|
var STALE_THRESHOLD_MS = 30 * 24 * 60 * 60 * 1000;
|
|
2010
2011
|
function sanitizeChatId(chatId) {
|
|
2011
2012
|
return chatId.replace(/[^a-zA-Z0-9_@.-]/g, "_").slice(0, 200);
|
|
2012
2013
|
}
|
|
2014
|
+
function sanitizeOutboxChatId(chatId) {
|
|
2015
|
+
return chatId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2016
|
+
}
|
|
2013
2017
|
function sessionDirFor(chatId) {
|
|
2014
2018
|
return join7(SESSIONS_DIR, sanitizeChatId(chatId));
|
|
2015
2019
|
}
|
|
2020
|
+
function outboxDirFor(chatId, outboxBase) {
|
|
2021
|
+
return join7(outboxBase ?? DEFAULT_OUTBOX_BASE, sanitizeOutboxChatId(chatId));
|
|
2022
|
+
}
|
|
2016
2023
|
function ensureSessionsDir() {
|
|
2017
2024
|
mkdirSync5(SESSIONS_DIR, { recursive: true, mode: 448 });
|
|
2018
2025
|
}
|
|
@@ -2028,6 +2035,54 @@ function removeSessionDir(chatId) {
|
|
|
2028
2035
|
return false;
|
|
2029
2036
|
}
|
|
2030
2037
|
}
|
|
2038
|
+
function removeOutboxDir(chatId, outboxBase) {
|
|
2039
|
+
const dir = outboxDirFor(chatId, outboxBase);
|
|
2040
|
+
if (!existsSync2(dir))
|
|
2041
|
+
return false;
|
|
2042
|
+
try {
|
|
2043
|
+
rmSync(dir, { recursive: true, force: true });
|
|
2044
|
+
logger.info(`Removed outbox dir: ${dir}`);
|
|
2045
|
+
return true;
|
|
2046
|
+
} catch (err) {
|
|
2047
|
+
logger.warn(`Failed to remove outbox dir ${dir}: ${err}`);
|
|
2048
|
+
return false;
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
function cleanupStaleOutboxes(outboxBase) {
|
|
2052
|
+
const base = outboxBase ?? DEFAULT_OUTBOX_BASE;
|
|
2053
|
+
if (!existsSync2(base))
|
|
2054
|
+
return 0;
|
|
2055
|
+
const now = Date.now();
|
|
2056
|
+
let removed = 0;
|
|
2057
|
+
for (const entry of readdirSync2(base, { withFileTypes: true })) {
|
|
2058
|
+
if (!entry.isDirectory())
|
|
2059
|
+
continue;
|
|
2060
|
+
const dir = join7(base, entry.name);
|
|
2061
|
+
let newestMtime = 0;
|
|
2062
|
+
try {
|
|
2063
|
+
for (const file of readdirSync2(dir)) {
|
|
2064
|
+
const mtime = statSync3(join7(dir, file)).mtimeMs;
|
|
2065
|
+
if (mtime > newestMtime)
|
|
2066
|
+
newestMtime = mtime;
|
|
2067
|
+
}
|
|
2068
|
+
} catch {
|
|
2069
|
+
continue;
|
|
2070
|
+
}
|
|
2071
|
+
if (newestMtime === 0 || now - newestMtime > STALE_THRESHOLD_MS) {
|
|
2072
|
+
try {
|
|
2073
|
+
rmSync(dir, { recursive: true, force: true });
|
|
2074
|
+
removed++;
|
|
2075
|
+
logger.info(`Cleaned up stale outbox dir: ${entry.name}`);
|
|
2076
|
+
} catch (err) {
|
|
2077
|
+
logger.warn(`Failed to cleanup outbox dir ${entry.name}: ${err}`);
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
}
|
|
2081
|
+
if (removed > 0) {
|
|
2082
|
+
logger.info(`Outbox cleanup: removed ${removed} stale outbox(es)`);
|
|
2083
|
+
}
|
|
2084
|
+
return removed;
|
|
2085
|
+
}
|
|
2031
2086
|
function cleanupStaleSessions() {
|
|
2032
2087
|
if (!existsSync2(SESSIONS_DIR))
|
|
2033
2088
|
return 0;
|
|
@@ -2081,15 +2136,7 @@ function clearAllSessions() {
|
|
|
2081
2136
|
|
|
2082
2137
|
// src/engine/session.ts
|
|
2083
2138
|
import { mkdirSync as mkdirSync6, readdirSync as readdirSync3, statSync as statSync4 } from "fs";
|
|
2084
|
-
import { homedir as homedir7 } from "os";
|
|
2085
2139
|
import { join as join8 } from "path";
|
|
2086
|
-
var DEFAULT_OUTBOX_BASE = join8(homedir7(), ".omp-wechat", "outbox");
|
|
2087
|
-
function sanitizeChatId2(chatId) {
|
|
2088
|
-
return chatId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2089
|
-
}
|
|
2090
|
-
function outboxDirFor(chatId, config) {
|
|
2091
|
-
return join8(config.outboxDir ?? DEFAULT_OUTBOX_BASE, sanitizeChatId2(chatId));
|
|
2092
|
-
}
|
|
2093
2140
|
function outboxInstructions(outboxDir) {
|
|
2094
2141
|
return `## File delivery to WeChat
|
|
2095
2142
|
|
|
@@ -2137,7 +2184,7 @@ class ChatSession {
|
|
|
2137
2184
|
}
|
|
2138
2185
|
static async create(chatId, contextToken, config, onReply, onFiles) {
|
|
2139
2186
|
logger.info(`Creating session: ${chatId}`);
|
|
2140
|
-
const outboxDir = outboxDirFor(chatId, config);
|
|
2187
|
+
const outboxDir = outboxDirFor(chatId, config.outboxDir);
|
|
2141
2188
|
const sendFilesEnabled = config.sendFiles !== false;
|
|
2142
2189
|
if (sendFilesEnabled) {
|
|
2143
2190
|
try {
|
|
@@ -2270,13 +2317,14 @@ class SessionPool {
|
|
|
2270
2317
|
get(chatId) {
|
|
2271
2318
|
return this.pool.get(chatId);
|
|
2272
2319
|
}
|
|
2273
|
-
async resetSession(chatId) {
|
|
2320
|
+
async resetSession(chatId, config) {
|
|
2274
2321
|
const entry = this.pool.get(chatId);
|
|
2275
2322
|
if (entry) {
|
|
2276
2323
|
await entry.dispose();
|
|
2277
2324
|
this.pool.delete(chatId);
|
|
2278
2325
|
}
|
|
2279
2326
|
removeSessionDir(chatId);
|
|
2327
|
+
removeOutboxDir(chatId, config.outboxDir);
|
|
2280
2328
|
}
|
|
2281
2329
|
getContextToken(chatId) {
|
|
2282
2330
|
return this.pool.get(chatId)?.getContextToken() ?? "";
|
|
@@ -2479,7 +2527,7 @@ class ModelCommand {
|
|
|
2479
2527
|
// src/command/new-session-command.ts
|
|
2480
2528
|
class NewSessionInvocation {
|
|
2481
2529
|
async execute(ctx) {
|
|
2482
|
-
await ctx.pool.resetSession(ctx.chatId);
|
|
2530
|
+
await ctx.pool.resetSession(ctx.chatId, ctx.config);
|
|
2483
2531
|
return "Session reset. Your next message starts a fresh conversation.";
|
|
2484
2532
|
}
|
|
2485
2533
|
}
|
|
@@ -2583,7 +2631,11 @@ class WeChatBridge {
|
|
|
2583
2631
|
this.releaseLock();
|
|
2584
2632
|
});
|
|
2585
2633
|
cleanupStaleSessions();
|
|
2586
|
-
|
|
2634
|
+
cleanupStaleOutboxes(config.outboxDir);
|
|
2635
|
+
this.cleanupTimer = setInterval(() => {
|
|
2636
|
+
cleanupStaleSessions();
|
|
2637
|
+
cleanupStaleOutboxes(config.outboxDir);
|
|
2638
|
+
}, 6 * 60 * 60 * 1000);
|
|
2587
2639
|
return this.state;
|
|
2588
2640
|
}
|
|
2589
2641
|
async stop() {
|
|
@@ -2835,7 +2887,7 @@ ${truncated}
|
|
|
2835
2887
|
}
|
|
2836
2888
|
|
|
2837
2889
|
// src/service.ts
|
|
2838
|
-
import { platform, homedir as
|
|
2890
|
+
import { platform, homedir as homedir7 } from "os";
|
|
2839
2891
|
import { join as join9, basename as basename4 } from "path";
|
|
2840
2892
|
import { existsSync as existsSync3, mkdirSync as mkdirSync7, writeFileSync as writeFileSync4, rmSync as rmSync3 } from "fs";
|
|
2841
2893
|
var PLIST_LABEL = "com.omp-wechat";
|
|
@@ -2851,14 +2903,14 @@ function detectPlatform() {
|
|
|
2851
2903
|
return "other";
|
|
2852
2904
|
}
|
|
2853
2905
|
function getLogDir() {
|
|
2854
|
-
return join9(
|
|
2906
|
+
return join9(homedir7(), ".omp", "logs");
|
|
2855
2907
|
}
|
|
2856
2908
|
function resolveHostBinary() {
|
|
2857
2909
|
const exe = process.execPath || "omp";
|
|
2858
2910
|
return basename4(exe);
|
|
2859
2911
|
}
|
|
2860
2912
|
function plistPath() {
|
|
2861
|
-
return join9(
|
|
2913
|
+
return join9(homedir7(), "Library", "LaunchAgents", `${PLIST_LABEL}.plist`);
|
|
2862
2914
|
}
|
|
2863
2915
|
function generatePlist() {
|
|
2864
2916
|
const omp = resolveHostBinary();
|
|
@@ -2894,14 +2946,14 @@ function generatePlist() {
|
|
|
2894
2946
|
<key>PATH</key>
|
|
2895
2947
|
<string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>
|
|
2896
2948
|
<key>HOME</key>
|
|
2897
|
-
<string>${
|
|
2949
|
+
<string>${homedir7()}</string>
|
|
2898
2950
|
</dict>
|
|
2899
2951
|
</dict>
|
|
2900
2952
|
</plist>
|
|
2901
2953
|
`;
|
|
2902
2954
|
}
|
|
2903
2955
|
function installLaunchd() {
|
|
2904
|
-
const dir = join9(
|
|
2956
|
+
const dir = join9(homedir7(), "Library", "LaunchAgents");
|
|
2905
2957
|
mkdirSync7(dir, { recursive: true });
|
|
2906
2958
|
mkdirSync7(getLogDir(), { recursive: true });
|
|
2907
2959
|
const plist = plistPath();
|
|
@@ -2943,7 +2995,7 @@ ExecStart=/bin/sh -c 'while true; do echo "{\\"id\\":\\"ka\\",\\"type\\":\\"get_
|
|
|
2943
2995
|
Restart=always
|
|
2944
2996
|
RestartSec=10
|
|
2945
2997
|
|
|
2946
|
-
Environment=HOME=${
|
|
2998
|
+
Environment=HOME=${homedir7()}
|
|
2947
2999
|
Environment=PATH=/usr/local/bin:/usr/bin:/bin
|
|
2948
3000
|
|
|
2949
3001
|
StandardOutput=null
|
|
@@ -2952,7 +3004,7 @@ StandardError=append:${logDir}/rpc.log
|
|
|
2952
3004
|
NoNewPrivileges=true
|
|
2953
3005
|
ProtectSystem=strict
|
|
2954
3006
|
ProtectHome=read-only
|
|
2955
|
-
ReadWritePaths=${logDir} ${join9(
|
|
3007
|
+
ReadWritePaths=${logDir} ${join9(homedir7(), ".omp-wechat")} ${join9(homedir7(), ".omp")}
|
|
2956
3008
|
PrivateTmp=true
|
|
2957
3009
|
|
|
2958
3010
|
[Install]
|
|
@@ -2993,7 +3045,7 @@ function uninstallSystemd() {
|
|
|
2993
3045
|
}
|
|
2994
3046
|
var WIN_TASK_NAME = "OMP-Wechat";
|
|
2995
3047
|
function winScriptPath() {
|
|
2996
|
-
return join9(
|
|
3048
|
+
return join9(homedir7(), ".omp-wechat", "omp-wechat-rpc.ps1");
|
|
2997
3049
|
}
|
|
2998
3050
|
function generateWinScript() {
|
|
2999
3051
|
const omp = process.execPath || "omp";
|
|
@@ -3036,7 +3088,7 @@ while ($true) {
|
|
|
3036
3088
|
`;
|
|
3037
3089
|
}
|
|
3038
3090
|
function installWinTask() {
|
|
3039
|
-
mkdirSync7(join9(
|
|
3091
|
+
mkdirSync7(join9(homedir7(), ".omp-wechat"), { recursive: true });
|
|
3040
3092
|
mkdirSync7(getLogDir(), { recursive: true });
|
|
3041
3093
|
writeFileSync4(winScriptPath(), generateWinScript());
|
|
3042
3094
|
Bun.spawnSync(["schtasks", "/end", "/tn", WIN_TASK_NAME], { stderr: "ignore" });
|