weflow-cli 1.13.0 → 1.14.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/CHANGELOG.md +33 -0
- package/OPERATIONS.md +1 -0
- package/README.md +6 -0
- package/bin/weflow-cli.ts +25 -2
- package/dist/bin/weflow-cli.js +28 -2
- package/dist/bin/weflow-cli.js.map +1 -1
- package/dist/src/services/configService.d.ts +3 -0
- package/dist/src/services/configService.d.ts.map +1 -1
- package/dist/src/services/configService.js +3 -2
- package/dist/src/services/configService.js.map +1 -1
- package/dist/src/services/wechatClient.d.ts +8 -0
- package/dist/src/services/wechatClient.d.ts.map +1 -1
- package/dist/src/services/wechatClient.js +14 -2
- package/dist/src/services/wechatClient.js.map +1 -1
- package/docs/DECISIONS.md +30 -0
- package/package.json +1 -1
- package/scripts/_utils.py +21 -2
- package/scripts/daily_mail.py +467 -0
- package/scripts/daily_task.ps1 +20 -0
- package/scripts/jev_client.py +136 -2
- package/src/services/configService.ts +8 -3
- package/src/services/wechatClient.ts +12 -2
|
@@ -49,8 +49,10 @@ interface CliConfig {
|
|
|
49
49
|
typesafeApiKey: string
|
|
50
50
|
// 阿里云百炼(DashScope)API Key —— 语义检索 / RAG 的 embedding 用它
|
|
51
51
|
dashscopeApiKey: string
|
|
52
|
-
// 决策模型走哪条通路:native(默认,api.typesafe.ai)/ openrouter
|
|
52
|
+
// 决策模型走哪条通路:native(默认,api.typesafe.ai)/ openrouter / chat / local(本机决策模型)
|
|
53
53
|
judgeProvider: string
|
|
54
|
+
// 本地决策模型服务地址 —— judgeProvider=local 时用它(默认 http://127.0.0.1:8090,见 D-127)
|
|
55
|
+
judgeLocalUrl: string
|
|
54
56
|
// OpenRouter API Key —— judgeProvider=openrouter 时用它(D-120)
|
|
55
57
|
openrouterApiKey: string
|
|
56
58
|
// OpenRouter 上用的模型 id(默认 typesafe/jev-router,即 TypeSafe 发布的决策模型)
|
|
@@ -97,6 +99,8 @@ interface CliConfig {
|
|
|
97
99
|
/** 不在日报里出现的主题,逗号分隔(如 新闻,投资);展示层开关,改它不用重抓 */
|
|
98
100
|
dailyExcludeTopics: string
|
|
99
101
|
dailyAiEnabled: string
|
|
102
|
+
/** 日报邮件的收件人(`daily --email` 与定时任务用);空则发给 SMTP 账号自己 */
|
|
103
|
+
dailyMailTo?: string
|
|
100
104
|
}
|
|
101
105
|
|
|
102
106
|
export interface ListEntry {
|
|
@@ -117,7 +121,7 @@ const CONFIG_DIR = join(homedir(), '.weflow-cli')
|
|
|
117
121
|
const CONFIG_FILE = join(CONFIG_DIR, 'config.json')
|
|
118
122
|
|
|
119
123
|
export class ConfigService {
|
|
120
|
-
private config: CliConfig = { dbPath: '', wxid: '', decryptKey: '', decryptKey3x: '', dataVersion: '', dbPath3x: '', ntDbPath: '', ntKey: '', ntSalt: '', contactDbPath: '', contactKey: '', contactSalt: '', wechatOcToken: '', wechatOcAccountId: '', wechatOcBaseUrl: '', wechatOcSyncBuf: '', wechatOcContextTokens: '', wechatMediaDownload: 'false', whitelist: [], blacklist: [], whitelistEntries: [], blacklistEntries: [], vaultRepo: '', aiEngine: 'deepseek', wereadApiKey: '', deepseekApiKey: '', typesafeApiKey: '', dashscopeApiKey: '', judgeProvider: 'native', openrouterApiKey: '', openrouterJudgeModel: '', snsDbPath: '', snsKey: '', snsSalt: '', favDbPath: '', favKey: '', favPassphrase: '', emoticonSeed: '', assistantPrivacy: 'strict', localModel: '', aiBaseUrl: '', aiModel: '', assistantWhitelist: '', assistantGroupWhitelist: '', assistantGroupRequireMention: 'true', assistantFastRoute: 'off', assistantPanelUser: '', quickReplyContacts: '', skillDirs: '', skillDisabled: '', dailySources: '', dailySourceCategories: '', dailyExcludeTopics: '', dailyAiEnabled: 'true' }
|
|
124
|
+
private config: CliConfig = { dbPath: '', wxid: '', decryptKey: '', decryptKey3x: '', dataVersion: '', dbPath3x: '', ntDbPath: '', ntKey: '', ntSalt: '', contactDbPath: '', contactKey: '', contactSalt: '', wechatOcToken: '', wechatOcAccountId: '', wechatOcBaseUrl: '', wechatOcSyncBuf: '', wechatOcContextTokens: '', wechatMediaDownload: 'false', whitelist: [], blacklist: [], whitelistEntries: [], blacklistEntries: [], vaultRepo: '', aiEngine: 'deepseek', wereadApiKey: '', deepseekApiKey: '', typesafeApiKey: '', dashscopeApiKey: '', judgeProvider: 'native', openrouterApiKey: '', openrouterJudgeModel: '', judgeLocalUrl: '', snsDbPath: '', snsKey: '', snsSalt: '', favDbPath: '', favKey: '', favPassphrase: '', emoticonSeed: '', assistantPrivacy: 'strict', localModel: '', aiBaseUrl: '', aiModel: '', assistantWhitelist: '', assistantGroupWhitelist: '', assistantGroupRequireMention: 'true', assistantFastRoute: 'off', assistantPanelUser: '', quickReplyContacts: '', skillDirs: '', skillDisabled: '', dailySources: '', dailySourceCategories: '', dailyExcludeTopics: '', dailyAiEnabled: 'true' }
|
|
121
125
|
|
|
122
126
|
/** 本进程修改过、待回写的字段 (多进程并发写保护) */
|
|
123
127
|
private dirty = new Set<keyof CliConfig>()
|
|
@@ -169,6 +173,7 @@ export class ConfigService {
|
|
|
169
173
|
typesafeApiKey: data.typesafeApiKey || '',
|
|
170
174
|
dashscopeApiKey: data.dashscopeApiKey || '',
|
|
171
175
|
judgeProvider: data.judgeProvider || 'native',
|
|
176
|
+
judgeLocalUrl: data.judgeLocalUrl || '',
|
|
172
177
|
openrouterApiKey: data.openrouterApiKey || '',
|
|
173
178
|
openrouterJudgeModel: data.openrouterJudgeModel || '',
|
|
174
179
|
snsDbPath: data.snsDbPath || '',
|
|
@@ -378,7 +383,7 @@ export class ConfigService {
|
|
|
378
383
|
}
|
|
379
384
|
|
|
380
385
|
clear(): void {
|
|
381
|
-
this.config = { dbPath: '', wxid: '', decryptKey: '', decryptKey3x: '', dataVersion: '', dbPath3x: '', ntDbPath: '', ntKey: '', ntSalt: '', contactDbPath: '', contactKey: '', contactSalt: '', wechatOcToken: '', wechatOcAccountId: '', wechatOcBaseUrl: '', wechatOcSyncBuf: '', wechatOcContextTokens: '', wechatMediaDownload: 'false', whitelist: [], blacklist: [], whitelistEntries: [], blacklistEntries: [], vaultRepo: '', aiEngine: 'deepseek', wereadApiKey: '', deepseekApiKey: '', typesafeApiKey: '', dashscopeApiKey: '', judgeProvider: 'native', openrouterApiKey: '', openrouterJudgeModel: '', snsDbPath: '', snsKey: '', snsSalt: '', favDbPath: '', favKey: '', favPassphrase: '', emoticonSeed: '', assistantPrivacy: 'strict', localModel: '', aiBaseUrl: '', aiModel: '', assistantWhitelist: '', assistantGroupWhitelist: '', assistantGroupRequireMention: 'true', assistantFastRoute: 'off', assistantPanelUser: '', quickReplyContacts: '', skillDirs: '', skillDisabled: '', dailySources: '', dailySourceCategories: '', dailyExcludeTopics: '', dailyAiEnabled: 'true' }
|
|
386
|
+
this.config = { dbPath: '', wxid: '', decryptKey: '', decryptKey3x: '', dataVersion: '', dbPath3x: '', ntDbPath: '', ntKey: '', ntSalt: '', contactDbPath: '', contactKey: '', contactSalt: '', wechatOcToken: '', wechatOcAccountId: '', wechatOcBaseUrl: '', wechatOcSyncBuf: '', wechatOcContextTokens: '', wechatMediaDownload: 'false', whitelist: [], blacklist: [], whitelistEntries: [], blacklistEntries: [], vaultRepo: '', aiEngine: 'deepseek', wereadApiKey: '', deepseekApiKey: '', typesafeApiKey: '', dashscopeApiKey: '', judgeProvider: 'native', openrouterApiKey: '', openrouterJudgeModel: '', judgeLocalUrl: '', snsDbPath: '', snsKey: '', snsSalt: '', favDbPath: '', favKey: '', favPassphrase: '', emoticonSeed: '', assistantPrivacy: 'strict', localModel: '', aiBaseUrl: '', aiModel: '', assistantWhitelist: '', assistantGroupWhitelist: '', assistantGroupRequireMention: 'true', assistantFastRoute: 'off', assistantPanelUser: '', quickReplyContacts: '', skillDirs: '', skillDisabled: '', dailySources: '', dailySourceCategories: '', dailyExcludeTopics: '', dailyAiEnabled: 'true' }
|
|
382
387
|
// clear 意图是全量重置: 所有字段标记为脏, 覆盖磁盘上的全部旧值
|
|
383
388
|
this.dirty = new Set(Object.keys(this.config) as (keyof CliConfig)[])
|
|
384
389
|
this.save()
|
|
@@ -90,7 +90,7 @@ const VERSION_DIR = /^\d+(\.\d+)+$/
|
|
|
90
90
|
// 于是"客户端自报数据目录"这一项**永远是空的**而看不出来)。版本那一支只认 `Weixin.exe`(见 `summarize`)。
|
|
91
91
|
// `WeixinDll` 是**同一件事的第二观测**:Win32_Process 只有命令行,模块表要问进程本身。
|
|
92
92
|
// 每条都单独 try —— 一个进程读不到模块不该让整张表为空(那会把"读不到"讲成"客户端没在跑")。
|
|
93
|
-
const PS_LIST = "$rows = Get-CimInstance Win32_Process -Filter (\"Name='Weixin.exe' or Name='WeChatAppEx.exe'\") | ForEach-Object { $dll = $null; try { $dll = (Get-Process -Id $_.ProcessId -ErrorAction Stop).Modules | Where-Object { $_.ModuleName -eq 'Weixin.dll' } | Select-Object -First 1 -ExpandProperty FileName } catch {}; [pscustomobject]@{ ProcessId = $_.ProcessId; ExecutablePath = $_.ExecutablePath; CommandLine = $_.CommandLine; WeixinDll = $dll } }; if ($rows) { $rows | ConvertTo-Json -Compress }"
|
|
93
|
+
export const PS_LIST = "$rows = Get-CimInstance Win32_Process -Filter (\"Name='Weixin.exe' or Name='WeChatAppEx.exe'\") | ForEach-Object { $dll = $null; try { $dll = (Get-Process -Id $_.ProcessId -ErrorAction Stop).Modules | Where-Object { $_.ModuleName -eq 'Weixin.dll' } | Select-Object -First 1 -ExpandProperty FileName } catch {}; [pscustomobject]@{ ProcessId = $_.ProcessId; ExecutablePath = $_.ExecutablePath; CommandLine = $_.CommandLine; WeixinDll = $dll } }; if ($rows) { [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes(($rows | ConvertTo-Json -Compress))) }"
|
|
94
94
|
|
|
95
95
|
export function parseProcessRows(raw: string): WechatClientProcess[] {
|
|
96
96
|
const text = String(raw || '').trim()
|
|
@@ -362,7 +362,17 @@ export async function reportedDataDirs(run: PowershellRunner = defaultRunner): P
|
|
|
362
362
|
const defaultRunner: PowershellRunner = async (command) => {
|
|
363
363
|
const { stdout } = await execFileAsync('powershell.exe',
|
|
364
364
|
['-NoProfile', '-NonInteractive', '-Command', command], { timeout: 15_000 })
|
|
365
|
-
|
|
365
|
+
const raw = String(stdout || '').trim()
|
|
366
|
+
// PowerShell 5.1 往 stdout 写的是**控制台代码页**(中文 Windows 上是 GBK 936),
|
|
367
|
+
// 而 Node 按 UTF-8 解码 —— 于是 `D:\微信\xwechat_files` 变成 `D:\��\xwechat_files`,
|
|
368
|
+
// 接着把"与配置是同一份"判成"否",报告就会给出错误的迁移建议(2026-10-19 实测)。
|
|
369
|
+
// 让 PowerShell 先 base64(UTF-16LE)再输出,就与代码页彻底无关了。
|
|
370
|
+
if (!raw || raw.startsWith('{') || raw.startsWith('[')) return raw // 兼容注入的 runner / 老输出
|
|
371
|
+
try {
|
|
372
|
+
return Buffer.from(raw, 'base64').toString('utf16le').trim()
|
|
373
|
+
} catch {
|
|
374
|
+
return raw
|
|
375
|
+
}
|
|
366
376
|
}
|
|
367
377
|
|
|
368
378
|
/**
|