Skip to content

feat: consolidate client upgrades (SSH/Git ops, desktop pet assistant, smart routing gateway) - #2

Open
Jason880902 wants to merge 15 commits into
mainfrom
feat/client-upgrades
Open

feat: consolidate client upgrades (SSH/Git ops, desktop pet assistant, smart routing gateway)#2
Jason880902 wants to merge 15 commits into
mainfrom
feat/client-upgrades

Conversation

@Jason880902

@Jason880902 Jason880902 commented Aug 16, 2026

Copy link
Copy Markdown
Owner

概述

客户端功能升级收拢(相对于当前 main 的净变更)。桌面助手(小珀)已通过 #1 合入 main,本 PR 聚焦:

  1. 客户端左侧菜单运维能力(SSH + Git):侧边栏新增 SSH ops 面板、Git 泳道图面板,以及 LAN 远程预览(手机/平板只读查看工作台,支持 DingTalk 摘要推送)。
  2. 模型路由 API 供应商配置(智能路由网关):设置页新增路由网关配置区块(主模型 + 自动升级模型、上下文压缩上限、apiKey 环境变量/明文),IPC 读写 ~/.config/ipollowork/router-gateway/routing.json 并轮询本地网关状态。
  3. 成熟度加固(来自 DeepSeek Harness review):LAN 预览打包、git graph 异步化、路由网关密钥文件权限。
  4. 模板贡献:把 10 个 slide 风格模板(ipollowork.deck.,源自现代设计语汇:包豪斯/瑞士/蓝图/水墨/玻璃拟态等)与 2 个学术模板(ipollowork.academic.)打入 bundled 模板目录。

验证(已执行)

检查 命令 结果
typecheck pnpm typecheck (apps/app)
apps 单测 bun test graph-layout/ops-utils/settings-route/session-env ✅ 24 pass
desktop 单测 pnpm test (apps/desktop) ✅ 132 pass / 1 skip
模板契约 bun test src/templates.test.ts ✅ 44 pass
维护性审计 audit-changes.mjs ✅ errors=0

DeepSeek Harness review 结论

整体成熟度高于平均,评审发现 3 个高优项已在本分支修复:

  • 🔴 H1 LAN 预览页面未打包(生产构建 "Preview page missing")→ resources/lan-preview/** 已加入 electron-builder files
  • 🔴 H2 git graph spawnSync 同步阻塞主进程 UI → 改为异步 execFile + await
  • 🔴 H3 路由网关 apiKey 明文落盘权限过宽 → writeFilemode: 0o600

模板贡献说明

  • 12 个新模板ipollowork.deck.{bauhaus,blueprint,consulting,dark-tech,editorial-report,glassmorphism,ink-wash,luxury-dark,midcentury,swiss} + ipollowork.academic.{marp-academic,quarto-clean}
  • 已抹除 slide-maker 标识:manifest 的 id/tags/description/source/attribution 与 cover 文案中不残留任何 slide-maker 品牌引用;academic 保留上游 Marp/Quarto 主题署名(版权必需)
  • cover:渲染为 960×540 PNG(满足 bundled 模板契约:唯一哈希、>15KB)
  • 排除:8 个 html-anything 中文版模板未贡献——与官方已存在的 52 个 ipollowork.html-anything.* 目录同名冲突,且官方测试强制 manifest/entry 无中文、png cover;这些官方版已覆盖同一上游(nexu-io/html-anything)

遗留中低优项(不阻断合并,建议后续跟进)

  • PetActivityInput 类型在 desktop-ipc.ts / whale-machine.ts 重复定义且结构不一致(turnCompleted 漂移)——建议以 packages/types 为 canonical 收敛
  • router-gateway parseRouting/serializeRouting 与 whale-machine 状态机缺单测
  • LAN preview challenges Map 无 TTL、SSH 目标未防御 - 开头参数注入、IM 摘要未脱敏路径字段
  • Live2D PIXI Application 从不 destroy()(模板切换泄漏)、pet-companion fetch 无超时
  • 注意:apps/server 的 plugin-package-manifest/lifecycle 测试在 main 上即失败(pet 分支带入的 lark/dingtalk/wecom 插件元数据问题),非本 PR 引入,建议单独跟进

说明

  • 未附带屏幕录像(headless 环境无法运行 GUI),核心路径已由单测覆盖;reviewer 可参考上表命令复现。

本次收敛更新

  • 已合并 main 最新(含上游 design templates / plugin library / marketplace 新功能,以及 macOS 未签名包 ad-hoc 签名修复、types/plugins 打包修复)
  • 已合入 scheduled-tasks 的 4 个 cron 修复与测试(cron 表达式校验、last-run 状态持久化、async fire + 错误状态、cron 引擎测试 15 pass)
  • 关闭了零散 upstream PR feat: add SSH ops panel, Git graph swimlane, LAN remote preview & IM push Devin-AXIS/iPolloWork#341-344,本 PR 为唯一合并入口
  • 本地已验证:dev 版全部功能正常;打包产物覆盖安装到正式版(/Applications/iPollo.app),含 SSH/Git/LAN/智能路由网关/桌宠/定时任务全部新功能

Jovan-zjy added 15 commits August 16, 2026 11:11
Extend the in-session terminal bridge to spawn commands directly
(e.g. ssh user@host), parse ~/.ssh/config for a host list, and add a
sidebar entry ('运维') that opens a multi-session SSH ops panel with
quick-connect input and xterm rendering.
Add a sidebar entry ('Git') that opens a swimlane git graph panel. The
Electron main process gains an ipollowork:git:graph IPC that builds a
commit DAG from rev-list --parents plus ref -> commit mapping from
for-each-ref; the renderer draws an SVG lane layout with branch badges,
commit selection, and a detail pane.
Add a default-off LAN read-only preview server so phones and tablets on
the local network can view the workbench via a pairing flow. The main
process gains a lan-preview-server with 6-digit single-use pair codes,
challenge-based anti-CSRF, in-memory session tokens, per-IP fail lockout
and rate limiting, and a hard 403 on /api/execute (read-only). A new
settings tab (Remote Preview) toggles the server, shows the LAN address
and pair code with countdown, and lists paired devices.
SSH ops + Git graph + LAN preview remediation pass:
- Git graph: detect and surface truncation (rev-list total-count probe,
  truncated banner, dashed stub edges for parents outside the window);
  fix lane layout so sibling branches fork to distinct lanes instead of
  collapsing onto the parent lane.
- LAN preview: raise pair-code entropy (8-char uppercase alphabet,
  ~39.6 bits) and add a global fail lockout with exponential backoff on
  top of per-IP limits.
- Module layout: move ops-panel/git-panel out of domains/session/terminal
  into domain-owned dirs with pure-logic modules (graph-layout.ts,
  ops-utils.ts) instead of dodging the single-file-directory audit rule.
- Main process: extract ssh-ops.mjs and git-graph.mjs factories from
  main.mjs; add preview-core.mjs shared read-only renderer bridge with
  sanitized public summary for LAN/IM channels.
- Tests: node:test suites for ssh config parsing, git DAG building, and
  preview-core redaction; bun:test suites for swimlane layout and SSH
  target normalization.
Add an IM notification section to the Remote Preview settings tab: paste
a DingTalk/Feishu MCP Streamable-HTTP endpoint and push a redacted
workbench summary to the group. The main process gains im-bot.mjs, a
minimal MCP client that discovers a send tool by name (send_message /
sendMessage / send_text / messages_send) and calls it with the sanitized
snapshot from preview-core. No lan-preview session tokens are ever sent.
Includes node:test coverage for tool discovery, argument mapping, and
summary redaction.
…o feat/client-upgrades

# Conflicts:
#	apps/app/src/react-app/domains/settings/shell/settings-page.tsx
…le perms

- Package resources/lan-preview/index.html into the asar so remote preview
  works in production builds (not just dev)
- Run git graph commands async (execFile) so large repos never block the
  Electron main process UI
- Write router gateway routing.json with 0600 perms to protect plaintext
  apiKey from other local users
…ademic

Port the 10 slide-maker presets and 2 academic themes into the bundled
template catalog under the ipollowork.deck.* and ipollowork.academic.*
namespaces. slide-maker branding is stripped from manifests, cover art,
and attribution; covers are rendered to 960x540 PNG per the bundled
template contract. All templates pass the shared theme contract test
(design-tokens.css linkage, token coverage, unique PNG covers).
# Conflicts:
#	apps/app/src/i18n/locales/en.ts
#	apps/app/src/i18n/locales/zh.ts
… scan

- update() now applies lastRunAt/lastRunStatus so runNow records the run
- nextRunAfter parses once and scans at most 4 years to avoid UI stalls on
  never-matching expressions (e.g. "0 0 31 2 *")
…s, async fire with error status

- parseFieldPart now rejects malformed tokens (e.g. 5abc, 1-2x) via strict regex
- create/update reject invalid cron expressions in the main process
- fire() is async, records 'error' status when onFire rejects, drops misleading log text
- 15 node:test cases covering cron parsing/matching/next-run and factory CRUD/tick dedup
- register the suite in the desktop test script
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant