Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,8 @@ ADR-147:Terminal正常实际提交“你”及wq前缀确认后的failure/INT/
- [ ] **2026-10-27 MVP 正式发布(目标 `1.0.0`,ADR-298)**:阶段 A 在 0.1.16/26 上演练 IT-22(`docs/tasks/T-ITER-22.md`)→ 修复入库 → 阶段 B 递增 1.0.0(build 27)并双机装同一包(同时闭环「更新器自更新」)→ 阶段 C 只在 1.0.0 上做正式 IT-22、IT-15 独立重建、IT-23 五工作日 → 阶段 D `tag v1.0.0` 打在验收候选提交 → Release → Pages。
- [x] 2026-10-28 **锁定候选 1.0.0 / build 29**(报告217):提交 `11abece3`、ZIP `aca4ed5c…`、宿主执行 `4ad949e6…`,air 已装同包。装机定向复验:2.1 多词拼接 PASS、9.1 编码播报 PASS、11.1 候选跟随(6 张截图:下方/镜像/底部翻上,无压字)PASS。**IT-22 限定范围通过**(必查 11 + 抽查 8 全 PASS,其余沿用报告216 基线)。
- [x] 2026-10-28 **IT-15 独立离线重建通过(报告218)**:用户在 air 上从候选自带源码包离线重建 1.0.0/build 29,身份链与逐架构网络导入 PASS、**默认数据 4/4 逐字节一致**、空闲 0 外联;可执行文件因本机 SDK 27.0 vs 发布 26.5 不同(ADR-033 边界)。顺带修掉 `run-repro.sh` 的缺陷:原来 `cmp` 可执行文件失败会中断,导致数据表比对根本没跑,且漏比 `variant-s2t.tsv`。
- [ ] 2026-10-28 IT-23 五工作日试用(**1.0.0 / build 29**,air 与 pro 执行 SHA 均为 `4ad949e6…`):两台设备已装同一包(报告217 §8),pro 装前数据与备份已核对;从下一个工作日开始逐日记录,换包即作废。
- [ ] 2026-10-29 IT-23 五工作日试用(**1.0.0 / build 30**,air 与 pro 执行 SHA 均为 `16ac739f…`):两台设备已装同一包(报告217 §8)。build 29 因「候选窗跟随鼠标」缺陷(报告219)被 30 取代,IT-23 尚未起算,故换包不影响基线。
- [x] 2026-10-29 **候选窗跟着鼠标而不是插入点(报告219,build 30)**:`caretRect` 给解析器传了 `allowsEmptyCaret: false`,`length()==0` 时解析直接返回 nil → 落到鼠标兜底;改为 `true`,并把回退链收敛为「本轮 → 上次成功位置 → 鼠标」,新增 3 条断言。两台设备已装 build 30。
- [~] I3/IT-12/23:IT-12 性能/内存/久用已 PASS(报告191/192/199/207);**IT-23 五工作日试用尚未开始**(模板报告211)。
- [~] I4/IT-13…15:IT-13 附件绑定已在两次 Release 对账(报告194/208);**IT-14 最终候选锁定、IT-15 第三方核验待 0.1.15**。

Expand Down
13 changes: 8 additions & 5 deletions docs/reviews/217-1.0.0-freeze.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,15 +123,15 @@ platforms/macos/tests/run-repro.sh \
- **静态零外联**:`./scripts/verify-no-network.sh`(或 `make verify-no-network`)通过。
- **运行时零外联**:一边打字一边 `lsof -i -a -p "$(pgrep -x Lampyris)"`,预期**无输出**。

## 8. IT-23 试用基线:两台设备装同一个包(2026-10-28)
## 8. IT-23 试用基线:两台设备装同一个包(2026-10-29 更新为 build 30)

| 项 | air(本机,arm64 / macOS 27.0.1) | pro(x86_64 / macOS 13.7.8) |
|---|---|---|
| 版本 / 构建 | **1.0.0 / 29** | **1.0.0 / 29** |
| 宿主执行 SHA-256 | `4ad949e6c3608c689c07e8a3f092a53babc788b290e424b4784bebc1d3aae31c` | **同值**(同一个二进制) |
| 更新程序构建号 | 29 | 29 |
| 版本 / 构建 | **1.0.0 / 30** | **1.0.0 / 30** |
| 宿主执行 SHA-256 | `16ac739f135ef1e9abfd750956a54411da3313e9cf675bdf7f50a165d246bddb` | **同值**(同一个二进制) |
| 更新程序构建号 | 30 | 30 |
| 签名 / 公证 | Developer ID + `spctl` Notarized | 同(`codesign --strict`、`stapler validate` 均 PASS) |
| 用户数据 | config `cfc86cff…`、词库 800+ 行 | config `2bd3fde6…`、词库 **593 行**(装前装后一致) |
| 用户数据 | config `cfc86cff…`、词库 800+ 行 | config `cb8e7d05…`、词库 **685 行**(build 30 装前装后一致) |
| 旧版本备份 | `updates/`、`uninstalled/` 历史项 | `uninstalled/bundle.aPZKev`(0.1.16) |
| 输入源 | `cn.jokerhub.inputmethod.Lampyris.default` 已启用 | 已启用;当前停在 ABC,使用时按 ⌃Space 切 |

Expand All @@ -140,3 +140,6 @@ pro 的安装记录:`ev-95-pro-stage.log`(ZIP 校验 → 解包 → 停宿
改为「停宿主 → 确认 `pgrep -x Lampyris` 为空 → 立即安装」后成功;这是安装器**正确的**保护行为,不是缺陷。

**IT-23 从下一个工作日开始**:两台设备都固定在 1.0.0/29,期间任何换包都会让当天记录作废。

> **为什么从 29 换到 30**:build 29 装机复验时发现「聚焦输入框 + 鼠标在远处 → 候选窗跟着鼠标」,
> 根因与修法见报告 219。IT-23 尚未开始记第 1 天,因此换包不影响试用基线;两台设备均已升级到 30。
4 changes: 2 additions & 2 deletions docs/reviews/219-caret-follows-focus.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ HUD 那条路径一直传的是 `allowsEmptyCaret: true`,所以同样的场景
| 单元 | `caret-placement.swift` 新增回退链三例:本轮结果优先 / 无本轮时用上次位置 / 两者都没有才用鼠标 |
| 解析器 | 既有断言已覆盖「空文档 + `allowsEmptyCaret: true` 取到行框」,本次让候选窗走同一条 |
| 回归 | `make verify`、`make macos-offline-tests`(56 文件 / 303 例)全绿 |
| 实机 | 待 build 30 装机复验:**聚焦输入框、把鼠标移到屏幕另一端、再打字**,候选窗应贴着插入点 |
| 实机 | 待用户复验(build 30 已装两台设备):**聚焦输入框、把鼠标移到屏幕另一端、再打字**,候选窗应贴着插入点 |

## 4. 影响

- 版本仍 1.0.0,构建号 29 → **30**;锁定候选随之更新(报告 217 §8 的身份表在复验后补记)。
- 版本仍 1.0.0,构建号 29 → **30**;锁定候选随之更新为 build 30(ZIP `9704f209…`、宿主执行 `16ac739f…`,报告 217 §8)。
- IT-23 尚未开始记第 1 天,因此**不影响**试用基线;两台设备都升级到 30 后再开始计时。
2 changes: 1 addition & 1 deletion packaging/build-number
Original file line number Diff line number Diff line change
@@ -1 +1 @@
30
31
21 changes: 19 additions & 2 deletions platforms/macos/Sources/InputController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,20 @@ final class LampyrisInputController: IMKInputController {
// 只有会话仍在组合、候选窗会保留时才内联;宽度/模式/中英会 cancel 组合,
// 这类切换必须走 HUD,否则候选窗随即关闭、用户什么都看不到。
if let window = candidateWindow, window.isVisible, session?.isComposing == true {
if Self.hudDiagEnabled {
Self.hudDiag("feedback msg=\(message) branch=chip visible=true composing=true")
}
window.updateStatus(candidateStatus())
window.refreshLayout()
return
}
StateHUDController.shared.show(message, caret: hudCaretRect())
let caret = hudCaretRect()
if Self.hudDiagEnabled {
Self.hudDiag("feedback msg=\(message) branch=hud visible="
+ "\(candidateWindow?.isVisible ?? false) composing=\(session?.isComposing ?? false) "
+ "caret=\(caret.map(NSStringFromRect) ?? "nil")")
}
StateHUDController.shared.show(message, caret: caret)
}

/// HUD 用光标矩形:无客户端/取不到时返回 nil(不显示,不退鼠标)。
Expand All @@ -298,6 +307,11 @@ final class LampyrisInputController: IMKInputController {
let length = max(0, client.length())
let selection = client.selectedRange()
let bundle = client.bundleIdentifier() ?? ""
if Self.hudDiagEnabled {
Self.hudDiag("hud client=\(bundle) frontmost="
+ "\(NSWorkspace.shared.frontmostApplication?.bundleIdentifier ?? "nil") "
+ "len=\(length) sel=\(selection.location)")
}
let windowLevel = client.windowLevel()
let diag = Self.hudDiagEnabled
let startIndex = Self.caretLookupIndex(
Expand Down Expand Up @@ -376,7 +390,10 @@ final class LampyrisInputController: IMKInputController {
/// 诊断开关(默认关闭):`launchctl setenv LAMPYRIS_HUD_DIAG 1` 后重启宿主,
/// 光标矩形解析过程写入 `$TMPDIR/lampyris-hud-diag.log`,用于真机定位 HUD 偏移。
static var hudDiagEnabled: Bool {
ProcessInfo.processInfo.environment["LAMPYRIS_HUD_DIAG"] != nil
if ProcessInfo.processInfo.environment["LAMPYRIS_HUD_DIAG"] != nil { return true }
// 文件开关:宿主由 launchd 拉起,`launchctl setenv` 不总能传进来(报告219/220)。
let marker = ImePaths.supportDirectory()?.appendingPathComponent("hud-diag")
return marker.map { FileManager.default.fileExists(atPath: $0.path) } ?? false
}

static func hudDiag(_ message: String) {
Expand Down
Loading