Skip to content

window-warmup 0.1.4: Antigravity windows are warmed right after they reset, the service token survives restarts, and a new task opens at the bottom - #878

Open
YangHonghang wants to merge 2 commits into
magpie-community:mainfrom
YangHonghang:fix/window-warmup-token-and-new-task
Open

YangHonghang wants to merge 2 commits into
magpie-community:mainfrom
YangHonghang:fix/window-warmup-token-and-new-task

Conversation

@YangHonghang

Copy link
Copy Markdown
Contributor

改了什么

  1. Antigravity 等窗口重置后不自动发送(主要修复)
    插件原本默认「resetsAt 在未来 = 窗口在计时」。实机发现 Antigravity 空闲时不清空重置点,有两种报法,插件都当成在计时,一直不发:

    • 很久没用时:resetsAt = 读卡时刻 + 5h,每读一次往后推;
    • 旧窗口刚到期时:直接报「旧重置点 + 5h」并保持不动。

    现在不按供应商区分,只看读数本身:

    • 重置点在到来前随读卡同步后挪(挪动量与读卡间隔相差 ≤ 5 秒)且用量为 0 → 空闲,按小时去重;
    • 旧重置点已过、之后插件没发过、新重置点用量为 0 → 空闲,去重键取旧重置点(after:<旧重置点>),每轮最多一次。

    重置点固定、resetsAt 为空或已过去的卡片(如 ZCode)走原逻辑,不受影响;旧版 Magpie 不给 readAt 时保持原行为。

  2. 服务口令持久化:口令存到插件数据目录的 token(0600),Magpie 重启插件宿主后已打开的页面不再报 401;仍遇到 401 且没有未保存草稿时页面自动刷新一次。

  3. 新建任务在列表底部展开,与保存后的位置一致。

  4. README 新增「更新说明」,并在「已知限制」里写明空闲判定的代价:若厂商其实自动续上了下一窗,每轮会多发一条 hi。

验证

  • bun run build、bun run typecheck、bun test(276 通过,1 个浏览器用例因本机无 Playwright 跳过)、bun scripts/check.mjs window-warmup 全部通过;dist/ 与源码构建逐字节一致。
  • 新增 15 个调度器回归用例,对新判定的每个条件做了变异测试,均有用例能抓到。
  • 在 Docker 里的 Magpie 上实机跑了 2 天多(11-06 ~ 11-09):Antigravity Gemini 窗口每轮在重置后约 30 秒由调度器自动发出,同一轮无重复发送;ZCode 窗口行为不变。

- 重置点随读卡时刻滑动且用量为 0:复读确认后按空闲发送
- 旧重置点过后直接出现下一轮重置点、用量为 0 且其后未发送:按空闲发送,去重键取旧重置点
- README 增加更新说明并补充已知限制

@yetone yetone left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. The token that survives a restart and the reload on a stale token are both useful, and most of the new Antigravity logic is held by tests. I reviewed fe7f5db and ran it on macOS (mote, Bun 1.4.2, HOME and TMPDIR in the run's own folder). I can't merge it yet: two branches of the new reset logic can be deleted while every test stays green. The PR body says every condition was mutation-tested, which these runs don't bear out.

What I ran at fe7f5db

  • cd packages/window-warmup && bun test: 275 pass, 1 skip, 0 fail. The skip is tests/browser.test.ts, because Bun doesn't resolve playwright through NODE_PATH. With playwright linked into the package's node_modules it runs 6/6 pass in Chromium and WebKit.
  • bun scripts/check.mjs window-warmup: ✓ registry.json, ✓ window-warmup.
  • dist/ matches a fresh build (tests/dist.test.ts).
  • 17 hand breaks, each run against tests/scheduler.test.ts, server.test.ts and app.test.ts. Thirteen go red, including: rolls off, tolerance off, carried off, carried ignoring lastSent, backfill off, each used === 0 gate, the after: key, staleIdle, the probe, the token file, the reload flag and the dirty-draft guard. Four stay green:
Break Where Result
dRead >= ROLL_GAP_MS → true src/scheduler.ts:590 0 fail
drop mark.resetRolls = false in the same-value reread branch src/scheduler.ts:609 0 fail
drop the minDelay for a future probeAt src/scheduler.ts:949 0 fail
drop if (reloadedForToken) return false; web/app.ts:525 0 fail

Blocking

  1. The 60 s gap guard isn't tested. Without it, two card reads a few seconds apart whose resetsAt moved by about the same few seconds count as a rolling window. That is the false "idle" the guard exists to stop, and it leads to a send into a window that is really running. Please add a case with two reads under 60 s apart (for example 5 s, with resetsAt shifted by 5 s), and assert that resetRolls stays false and nothing is sent.
  2. The revoke branch (line 603-611) isn't tested. The test that looks like it covers it ("已判为滑动空闲,但读数早于「上次发送 + 1 分钟」", around scheduler.test.ts:1356) refreshes to sent + 5h. That value differs from lastReset, so it goes through the first branch and never reaches the revoke. Your comment at line 607 names the case the branch is for: the send lands in the same second as the last rolling read, so the reread gives the same value. Please add that case. Start from a mark with resetRolls: true and keep the same resetsAt with used: 0, read again ≥ 60 s later. Assert resetRolls ends false and there is no second idle: send at the next hour.

Non-blocking

  • The probe's wake-up (line 949) has no test. Without it the reread waits for the next regular tick. A test that advances the fake clock to first + 60 s and counts refreshes would hold it.
  • reloadedForToken resets with the module on each load, so it stops a second reload only within one page instance. If the token is still refused after the reload, the page reloads again on every first request. A sessionStorage flag (cleared after a request succeeds) would stop a loop across loads. Neither version has a test yet.
  • If a card's readAt doesn't move on refresh (a cached card), rollProbeAt returns the same past first + 60 s on every tick, so the scheduler refreshes once per tick until the reset. It might be worth capping it at one probe per new resetsAt.
  • I didn't run tsc.

Instructions-shaped text: none found in the diff.

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.

2 participants