jkooe
|
9b6b063e2b
|
docs: 更新 README 单测计数为 483
|
2026-11-03 20:33:36 +08:00 |
|
jkooe
|
0b858bb343
|
docs(changelog): 记录本轮四项遗留修复 + 单测数 477→480
- CHANGELOG [未发布] 补:依赖彻底清零、看门狗日志轮换、L2 参数常显、
e2e 子进程兜底清理;
- README 单测数同步 480(docs-numbers 守卫强制耦合)。
|
2026-10-27 08:04:33 +08:00 |
|
jkooe
|
9baf3b0443
|
fix(cli): rollback 指纹校验容忍 12/64 位两种口径
QA 独立验证路由的 P0 缺陷(tests/unit/qa-v210-supplement.test.mjs C⑦ 红):
- 写后校验(rollback.ts:462):back.hash 是 64 位流式 sha256,而老 LKG 记录的
expectHash 只有 12 位(无 hash_full)→ 严格 === 必不成立 → 老记录回滚永远
被判「写后校验失败」并用回滚源还原,向后兼容路径实际不可用。
- 重启复核(rollback.ts:519):新 LKG 记录带 hash_full(64 位)时,p.buildHash
是 12 位 → 严格 === 必不成立 → 回滚其实成功却被误报「90s 内未复核到回滚版本」
并以退出码 1 结束(--backup 逃生门同样命中此缺陷)。
修法:新增纯函数 hashMatchesEither(短的一方是长的一方前缀即命中),仅用于
「校验/复核」方向;挑回滚源仍用单向 hashMatches —— hash_full 在手时不许前缀
糊弄(C⑥ 钉死),两条语义各有其守卫。
README 单测数 476 → 477(新增 hashMatchesEither 用例,docs-numbers 守卫强制耦合)。
|
2026-10-26 21:00:26 +08:00 |
|
jkooe
|
dadd861fdd
|
test: QA 补充用例(代理重定向/NO_PROXY 组合、看门狗边界与恢复日志、rollback 双匹配路径、README 数字精度)
- A:httpGet 重定向链经代理逐跳绝对形态+共享预算;maxRedirects 上限边界;
NO_PROXY 命中直连/端口不匹配不误短路/miss+死代理大声报错(agent-proxy 已有
单跳经代理与直连重定向预算,组合形态空缺)
- B:看门狗宽限期精确边界(livedMs === STARTUP_GRACE_MS 按运行期不计数);
无指纹匹配时恢复日志须带回候选指纹且 install-dir 不动
- C:pickBackupByHash 在 hash_full 在场时不许仅凭 12 位前缀命中;
编排层老 LKG(无 hash_full)端到端前缀回滚 —— 后者当前为红,是路由给
工程师的 P0 缺陷(rollback.ts:462 全量 64 位指纹与 12 位 targetHash 严格
比较,详见缺陷单),修复后自绿
- D:README e2e 拆分口径(34 通用 + 16 Windows 专属按文件分别核对);
命令速查必须含 nodeagent rollback [--dry-run]
- README 单测数 467 → 476(docs-numbers 守卫强制耦合,非手滑)
|
2026-10-26 01:22:55 +08:00 |
|
jkooe
|
0074d09f08
|
docs: v2.1.0 收口回填(README/CHANGELOG/DEVELOPMENT/ROADMAP + 数字守卫)
- README:数字刷新为实测(52 能力 · 42 MCP · 467 单测 · 50 e2e · 23 Rust);
补 na_audit_l2 工具表项、看门狗三端接入段;删「控制台安装包只作为
CI artifact」过期行(9f95560 起已随 Release 发布)。
- CHANGELOG:[未发布] 定稿 v2.1.0 全部主题(rollback / 看门狗 /
na-gui 清理 / e2e 与文档收口),与 A 线已回填段共存无重复。
- DEVELOPMENT:新增 §7.5 selfupdate 代理出网机制(NA_PROXY→环境变量→
系统代理、PAC/socks5 明确报错、回环恒直连、计划任务环境变量告诫);
§7.4 补 rollback/看门狗双通道分工表与「为什么运行期不做自动回滚」
三问引述。
- ROADMAP:新增第十节 —— v2.1.0 已落地项划掉、P2 登记(控制台自更新
v2.2.0 / Linux auditd / macOS ESF / macOS 安装器 / guard 日志轮换)。
- tests/unit/docs-numbers.test.mjs(新,6 例):README 五个数字与可
复现实测口径钉死(manifest 条目 / defs.ts 工具 / node --test 实测 /
e2e 源码 / Rust 属性),「增能力不改 README」即红。单测数实测经
NODE_TEST_CONTEXT 剥离 + NA_DOCS_NUMBERS_CHILD 递归防护;注入故障
(52→53)实测 2 处守卫变红、恢复全绿。
|
2026-10-26 01:01:19 +08:00 |
|
jkooe
|
6b2fa29710
|
feat(cli): nodeagent rollback —— 从 LKG 回滚被控端(ARCH T03 / PRD P0-2)
- 新增 apps/cli/src/cmd/rollback.ts:读 LKG → 指纹比对定位备份 →
覆盖写入口(同 deploy 姿势)→ 写后校验(失败用回滚源还原)→
受控重启 → probeOnce 复核 build.hash == LKG(90s 墙钟)
- 纯函数 planRollback/pickBackupByHash/hashMatches/backupNameRegex +
流式 hashRemoteFile(client 注入,可假测);hash_full 全量优先、
老记录回落 12 位前缀(A-P0-3/R-2 向后兼容)
- --dry-run 只读零写;--backup 逃生门直指备份路径;退出码 0/1/2 分明
- HELP/README 写明能力圈边界:RPC 命令需被控端可达,「完全起不来」
走看门狗自动恢复或带外恢复;不提供自动回滚(DELIVERY-PIPELINE §6)
- 19 条单测:无 LKG 零调用 / already-lkg 零写 / 写后校验失败自动还原 /
无匹配零写 / dry-run 只读 / 多候选 mtime 新→早 / Windows 路径与元字符
|
2026-10-25 23:45:02 +08:00 |
|
jkooe
|
b9236dfaf1
|
chore(privacy): 公开仓库隐私脱敏 —— 清除可定位到个人与设备的字面量
按 security-reports/ 的隐私审查台账逐项收口。纯脱敏与表述泛化,
不含任何业务逻辑变更;实测结论与排查步骤一字未动。
P1(可定位到具体设备/个人)
- scripts/verify-b2.mjs:NA_URL 去掉硬编码缺省值(原指向一台真实机器),改为必填。
这是全仓库唯一「拿着就能连到某台真机」的常量。
- 测试账户名 pdverify → na-test(docs/VM-VERIFICATION.md 7 处、docs/console-plan.md 1 处)
- 虚拟机与宿主的真实网段 → RFC 5737 文档保留段 192.0.2.x(含 CLOSE_WAIT 记录)
- 跨项目名与私人称呼 → 中性表述(docs/PRD.md、docs/DEVELOPMENT.md、docs/console-plan.md 等)
P2(低风险设备指纹)
- 虚拟化产品及其 CLI / 访客工具名 → 中性表述(12 个文件 + 1 个工作流注释)
- 测试目录 C:\nodeagent-test → C:\na-test
- NAS 设备型号与系统名 → NAS 设备 / NAS 系统(docs/DEPLOY-LINUX.md、scripts/install-linux.sh、README.md)
- 真机 CPU 型号、真机物理分辨率、代理软件品牌与监听端口、杀软品牌 → 泛化
- 单元测试示例段去掉真机 IP 尾八位:acl-v11 / net-scripts 的 fixture 与断言同步更新
- .gitignore 补 config.json / agent.json(含真实密钥与节点地址,绝不入库)
- 顺带移除混入技术文档的「不构成投资建议」字样(与文档主题无关)
验证:pnpm test:unit 340/340 通过;独立扫描器对 235 个跟踪文件做 17 类模式
全量扫描,命中 0。
|
2026-10-13 22:35:40 +08:00 |
|
jkooe
|
00992e5c1c
|
feat(linux): Linux 被控端适配 —— 安装器 + systemd 自启 + 平台守卫 + 部署文档
面向「服务器型被控端」(命令/状态/文件/审计;无 GUI),实测环境 Debian 12(fnOS 底座)。
## 新增
- `scripts/install-linux.sh`:一键安装器(对齐 Windows `install.ps1` 的语义)
· 自动获取 Node 运行时(系统无 Node 22+ 时下载 linux-<arch>,走 npmmirror)
· **systemd 服务**(系统级 / 用户级+linger / `--no-service` 三种模式),开机自启
· 幂等:复用既有密钥(并自动备份 agent.json);卸载保留配置(`--purge` 才删)
· `--node-id/--port/--allow-input` 等参数;缺 `ip`/`ifconfig` 时 IP 展示多级回退
- `apps/agent/src/util/platform.ts`:**统一平台守卫**
· `assertPlatform(cap, ...allowed)` / `assertGuiPlatform` / `assertWindows`
· 抛 `E_UNSUPPORTED_PLATFORM` 并带上「支持哪些平台」,让"未实现"不再伪装成"参数错/环境缺依赖"
- `docs/DEPLOY-LINUX.md`:部署指南 + **实测能力清单** + 故障排查表
## 修改
- `screen.ts` / `record.ts` / `clipboard.ts` / `audio.ts` / `input.ts`:入口接入平台守卫。
修复前的表现是**误导性错误**(`screen.capture` 在 Linux 上报 `region 宽高必须 ≥ 1`,
像是参数没传对),现在是 `screen.capture 未在 Linux 上实现(仅支持 Windows / macOS)`。
- `scripts/verify.mjs`:v2.1 / v2.3 补 `E_UNSUPPORTED_PLATFORM → skip`
(v2.2 早已处理;此前把"平台不支持"记成失败)
- `README.md`:文档区链入 DEPLOY-LINUX
## 实测(Docker · Debian 12)
- 安装流程端到端:装文件 → 写配置(600) → 提取密钥 → 启动监听 → **幂等复装密钥不变** ✓
- 验收:**9 通过 / 1 失败 / 6 跳过**(对比 macOS 15/0/1)
· 1 失败 = 容器缺 `procps`(`process.list` 返回空),非代码问题;NAS 自带该包
· 6 跳过 = GUI 类能力(平台诚实拒绝)
- 单元测试 325 全绿;7 包构建通过
## 途中修正的三个"差点误判"
1. **Alpine 误判**:`spawn /bin/bash ENOENT` 是**镜像没 bash**,不是 Linux 不支持
2. **`set -e` 静默退出**:`LAN_IP=$(ip ...)` 在无 `ip` 的环境失败会**直接终止脚本**
(`2>/dev/null` 把原因吞了,表现为"跑到一半就没了")→ 已改多级回退
3. **slim 镜像缺 procps** → `process.list` 空列表,被误读为"Linux 特性"
|
2026-10-13 21:15:59 +08:00 |
|
jkooe
|
c20e71bddc
|
docs: 补齐 Windows 端控制台文档(含三次 run 的失败-修复-实证全过程)
README / CHANGELOG / docs/console-plan.md 三处同步:
- README:补 Windows 双架构安装包实测体积、第三条断言(解开安装包查内容)、
以及实测解出的 node.exe 体积与 PE Machine。
- CHANGELOG:新增「Windows 端控制台安装包」整节,含双架构理由、
为什么用原生 ARM runner、cfg!(windows) 分支首次被编译器看到、
以及三次 run 的完整过程(体积断言写错 → `&` 调 GUI 程序不等待 → 双绿)。
- docs/console-plan.md:断言表 2 条 → 3 条;新增三节实测记录;
产物形态表补实测体积;8.2 指标验收的「Win 安装包 < 40MB(待实测)」补上实测值。
另修复:`## 界面观感约定(2026-10-11)` 标题被上一轮编辑误吞
(正文直接从「两轮纯界面调整」开始),已恢复。
留下两条可迁移教训:
1. 体积阈值属于「中间逻辑自洽」式断言 —— 判据要落在产物内容上;
且压缩容器与未压缩目录的体积不可直接比。
2. `msiexec.exe` / NSIS 安装包是 GUI 子系统程序,PowerShell `&` 调用
既不等待也不设 $LASTEXITCODE → 必须 Start-Process -Wait -PassThru。
|
2026-10-12 00:20:50 +08:00 |
|
jkooe
|
2528f6b709
|
docs: 归档「控制台去命令行化」—— CHANGELOG / console-plan / README
CHANGELOG:新增 [未发布] 章节,并按「刻意不升版本号」写明理由 ——
本轮新增的全是控制台功能,被控端能力集合未变;而 bundle-agent.mjs 会把根
package.json 的 version 注入 agent.mjs(__AGENT_VERSION__),
一旦为控制台功能升号,被控端就会谎报一个它并未包含的版本。故维持 2.0.2。
console-plan:新增「本机服务托管」章节,含需求逐条落点对照表、
消灭命令行窗口的三条措施、四条实测踩出来的约束、播种防降级的规则、
「不靠单一信号判实例在跑」的交叉判定、以及仍需图形环境人工实点的清单。
README:控制台页面表 7 → 9(补「本机服务」与「服务日志」),
打包命令改为 pnpm --filter nodeagent-console bundle,
体积数字修正 —— 原文写的 .app ≈ 6.8 MiB 是 Node sidecar 方案之前的旧数,
现为 .app 90.8 MiB / .dmg 33.78 MiB,并补「无需预装 Node」「自启与图形能力
要求登录用户会话」两条注意事项。
|
2026-10-11 11:42:27 +08:00 |
|
jkooe
|
9ae1326be2
|
docs(readme): 版本基线更新到 v2.0.2
v2.0.0(10-10)那条基线已过期。现基线:v2.0.2(2026-10-11,资产修复 ——
v2.0.1 的 arm64 包内实为 x64 node),51 项能力 · 274 单测(本地实跑全绿)。
|
2026-10-11 10:45:48 +08:00 |
|
jkooe
|
ba57d99806
|
docs: 新增 VM 验证清单(Parallels 27 + Win11 ARM)—— 真机不可用时的替代路径
## 背景
Windows 被控端离线导致 4 项验证卡住(v1.5 四项 / v23 三防护 / v26 清理 / 锚点端到端)。
Parallels Desktop 27 可跑 **Windows 11 ARM** 虚拟机(Apple silicon 只支持 ARM 版 Windows,
x86_64 仅 Pro/Business 的早期预览),可提前跑掉**架构无关**的验证项。
## 清单内容(docs/VM-VERIFICATION.md)
- **能补 / 不能补的矩阵**:协议层与输入层可验;**杀软交互、显示/DPI、性能指标不可替代**
- 前置准备:桥接网络(否则 UDP 广播发现测不了)、优先 ARM64 Node、run-portable/install 二选一
- **逐条命令**(均已对着源码核实参数):
- A 基础验收:直接复用既有 `scripts/verify.mjs`(17 项 + Markdown 报告)
- B1 v1.5 四项:`key press "ctrl+shift+esc"` / `copy` / `--hold 800` / `--route post --pid N`
(对应 args 的 hotkey / preset / hold_ms / route+target_pid 四个分支)
- B2 v23 三防护:`agent.json` 的 `security.auth_ban` 与 `idle_timeout_ms` + 三场景判定
- B3 v26 清理:`restart` 后 `schtasks /query`,**重点看"当前宿主任务必须仍在"**(否则即误杀)
- B4 锚点端到端:`anchor-audit.mjs collect` → 云盘 → `verify`
- B5 额外结论:**win-x64 包在 ARM Windows 上能否跑**(走 Prism;跑通则写进 README)
- **结论标注规则(强制)**:VM 验过的写「VM 已验」;杀软/显示/性能**不得**因 VM 通过就标已验;
并注明「VM 与真机架构不同(真机 x86_64),VM 通过不自动推出真机通过」
- **已知 VM 环境差异表**(排查先看):广播发现需桥接、坐标为逻辑验证、性能数字不可采信等
README 文档区与 ROADMAP §九 均已链入。
|
2026-10-10 23:38:02 +08:00 |
|
jkooe
|
53bf5a0634
|
feat(console)!: Rust 壳改用 Node sidecar(选项 D 完成)—— 退役 crates/nodeagent-client
## 动机(消除「两套协议实现」)
原设计让 Rust 壳自己实现 client,与 TS 版(@nodeagent/client)并存 → 改一处漏一处时
构建过、单测过,只在真机暴露。现 Rust 壳只做**进程管理 + 消息转发**,协议实现只剩 TS 一份。
## ④ Rust 壳改造
- 新增 `src-tauri/src/sidecar.rs`(~290 行):Sidecar 管理器 —— spawn node、
行分隔 JSON-RPC 的请求/响应匹配(oneshot + 超时兜底)、通知回调(state/log/agent_event)、
`resolve_node`/`resolve_sidecar` 路径解析(env → Tauri resource → 开发期系统 node)
- 重写 `lib.rs` 为薄转发层:`ensure_sidecar` 懒启动;**5 个 command 签名与 3 个 event 名
(na-state/na-log/na-event)一律不变 → 前端零改动**;`get_capabilities`/`get_state`
读本地缓存以**保持同步签名**;`RunEvent::Exit` 时优雅 shutdown(kill_on_drop 兜底不留孤儿)
- `Cargo.toml`:移除 nodeagent-client 依赖、加 tokio;**版本 0.1.0 → 2.0.0**
(原先与 tauri.conf.json 的 2.0.0 不一致,属版本号统一范围)
## ⑤ 打包配置
- `tauri.conf.json`:`bundle.resources` 声明 sidecar.mjs 与 node;
`beforeBuildCommand` 串上 `sidecar:build`(否则 resource 缺失)
## ⑥ 退役
- 删除整个 `crates/`(12 文件,含 nodeagent-client 与其 probe 示例)
- `rust.yml` 由「Rust client 单测」改为「**Rust 壳单测(真跑 sidecar)**」:
装 Tauri 系统依赖 + Node + pnpm,跑 clippy `-D warnings` 与 `cargo test`
- `package.json`:`test:rust` 改指 console 壳;移除 `probe`
(其「对真机逐项核对字段」的用途已由 CLI `nodeagent invoke` 覆盖)
- 引用清理:README(数字与协议客户端说明)、console 前端两处注释、
console-plan(开头加「原方案已被取代」提示 + 补改造详情)、ROADMAP 历史描述加退役批注
## 验证
- **`cargo test` 3/3 通过**(真跑 Node sidecar 子进程:spawn/请求-响应/错误不崩)——
这是关键:sidecar 管理器**不依赖 Tauri GUI**,故核心逻辑可在 CI 真实验证,不必等人工开窗口
- `cargo check` 零警告;clippy 标准与 CI 一致
- 273 单测 / 7 包构建 全绿
- ⚠️ **仍需人工验证**:Tauri GUI 端到端(开窗口 → 连被控端 → 点界面),沙箱跑不了图形应用
|
2026-10-10 15:16:24 +08:00 |
|
jkooe
|
e23788d717
|
refactor(versioning): 统一版本号 —— semver 为唯一版本号,开发批次代号并入其归属版本
## 问题(皇上指出)
项目里两套编号并行,无法判断哪个是"当前版本":
- **发布版本**(semver):v1.1.0 ~ v1.6.0、v2.0.0
- **开发批次代号**:v1 ~ v26(README 路线表 / 代码注释 / 文档)
时间线证据:v1.1.0 首发(09-29)时批次已推进到 v12.4 —— **二者从来不是一对一**(26 批次只发过 10 版)。
## 规则(新增 docs/VERSIONING.md §0 版本号唯一性规范)
- **唯一版本号 = semver `vX.Y.Z`**,两个来源必须永远一致:git tag 与 package.json(构建期注入 agent)
- **批次代号不是版本号**,不再单独出现;需要区分同版内多批改动时用**功能名**
- 附「批次 → 归属发布版本」映射表(按 tag 时间线与功能内容推定,并注明以 CHANGELOG 为准)
## 统一动作
1. **批次 v23 ~ v26 → v2.0.0**(22 文件 / 53 处)—— 它们确实属于 v2.0.0
2. **臣的批次号 v1.7 / v1.8 → v2.0.0**(27 文件)—— 未单独发版
3. **简写补全三段式**:v1.5 → v1.5.0、v1.6 → v1.6.0
4. **README 路线表**:`**v1**` → `**批次 1**`;表头加「批次 ≠ 版本号」说明并链到 §0;
补齐批次 16~29 与 **v2.0.0 发布行**;删掉过时的「待办」行(提到的分支早已删除)
5. `docs/VERSIONING.md` 里**故意保留** 3 处批次号 —— 那是规范说明本身
## 保留项(真实发布版本,不动)
v1.1.0 / v1.2.1 / v1.3.0 / v1.4.0~v1.4.3 / v1.5.0 / v1.6.0 / v2.0.0(10 个 tag)
## 验证
- 版本号一致性:package.json = tag = 8 个 workspace = tauri.conf.json = **2.0.0** ✓
- v1.7/v1.8/v23~v26 全仓残留 **3 处**(均在 VERSIONING.md 规范说明中,属预期)
- 7 包构建 · 单测 273 · e2e 30 · ps1-encoding 24 全绿
|
2026-10-10 14:27:12 +08:00 |
|
jkooe
|
5b69d6cec9
|
refactor: 项目结构与命名规范化(重写前的最后一次常规提交)
## 改名
`scripts/run-temp.cmd` → `scripts/run-portable.cmd`
理由:它是**正式功能**(免安装、免管理员的便携启动方案),"temp" 易被误认成临时文件。
程序内文案同步:TEMPORARY launcher → PORTABLE launcher;
打包产物 README 的"【临时试用,不装也行】" → "【免安装试用,不装也行】"。
## 移动
`PRD.md` → `docs/PRD.md`
理由:文档统一放 docs/(README/CHANGELOG 按惯例留在根)。
## 同步的引用(共 11 处)
- scripts/pack.mjs:产物文件名校验 + 生成 README 的 3 处指引文案
- scripts/run-portable.cmd:自身用法注释 6 处
- README.md:目录树 + 文档链接
- docs/DEVELOPMENT.md:配套文档链接(`../PRD.md` → `PRD.md`,现已同目录)+ 目录树
## 验证
- 全仓 `run-temp` 残留 **0**;`./PRD.md`/`../PRD.md` 旧路径残留 **0**
- 7 包构建通过;单测 273 全绿;ps1-encoding 24 全绿
- `pack.mjs` 实跑通过,`run-portable.cmd` 已正确进入 Windows 产物
- `.cmd` 保持 ASCII + CRLF(94 行);PRD.md 无内部相对链接需调整
|
2026-10-10 13:39:42 +08:00 |
|
jkooe
|
01e711be77
|
docs: 新增 CHANGELOG(项目此前没有变更日志)
自 v1.6.0 起累计 33 个未发版提交,按 Keep a Changelog 结构整理:
新增(语义可断言 / 状态可回看 / 安全加固三批)→ 修复(五处只有真机能暴露的严重缺陷 +
其他)→ 安全隐私 → 文档。并补记 v1.6.0 / v1.5.0 历史条目(含该版未经真机验证即发布、
|
2026-10-10 00:40:36 +08:00 |
|
jkooe
|
dfd3b2349e
|
docs: README/ROADMAP 同步至 v26(能力 51 / MCP 41 / 单测 269 / Rust 9)
README:
- 能力总览补三行(GUI 等待 / 状态采样 / 审计锚定)
- 数字行 43→51 项能力、38→41 个 MCP 工具、215→269 单测、11→9 Rust 单测(实测)
- gui.await 章节补「属性谓词与组合」(where 四属性表 + any_of 示例 + 引擎限制说明)
- 新增两章:状态采样(log.query + monitor)、审计链外部锚定
ROADMAP:
- 头部基线刷新(269 单测 / 51 能力 / 未发版提示)
- §九 台账补 10-09~10-10 的语义 / 状态 / 安全三方向收尾(含 SECURITY §5 清单全部完成)
- 新增「真机验证抓到的 8 个真 bug」表,便于后续复盘
|
2026-10-10 00:29:39 +08:00 |
|
jkooe
|
d065242413
|
docs/ci: README 数字校正 + checkout 升 v5
- README:统计口径已过期(43 能力 · **32** MCP 工具 · **114** 单测 · **26** E2E),
校正为实测值:43 能力 · 38 MCP 工具 · 215 单测 · 30 E2E · 11 Rust 单测。
另补「桌面控制台」小节(架构图、页面表、构建命令、平台门控说明)与构建步骤说明
—— 新组件入库后不同步 README,读者会以为仓库里没有它。
- CI:actions/checkout@v4 → v5,消除 runner 上的 Node.js 20 弃用告警。
仅升被标记的这一个;setup-node / pnpm-action 未被标记,不做未验证的连带升级。
|
2026-10-07 10:18:52 +08:00 |
|
jkooe
|
2eb33587fe
|
feat(v1.6): 新增 gui.await 等待条件能力(复盘短板之「语义」)
把 GUI 操作从「按一下→睡几秒→截图碰运气」变成**可断言**:四类条件
window / control / process / file,各复用 window.list / screen.find /
process.list / fs.stat(零新平台代码,平台行为与既有能力一致,只读低危)。
- present/absent 两种等待;超时正确返回 satisfied:false + note
- 轮询期单次异常**不视为失败**(启动中程序常短暂报错),超时才带回 last_error
- 参数非法分两层拒:schema 层(协议错误)与业务层(E_PARAM_INVALID)
本地真实验证(macOS,7 项全过):present 命中(1208ms/7 次轮询)、absent 命中、
超时返回、非法参数 2+1 拒绝、process 命中、底层报错不中断轮询(last_error 带回
辅助功能权限提示)、缺省参数可用。
能力数 42 → 43(数量守卫测试同步更新);README 补快捷键与 gui.await 用法章节。
|
2026-10-07 01:21:41 +08:00 |
|
jkooe
|
689bb8c98d
|
feat(v1.5): 快捷键控制范围扩展 —— 字符串热键 / 预设别名 / 长按 / 后台定向投递
## 背景
原 `input.key.press` 只接受数组和弦(keys/sequence),按键表也不全:
AI/MCP 调用要拼 ["ctrl","shift","esc"],且 **win+d、ctrl++、win+. 这类
"修饰键 + OEM 符号键"的组合根本打不出来**(表里没有符号键)。
## 四类扩展
① **字符串热键**:`hotkey: "ctrl+shift+esc"`、`hotkeys: ["ctrl+c","ctrl+v"]`
—— 分隔符支持 `+ - 空格`,大小写不敏感,别名归一(command/cmd→win、del→delete…)
② **预设别名**:约 50 个语义名(copy / show_desktop / task_manager / screenshot /
volume_mute_toggle…),AI 调用免记键位;`preset` 与 `presets`(序列)均支持
③ **长按** `hold_ms`(≤5s):按下→保持→释放,插在"按完"与"释放"之间
④ **后台定向投递** `route=post` + `target_pid`:向目标进程**全部顶层窗口**
PostMessage WM_KEYDOWN/UP —— 目标窗口被遮挡/最小化时可用
(媒体键的 WM_APPCOMMAND 机制早已验证,此为其等价物)
文档明示局限:游戏/部分输入型程序不响应后台键消息
## 按键表补齐(单测覆盖断言防漂移)
- 左右侧修饰键 lctrl/rctrl/lshift/rshift/lalt/ralt/lwin/rwin(游戏常区分左右)
- 小键盘 numpad0-9 + 四则运算,**与数字键分开**(Excel 靠 NumLock 区分)
- OEM 符号键 oem_1..oem_8 / oem_minus/plus/comma/period(解锁 win+d、ctrl++、win+.)
- 浏览器收藏夹/主页、系统键(sleep/help/select/execute/clear/separator/oem_clear)
- IME 键(kana/hangul/kanji/hanja/convert/nonconvert/accept/modechange)
- 补齐 pause/apps(重构时一度漏掉,被覆盖断言测试立刻抓到)
## 可测性重构
脚本生成抽成**纯函数** `apps/agent/src/capabilities/input-script.ts`
(VK_MAP / MEDIA_COMMANDS / toVk / build{Media,Foreground,Post}Body),
行内生成逻辑全部改为调用 —— 于是**按下顺序/逆序释放/hold 插入位置/post 路由**
这些最容易写错的部分,现在由 14 个单测逐行断言,真机只需验证最终效果。
## 参数校验
protocol `expandChords()` 统一展开六种输入形式,**混用即报错**(消除"以谁为准"歧义);
同一和弦重复修饰键、超 4 键、空输入均拒绝。渲染返回值新增 presets/via/channel/sent_windows。
## CLI / MCP
- CLI:`nodeagent key press "ctrl+shift+esc"` / `key press copy` / 老形式 `key press ctrl c`
新增 `--hold`、`--route`;回显预设展开与后台投递命中窗口数
- MCP `na_key`:同步支持 hotkey/hotkeys/preset/presets/hold_ms/route/target_pid
## 验证
- 单测 **179 → 195**:hotkeys 解析与别名 17 例、**脚本生成逐行断言 14 例**、
按键覆盖断言(HOTKEY_KEYS ⊆ VK_MAP)、新参数 schema 校验 2 例
- e2e **29** 全绿
- ⚠️ **真机未验证**:Windows 被控端当前离线(连接超时)。待上线后需验:
`key press "win+d"`(切桌面再切回)、`key press copy` 配剪贴板、
`route=post` 定向一个最小化窗口。验证通过后再发版。
|
2026-10-07 00:59:40 +08:00 |
|
jkooe
|
0d59d6032b
|
feat(v21): 第一批安全加固 —— 证书指纹钉住 + 来源网段白名单
对应审查建议的 P0 两条:这两项是**真实可利用的攻击路径**,其余(发现最小化/失败封禁等)
留待后续批次。
## ① 证书指纹钉住(TOFU)—— 挡同网段中间人
自签证书没有 CA 链,历史上客户端只能 `insecure` 接受任意证书 → 攻击者可**透明中继**:
拿不到钥匙(挑战-应答挡得住冒名),但能读到截屏/剪贴板/键入/exec 输出。
- 被控端:`install.ps1` 打印证书指纹(sha256 of DER)供**带外核对**;
`system.info.build.cert_sha256` 与 `auth_ok.build.cert_sha256` 上报
- 控制端:首次连接自动钉进 `nodes.<名>.cert_sha256`;之后**严格比对**,
不一致即 `E_CERT_MISMATCH`(-32422) 拒连,并提示 `--forget-cert` 重钉
- 额外做**交叉确认**:实际握手证书 vs auth_ok 自报,不一致同样拒绝(防自报被篡改)
- 指纹基于 **DER**(不是 PEM 字节),保证与 Windows .NET `GetRawCertData()` 同值
**踩坑记录(写进代码注释,避免后人重走)**:
1. `ws` 客户端的 `upgrade` 事件**只传 IncomingMessage**,拿不到 socket
2. socket 要在 `open` 之后从 `ws._socket` 取(TLSSocket)
3. Node ≥15 的 `getPeerCertificate()` 返回**对象**,DER 在 `.raw` 上(老版本才是 Buffer)
—— 现已双兼容
## ② 来源网段白名单 `allow_from` —— 收敛暴露面
被控端默认监听 `0.0.0.0`(远程接入所需),但**换到不可信网络就自动暴露**。
- 支持 CIDR / 单 IP / `*`;**未配置 = 放行全部**(保持向后兼容,不打断现有部署)
- 拒绝发生在**业务握手之前**(不做 TLS/挑战应答,省资源),并记 `net.deny` 审计
- 判定按**前缀比特**而非字符串相等:Node 在 IPv6 监听上把 IPv4 客户端报成
`::ffff:a.b.c.d`,已归一化(单测覆盖)
- `system.info.network.allow_from` 上报状态;`nodeagent info` 一眼看出是否已收敛
## 验证(本地真跑,非纸面)
- 白名单不含本机 → 连接被拒(agent 侧 WARN + 审计留痕)✓
- 白名单含本机 → 连上,并**自动钉住**指纹 ✓
- **换掉被控端证书后重连 → `E_CERT_MISMATCH` 拒绝**(期望 2ed4957b… / 实际 ca8dc20c…)✓
- 新增 e2e 用例(自起 TLS agent)覆盖上述四种情形 + agent 自报与实际证书一致性 ✓
- 新增单测 9 例(CIDR 前缀匹配 / IPv4-mapped 归一 / IPv6 zone / PEM≡DER / 篡改即变)
- 全量:单测 **159**(150→159)· e2e **29**(28→29)全绿
## 文档
新增 `docs/SECURITY.md`:信任模型(钥匙=root)、认证现状与**已知限制**(ACL 身份维度仅在
ed25519 有效)、本次两项加固的用法、尚未收敛的 6 项、应急处置表。
|
2026-10-05 02:25:19 +08:00 |
|
jkooe
|
cedc46d090
|
feat(v20): 版本纪律 + 发版自动化(对齐「做好版本功能 + GitHub 同步资产」)
## 一、版本功能(防新旧混用)
1. **单一版本源 + 构建注入**:根 package.json 的 version、git sha、构建时间经 esbuild
`--define` 注入 agent;`system.info.build` 新增 `version/commit/built_at`(原有 `hash` 指纹不变)。
开发态用 typeof 探测(未注入也不崩)。
2. **握手携带版本**:`auth_ok` 新增可选字段 `agent_version` / `build` / `protocol`(只增不减 → 旧控制端忽略即可)。
3. **能力级兼容比对**:新增纯函数 `capabilityDiff(local, remote)` ——
- `missingOnRemote`:本地有远端没有 → **远端较旧**,提示更新被控端
- `unknownLocally`:远端有本地没有 → **本控制端较旧**(不影响既有功能)
控制端不比版本号而比**能力集合**:版本号可能相同而内容不同,能力集合不会骗人。
4. **CLI 体检**:`nodeagent info` / `connect` 直接显示被控端版本与能力对齐情况,
把"调用时才炸"变成一句人话提示。
## 二、发版自动化(GitHub 资产同步)
`pnpm release <x.y.z|patch|minor|major>`:前置检查(干净/在 main/与远端同步)→ 改 7 个 package.json
→ 构建+打包 → 生成资产 → 提交打标签推送 → `gh release create` 上传。
- 资产:`agent.mjs`(**自更新载荷**)、`nodeagent-win-x64.zip`(人工安装包)、
`latest.json`(version/commit/能力数 + 两个资产的 url 与 sha256)、`SHA256SUMS`
- `--dry-run` 无副作用演练;`--no-publish` 只到本地标签
- 能力数从 dist 动态取(避免写死漂移);刻意排除 `.github/`(缺 workflow 权限推不了)
## 三、兼容性契约文档
新增 `docs/VERSIONING.md`:semver 各位的含义、**只增不改**六条硬规则、
升级顺序建议(**先被控端**:新被控端向后兼容旧 CLI)、两条更新路径、发版流程、排查手册。
## 验证
- 单测 147 → **149**(新增 capabilityDiff 用例:远端过旧 / 本机过旧 / 完全一致 / 真实清单自比无差异)
- e2e 28 全绿;`node scripts/release.mjs 1.0.0 --dry-run` 演练通过且工作区无副作用
|
2026-10-04 23:54:51 +08:00 |
|
jkooe
|
553b16f595
|
docs: 口径更新到 v15(图像模板匹配 / 助手提速)+ 三条腿定位说明
|
2026-09-30 01:27:55 +08:00 |
|
jkooe
|
87d7f3fbcc
|
docs: 口径更新到 v13(36 能力 / 32 MCP 工具 / 101 单测)+ 指标命令
|
2026-09-30 00:23:16 +08:00 |
|
jkooe
|
0f8b878de0
|
docs: 路线图补 v12.4(事件直达 MCP)+ 验证脚本说明
|
2026-09-29 15:47:49 +08:00 |
|
jkooe
|
82a44bb13f
|
docs: 路线图补 v12.1~v12.3(Hub 授权 / 等待语义 / macOS GUI 对齐)
|
2026-09-29 14:56:35 +08:00 |
|
jkooe
|
cd774ae0a6
|
feat(E3c): Hub 侧按控制端授权(多令牌 + 按设备白/黑名单 + 注册准入)
## 背景
Hub 原先只有**一个**令牌:任何持有者都能接入任意设备,无法区分「谁在控制哪台机器」。
E3 的权限隔离因此只做到能力级(被控端 ACL),Hub 侧仍是全通。
## 实现(apps/hub/src/authz.ts,纯函数便于单测)
- 多令牌:每个令牌 = 一个控制端身份,可独立指定 allow_nodes / deny_nodes(glob)
- 判定顺序 deny -> allow -> 默认拒绝;未配置 allow_nodes 时默认放行(兼容)
- 顶层 token 视为主令牌(放行全部),旧配置零改动
- 前缀式滚动令牌:value 以 * 结尾时按前缀匹配(轮换期间可灰度)
- 注册准入:node_allowlist 非空时只有匹配的 node_id 能注册,防止他人借令牌挂靠节点
- 列表按身份过滤:控制端只看得到自己被授权的设备
- 越权接入返回新错误码 E_NODE_FORBIDDEN
## 职责边界(重要)
Hub 只做「能否连到某设备」的接入过滤;连上之后的**能力级**授权仍由被控端 ACL
按 client_id 裁决。两层各自独立,Hub 不参与能力决策 —— 保持 Hub 不可信假设。
## 测试
- 单测 79 -> 89(新增 Hub 授权 10 例:主令牌兼容 / 未知令牌 / 前缀轮换 /
deny 优先 / glob 白名单 / 默认放行 / 注册准入 / 旧配置兼容 / 列表过滤 / glob 转义)
- e2e:Hub 用例新增受限令牌访问未授权设备 -> 断言 E_NODE_FORBIDDEN 且错误信息含授权原因
|
2026-09-29 14:38:53 +08:00 |
|
jkooe
|
66c44f6822
|
feat(E3): Hub 并发多控制端 + 设备分组(阶段 E 全部完成)
## E3a 并发多控制端(Hub 槽位池)
过去:一个被控端只有一条 Hub 连接 -> 同时只能一个控制端(否则 E_NODE_BUSY)。
现在:
- Hub 侧 agents 表改为「node_id -> 槽位池」,每个槽位服务一个控制端:
有空闲槽位直接配对;不足且未达上限则向被控端请求扩容(need_slot,3s 超时);
仍不满足才返回 E_NODE_BUSY。新增配置 max_slots_per_node(默认 3,设 1 即退回独占语义)
- 被控端侧 hub-mode 重写为槽位池:常备 2 条连接(warm_slots 可调),
并在某槽位被占用(收到 hello)时预热下一条直到 max_slots
—— 复用既有协议信号,不新增控制消息;每条槽位独立重连与退避
- Hub 列表视图聚合为「一节点一行」并带 slots / paired_slots
- e2e 新增并发用例:两个控制端同时握手 + 交替并发调用,均成功(旧版会失败)
## E3b 设备分组
- 客户端配置新增 groups(组名 -> 设备名数组;成员可写 @其它组名,最多展开 3 层防环)
- CLI:nodeagent group add|remove|list;fanout --nodes @组名 按组并发下发
- 真机验证:group add 本机 win -> fanout system.info --nodes @本机 正常
## E3c 权限隔离(部分完成)
- 能力级隔离沿用被控端 ACL(按 client_id,已含 allow/deny/glob/生效时段/IP 白黑名单/按能力限速)
- Hub 侧「按设备/按控制端授权」尚未实现(当前 Hub 视角为单一令牌),已记入路线图待办
## 测试
- 单测 73 -> 79(新增设备分组 6 例:展开 / 嵌套 / 去重 / 未知 / 兼容旧配置 / 环引用收敛)
- e2e 21/21(含扩展后的 Hub 并发双控制端用例)
|
2026-09-29 14:33:01 +08:00 |
|
jkooe
|
2dccec9a5c
|
feat(D): 生产化 —— 无人值守模式 / 一键升级 / 文档口径更新
## D1 无人值守(install.ps1)
- 新增 -Unattended(S4U 登录类型):**无需保存密码,注销/重启后仍自动运行**
- 新增 -AtStartup:追加开机触发器;任务设置补 StartWhenAvailable(错过触发后补跑)
- **诚实标注能力边界**:S4U 运行在非交互会话,GUI 能力(截屏/UIA/键鼠)不可用;
-Unattended 与 -AllowInput 冲突时自动关闭输入控制并回写配置
- 说明文档给出两种模式的对照表(交互模式支持 GUI,但注销即停)
## D2 一键升级(nodeagent deploy)
- system.info 新增自描述字段:pid / agent_script / agent_home / node_path
- deploy 流程:读取被控端入口路径 → 备份旧文件 → 分块上传新 agent.mjs
→ 调 system.agent.restart 受控重启 → 等待恢复并复验能力数
- 真机验证:
* 首次(旧版 agent 无自描述):--path 指定 → 上传 853KB → PID 16492 / 31 项能力
* 二次:自动识别路径 + 自动备份 → PID 34120 / 31 项能力(免 --path)
## D3 CI(待推送)
- windows-e2e.yml 增加单元测试步骤(3 行);因 OAuth token 缺 workflow scope,
该改动暂留本地未推送,需用户授权后推送
## D4 文档口径更新(README)
- 能力总览补齐 31 项(新增:自持/异步任务/窗口/录屏/剪贴板/拖拽/审计校验)
- 统计数字更正:19 项能力 -> 31,15 个 MCP 工具 -> 26,补 61 项单元测试
- 路线图补 v7~v11+;安全章节补密钥库/Audit 链/ACL 细化
- 命令速查新增:restart / deploy / daemon / fanout / bg / tasks / clip / record /
window.* / screen.find / mouse drag
- MCP 工具表按新工具重排;安装章节新增两种运行模式对照表
单测 61/61、e2e 21/21 全绿
|
2026-09-29 11:47:15 +08:00 |
|
jkooe
|
3f91e1ddc0
|
docs: 新增《实战复盘:短板与改进优先级》
基于真机部署 + v2rayN 故障排查 + 重装前采集的真实使用,梳理短板:
P0(决定能不能用)
1. GUI 语义能力缺失 —— 有截屏有鼠标,但没有「界面元素 -> 坐标」的映射,
切个节点反复点错三次,最后靠键盘导航才成功。建议引入 UIA。
2. 编码不统一 —— 三个真实事故均源于此:Set-Content 写 BOM 致 agent 起不来、
PowerShell 管道损坏中文致清单报废、控制台 GBK 误判。
3. 自断生路 —— 重启 agent 时分离进程被自身进程树清理一起杀掉,导致失联。
建议提供受控重启(system.agent.restart)+ 看门狗自愈 + 配置回滚。
4. exec 输出未结构化 —— 尾部附加 [退出码/耗时] 文本,污染 JSON 解析。
P1:长任务异步化、定时采样、剪贴板、窗口管理、CLI 常驻 daemon
P2:事件订阅、文件监控、录屏、拖拽/宏、多设备并行、DPAPI
一句话:能看能算能跑命令已扎实,短板在「语义」(读不懂界面)、
「状态」(只看当下)与「自持」(改不动自己)。
|
2026-09-28 22:01:15 +08:00 |
|
jkooe
|
eb331502a6
|
docs: 新增《跨机接管的边界与局限》并记录真实故障诊断案例
皇上报障「Windows 上 WorkBuddy 反复提示 Response timed out」,要求记录
「受到什么局限导致 Mac 端无法修复 Windows 上的问题」。
新增 docs/REMOTE-LIMITS.md:
- 能力边界总览(读状态/执行命令/改文件可;改网络高风险;GUI 与人工判断不可)
- 五大核心局限:自断生路悖论 / 无 GUI 交互 / 无法替代人的判断 / 观测窗口时点性 / 破坏性操作不可逆
- 协作模式建议(能看能算的远程,断后路与需判断的交人工)
- 真实案例(2026-09-27):完整诊断链路与判读
本次远程诊断结论(未触碰 Windows 即完成):
- 链路正常:Ethernet 1Gbps/百度 200/腾讯 IPv4 200
- 矛盾状态:System Proxy ProxyEnable=0 但 ProxyServer 残留 127.0.0.1:10808
- 走 10808 访问外网超时 -> xray 上游节点不通
- resolveProxy RPC 耗时 1737ms(代理解析卡顿)
- MarketplaceInitGate 15s 安全超时后强放行
判定高度可能为「代理配置残留 + 上游节点实际不通」导致部分请求超时;
未直接修复,因所需动作为 v2rayN GUI 换节点(属 GUI + 人工判断)。
|
2026-09-27 20:23:21 +08:00 |
|
jkooe
|
665c0e85c4
|
feat: Mac 控制端一键安装(pack:mac + install-macos.sh)
Mac 是控制端,不需要 Windows 安装包,但此前必须 cd 到仓库敲
node apps/cli/dist/index.js,太啰嗦。
新增:
- pnpm pack:mac(scripts/pack-macos.mjs):把 CLI 与 MCP 打包为带 shebang 的
可执行单文件(195KB / 772KB),免 node_modules
- scripts/install-macos.sh:安装到 ~/.local/bin(已在 PATH)+ 打印 MCP 配置片段
- Mac 端不打 Node 运行时(控制端本机已有 Node,体积从约 50MB 降到约 1MB)
修复:execFileSync 不能接收带参数的命令字符串(改用 execSync)
验证:./nodeagent --help 与 MCP tools/list(18) 可直接执行;
install-macos.sh 安装后可在任意目录调用 nodeagent
|
2026-09-27 19:24:57 +08:00 |
|
jkooe
|
4c9b44288c
|
fix(pack): esbuild 输入改用绝对路径,支持从任意目录调用
此前 pack.mjs 用相对路径 apps/agent/dist/index.js 作为 esbuild 输入,
从项目目录外调用(node <abs>/scripts/pack.mjs)时报
Could not resolve apps/agent/dist/index.js。
改为基于 __dirname 的绝对路径;README 补充两种调用方式并注明需在项目目录执行。
验证:cd /tmp && node <abs>/scripts/pack.mjs 可正常产出 32MB 安装包
|
2026-09-27 19:21:21 +08:00 |
|
jkooe
|
192e08b171
|
feat: Windows 便携安装包构建(免装 Node.js)
新增 pnpm pack:win(scripts/pack.mjs),一键产出 nodeagent-win-x64.zip:
- esbuild 打包被控端为单文件 bundle(含全部依赖,约 800KB)
- 自动下载 Node.js Windows x64 运行时(npmmirror,node.exe)
- 组装便携包并打 zip(node.exe + agent.mjs + install.ps1 + uninstall.ps1)
改造 install.ps1:
- 优先使用包内 node.exe + agent.mjs(便携包模式)
- 否则回退系统 Node.js + 仓库构建产物(开发模式)
- 无 Node.js 的 Windows 机器也能一键安装
配套:
- .gitignore 忽略 release/(产物体积大,不入库)
- README 安装说明改为「安装包(推荐)/ 开发模式」两方式
验证:打包产物 32MB;解压后 agent.mjs 可独立运行(19 项能力、wss 监听);
esbuild bundle 通过 banner 提供 createRequire 兼容 CJS 依赖(node-forge)
|
2026-09-27 18:03:04 +08:00 |
|
jkooe
|
0bf9a2f918
|
docs: 重写 README
原 README 已滞后与冗余,具体问题:
- 「当前状态」仍写 v1(实际已到 v6)
- 「关键决策」写「点对点直连(无中枢)」,与已实现的 Hub 中转自相矛盾
- Hub 说明重复出现两处;CLI 命令、验证、工程结构之间层级混乱
按读者动线重写(这是什么 → 能做什么 → 怎么用 → 怎么做的 → 深入):
1. 价值主张:突出「能力层」而非「远程控制」的四点差异(结构化/可授权/可审计/可穿透)
2. 能力总览:19 项能力分组表格
3. 快速开始:构建 → Windows 被控端 → Mac 控制端 → MCP 接入
4. 架构:三链路拓扑(直连 / 发现 / Hub)+ 分层职责表
5. 安全模型:认证 → 授权 → 审计 三层收窄 + 零信任启用步骤
6. 命令速查:按「连接设备 / 系统软件 / 图形文件 / 审计密钥」分组
7. MCP 工具表、Hub 中转、开发与三层验证、工程结构、路线图
同步修正:CLI 帮助补充 Hub 参数(--hub-token / --hub-node)
验证:命令与 CLI --help 逐条核对一致;构建 + E2E 21/21 全绿
|
2026-09-27 15:35:54 +08:00 |
|
jkooe
|
3d03945448
|
feat(v6): Hub 中转 —— 跨网段 / 公网接入
新增 apps/hub(中转节点):
- 被控端主动外连注册(/hub/agent),控制端接入配对(/hub/client)
- 配对后双向字节透传 —— Hub 不解析内容、不持有设备密钥
- Hub 令牌鉴权;list 可查在线设备
- 连接语义:控制端断开仅解绑(被控端保持在线);被控端掉线连带关闭控制端
- 同一被控端同一时刻仅服务一个控制端(占用返回 E_NODE_BUSY)
被控端:
- 新增 hub 配置;启用后不监听本地端口,改为主动外连 Hub(穿 NAT)+ 指数退避重连
- 重构抽出 createAgentCore(),监听模式与 Hub 模式共用同一套鉴权/ACL/能力分发
控制端:
- NodeProfile 新增 hub 字段;toWsUrl 自动附 /hub/client 路径
- client 支持 Hub 配对(控制面消息与 RPC 分离)
修复(Hub 场景暴露):
- cmdConnect 漏传 hub 字段,导致跳过配对直接发 RPC
- Hub unpair 过激进:控制端断开时把被控端也踢下线
- 安全:被控端 hello 时重置认证态与授权(Hub 下同一连接被多控制端复用)
验证:本地 E2E 21/21;构建 + 类型检查全绿;冒烟确认 info/exec 穿透 Hub 且多次接入保持在线
|
2026-09-27 15:04:05 +08:00 |
|
jkooe
|
4ff1b4fd90
|
feat(v5): 多设备管理 + 文件传输
方向 1 · 多设备管理:
- 配置模型升级为 nodes{} + current,自动迁移 v1/v2 单设备扁平配置(零破坏)
- 新增 resolveTarget():按名解析生效设备与控制端身份
- CLI: nodes(列表)/ use(切换)/ remove(移除)/ connect --name(命名)
- 全局 --node <设备名> 单次指定目标,前置(--node=x cmd)与后置(cmd --node x)均可
方向 2 · 文件传输(分块 RPC,协议零改动):
- fs.list(递归+glob)/ fs.stat / fs.read(offset+max_bytes 分块)/ fs.write(原子写+append)
- 小文件(<=8MB)首次读取附带 sha256;路径白名单 fs_roots,越界 -> E_ACL_DENIED
- CLI: ls / stat / cat / pull / push(自动分块;pull 与 push 均原子落盘)
- MCP: na_fs_list / na_fs_read / na_fs_write
能力总数 15 -> 19;MCP 工具 12 -> 15
验证:本地 E2E 20/20(新增文件传输全链路用例);构建 + 类型检查全绿;
冒烟确认 3MB 文件 pull 后 sha256 一致、白名单越界被拒
|
2026-09-27 13:25:38 +08:00 |
|
jkooe
|
3d0eb1c696
|
feat(v4): 无感体验 —— 局域网自动发现 + 断线自动重连
自动发现(免手抄 IP):
- 被控端 UDP 心跳广播(默认 5s 一次,目标 255.255.255.255:8766)
- 控制端 Discovery 监听 + TTL 设备表(默认 30s 过期)
- 报文不含任何凭据;可 discovery.enabled:false 关闭
- 控制端取「报文来源 IP」作为可达地址(比被控端自报地址可靠)
- CLI: nodeagent discover [--wait 5];MCP: na_discover
断线自动重连:
- client 新增 autoReconnect(指数退避 1s→30s + ±15% 抖动)
- 重连前清空在途请求(统一 E_NODE_OFFLINE),避免悬挂
- onStateChange 回调(connected/reconnecting/closed)
- close() 会停止重连,不会关不掉
修复:UDP socket 需先 bind 再 setBroadcast(未绑定时报 EBADF)
验证:本地 E2E 19/19(新增发现 + 重连两用例);构建与类型检查全绿
|
2026-09-27 13:11:13 +08:00 |
|
jkooe
|
edc69b0a34
|
feat(v3+): 审计日志 + 调用限速
审计(安全闭环最后一环):
- 被控端将关键动作以 JSONL 写入 <数据目录>/audit.log:agent 启停 / 认证成败 /
invoke 结果 / ACL 拒绝 / 限速拦截
- 大小轮转(默认 10MB × 5 份);参数默认只记 sha256 摘要,log_args 开启后
自动脱敏(pass/token/secret/key/auth 键 → ***,字符串截断 200 字符)
- 审计写入失败被吞掉,绝不阻断业务主流程
- 新增能力 system.audit.list(支持 limit/since/client_id/type 筛选)
- CLI: nodeagent audit;MCP: na_audit
限速:
- 落地 ACL 中预留的 max_calls_per_min(按调用方滑动窗口计数)
- 超限返回 E_RATE_LIMITED(-32407)
验证:本地 E2E 全绿;零信任用例扩展为 6 项断言(授权/拒绝/审计留痕/脱敏/限速/未注册/错钥)
|
2026-09-27 11:56:37 +08:00 |
|
jkooe
|
5b7e967868
|
feat(v3): 零信任安全 —— Ed25519 身份认证 + 能力级 ACL
认证(两模式并存,默认 psk 向后兼容):
- 新增 auth_mode: psk | ed25519
- ed25519:每控制端独立密钥对,挑战-应答签名验证(替代共享密钥)
- 密钥用 Node 内置 crypto 生成(零新依赖),Base64(DER) 单行格式
- 私钥存 <数据目录>/keys/ed25519.json(600 权限,永不外传)
授权(能力级 ACL):
- acl.clients[] 按调用方登记 pubkey + allow/deny(glob 匹配)
- 判定顺序 deny → allow → default_effect(默认拒绝)
- 未注册身份 / 验签失败 → 握手拒绝;未授权能力 → E_ACL_DENIED
- auth_ok 下发 authorized 子集,CLI 以 授权/未授权 标识展示授权矩阵
接入:
- CLI: keygen(生成密钥 + 打印 ACL 配置片段)、connect --auth-mode ed25519
- MCP: 按 auth_mode 自动选择认证方式
- install.ps1: 显式写 auth_mode + 零信任指引
验证:本地 E2E 17/17(新增零信任四项断言);手动端到端复验通过
|
2026-09-27 11:01:58 +08:00 |
|
jkooe
|
792937c6b0
|
feat(v2): 图形接管 —— 屏幕感知 + 输入控制
新增 7 项能力(总计 14):
- screen.info / screen.capture:显示器信息、截屏(region/scale/format)
- input.mouse.move/click/scroll、input.key.type/press:鼠标键盘控制
安全设计:
- input.* 为高危能力,由被控端 allow_input 开关统一管控,默认禁用
- 未开启时返回 E_CAPABILITY_DISABLED(附开启指引)
- 文本输入经 Base64 传参、PowerShell 侧解码,杜绝内容注入
- 按键名走白名单映射(虚拟键码),非法键名直接拒绝
实现:纯 PowerShell(System.Drawing 截屏 + user32.dll SendInput),
无原生编译、无第三方依赖。
接入:
- CLI: screen / screenshot / mouse / key 命令
- MCP: na_screenshot(直接返回图像)/ na_mouse / na_key
- install.ps1: 新增 -AllowInput 开关
- verify.mjs: 新增 v2.1~v2.3 验收项
验证:本地 E2E 16/16;远程验收 12 通过 / 0 失败
|
2026-09-27 03:43:10 +08:00 |
|
jkooe
|
bda45e41e5
|
docs: README 补充自动化验证的成本说明(GitHub Actions 免费额度与支出限额)
|
2026-09-27 01:29:37 +08:00 |
|
jkooe
|
f1506b3fd0
|
test: 新增自动化真机验证体系
- tests/e2e/windows.mjs: Windows 专属能力测试(service.list / app.list / winget 装软件 / cmd 外壳)
- tests/e2e/run.mjs: service.list 断言改为平台感知(Windows 期望成功)
- scripts/verify.mjs: 远程验收脚本,对齐 PRD FR-01~FR-08 逐条验收 + Markdown 报告
- package.json: 新增 test:windows / verify 脚本
- README: 补充自动化真机验证三层体系说明
注: .github/workflows/windows-e2e.yml 需 workflow scope,待授权后单独提交
|
2026-09-27 01:24:52 +08:00 |
|
jkooe
|
77c024703a
|
feat: nodeagent v1 初期开发完成
- packages/protocol: 协议定义(信封/方法/错误码/能力schema/校验/HMAC/ULID)
- packages/client: 控制端客户端库(连接/握手/invoke/超时)
- apps/agent: Windows 被控端(监听/HMAC认证/能力分发/7项能力/进程执行)
- apps/cli: 控制端 CLI(connect/info/status/ps/services/exec/apps/install/list/invoke)
- apps/mcp: MCP server(na_* 工具,接入 WorkBuddy)
- scripts: install.ps1 / uninstall.ps1(开机自启 + 防火墙 + 密钥生成)
- tests/e2e: 端到端测试 13/13 通过(握手/能力/超时强杀/参数校验/鉴权失败/未认证)
|
2026-09-27 01:06:35 +08:00 |
|
jkooe
|
3e129e6411
|
docs: 新增 nodeagent 开发文档(DEVELOPMENT.md,参考 NodeBuddy 裁剪)
|
2026-09-27 00:50:35 +08:00 |
|
jkooe
|
f0f4854110
|
docs: nodeagent PRD v1.0(已认可)+ README + .gitignore
|
2026-09-27 00:32:50 +08:00 |
|