weflow-cli 1.8.0 → 1.8.2

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.
Files changed (41) hide show
  1. package/CHANGELOG.md +176 -1
  2. package/OPERATIONS.md +42 -6
  3. package/README.en.md +3 -3
  4. package/README.md +3 -3
  5. package/bin/weflow-cli.ts +3 -1
  6. package/dist/bin/weflow-cli.js +3 -1
  7. package/dist/bin/weflow-cli.js.map +1 -1
  8. package/dist/src/panel/server.js +1 -1
  9. package/dist/src/panel/server.js.map +1 -1
  10. package/dist/src/services/assistantPrivacy.d.ts.map +1 -1
  11. package/dist/src/services/assistantPrivacy.js +7 -2
  12. package/dist/src/services/assistantPrivacy.js.map +1 -1
  13. package/dist/src/services/assistantService.d.ts.map +1 -1
  14. package/dist/src/services/assistantService.js +10 -1
  15. package/dist/src/services/assistantService.js.map +1 -1
  16. package/dist/src/services/assistantTools.d.ts +12 -0
  17. package/dist/src/services/assistantTools.d.ts.map +1 -1
  18. package/dist/src/services/assistantTools.js +29 -3
  19. package/dist/src/services/assistantTools.js.map +1 -1
  20. package/dist/src/services/wereadService.d.ts +33 -6
  21. package/dist/src/services/wereadService.d.ts.map +1 -1
  22. package/dist/src/services/wereadService.js +27 -2
  23. package/dist/src/services/wereadService.js.map +1 -1
  24. package/docs/BRANCHES.md +13 -4
  25. package/docs/PROJECT_STATE.md +299 -299
  26. package/package.json +1 -1
  27. package/resources/panel/main.cjs +43 -7
  28. package/resources/panel/mascot-thinking.png +0 -0
  29. package/resources/panel/panel.css +424 -407
  30. package/resources/panel/preload.cjs +79 -72
  31. package/resources/panel/renderer.js +470 -441
  32. package/scripts/_utils.py +23 -1
  33. package/scripts/backfill_articles.py +438 -438
  34. package/scripts/compile_wiki.py +18 -17
  35. package/scripts/wiki_lint.py +429 -397
  36. package/src/panel/server.ts +424 -424
  37. package/src/services/assistantPrivacy.ts +7 -2
  38. package/src/services/assistantService.ts +11 -1
  39. package/src/services/assistantTools.ts +33 -3
  40. package/src/services/wereadService.ts +43 -7
  41. package/resources/panel/mascot-focus.png +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "weflow-cli",
3
- "version": "1.8.0",
3
+ "version": "1.8.2",
4
4
  "description": "让 AI 读懂你的微信 — 公众号日报·聊天导出·知识库搜索·MCP Server",
5
5
  "type": "module",
6
6
  "bin": {
@@ -151,6 +151,26 @@ function readEndpoint() {
151
151
  }
152
152
  }
153
153
 
154
+ /**
155
+ * 把端点文件里的 token 种成 HttpOnly cookie。开窗时用一次,**凭据失效时也用它**。
156
+ *
157
+ * 为什么需要"再用一次":token 是**每次守护进程启动新生成**的(`server.ts` 的
158
+ * `generateToken()`),而窗口的 cookie 是打开那一刻种下的。所以 `assistant stop/start`
159
+ * 之后,一个还开着的窗口手里是**死凭据**:`/api/status` 回 401、静态资源(球的脸图,
160
+ * `Cache-Control: no-store`)也回 401 —— 表现是**球变成空白**,而窗口本身看着还在。
161
+ * 2026-09-28 实测:窗口比守护进程早 25 小时,图标就是这么没的。
162
+ */
163
+ async function applyEndpointCookie(endpoint) {
164
+ await session.defaultSession.cookies.set({
165
+ url: `http://127.0.0.1:${endpoint.port}`,
166
+ name: COOKIE_NAME,
167
+ value: endpoint.token,
168
+ httpOnly: true,
169
+ sameSite: 'strict',
170
+ })
171
+ }
172
+
173
+
154
174
  function errorPage(message, hint) {
155
175
  const html = `<!DOCTYPE html><html lang="zh-CN"><head><meta charset="utf-8">
156
176
  <style>body{margin:0;height:100vh;display:flex;flex-direction:column;justify-content:center;
@@ -202,13 +222,7 @@ async function buildWindow() {
202
222
  await win.loadURL(errorPage('助手没在运行', '先在终端跑一次 weflow-cli assistant start,再打开本机面板。'))
203
223
  } else {
204
224
  // token → HttpOnly cookie → 然后才 loadURL。**token 不进 URL、不进 argv、不进渲染进程。**
205
- await session.defaultSession.cookies.set({
206
- url: `http://127.0.0.1:${endpoint.port}`,
207
- name: COOKIE_NAME,
208
- value: endpoint.token,
209
- httpOnly: true,
210
- sameSite: 'strict',
211
- })
225
+ await applyEndpointCookie(endpoint)
212
226
  await win.loadURL(`http://127.0.0.1:${endpoint.port}/panel`)
213
227
  }
214
228
 
@@ -422,6 +436,28 @@ if (!app.requestSingleInstanceLock()) {
422
436
  })
423
437
  ipcMain.handle('panel:dragEnd', () => { dragOrigin = null; return null })
424
438
  ipcMain.handle('panel:info', () => ({ daemonRunning: !!readEndpoint(), endpointFile: ENDPOINT_FILE }))
439
+ /**
440
+ * 凭据失效时自愈:重读端点文件(守护进程每次启动都换 token),刷新 cookie 并重载。
441
+ *
442
+ * 触发者是页面(它先看到 401)。**两种"不修"要说清**,否则会把故障换成另一种故障:
443
+ * - 端点文件里的 token 与现有 cookie **一样** → 401 不是凭据过期引起的,别重载(否则
444
+ * 页面在别的原因 401 上无限重载);
445
+ * - 端点文件读不出来(守护进程没跑)→ 也别重载,那会把"助手没在运行"的提示刷掉。
446
+ * 再加一道 5 秒节流兜底:**重载风暴比空白球更难排查**。
447
+ */
448
+ let lastRepairAt = 0
449
+ ipcMain.handle('panel:repair', async () => {
450
+ if (Date.now() - lastRepairAt < 5000) return { ok: false, code: 'TOO_SOON' }
451
+ lastRepairAt = Date.now()
452
+ const fresh = readEndpoint()
453
+ if (!fresh) return { ok: false, code: 'DAEMON_DOWN' }
454
+ const url = `http://127.0.0.1:${fresh.port}`
455
+ const current = (await session.defaultSession.cookies.get({ url, name: COOKIE_NAME }))[0]
456
+ if (current && current.value === fresh.token) return { ok: false, code: 'SAME_TOKEN' }
457
+ await applyEndpointCookie(fresh)
458
+ if (win && !win.isDestroyed()) win.webContents.reload()
459
+ return { ok: true, code: 'RELOADED' }
460
+ })
425
461
  ipcMain.handle('panel:quit', (_event, what) => {
426
462
  app.isQuitting = true
427
463
  if (what === 'assistant') spawnCli(['assistant', 'stop', '--yes', '--json'])