← 全部工具

iselur/stillworks

热度 65 更新于 开发与构建

Take a snapshot of what your code does, then see if your edit moved anything. For code with no tests. Zero dependencies, MIT.

githubauto-collected

安装

暂未验证可直接使用的安装命令,请查看项目官方文档或 Release。

stillworks

Take a snapshot of what your code does. After you change it, see if anything moved.

You have to edit a file that has no tests. Afterwards, how do you know you only changed the thing you meant to change?

stillworks lock runs your code and writes down what it gives back. stillworks check runs it again after your edit and tells you if any answer is different. That's the whole idea.

It's a safety net for one risky change, not a test suite you keep. Set it up in under a minute, delete it when you're done.

Two verbs: lock and check. Zero dependencies. Plain CLI, so every coding agent can use it (Claude Code, Codex, OpenCode, Cursor, aider — anything that can run a shell command). Python ≥ 3.9, stdlib only, MIT license.

pip install stillworks   # one install, all five agent tools (see below)

stillworks lock src/pricing.py --fuzz 8   # before: record real behavior
# ... let your AI agent refactor pricing.py ...
stillworks check                          # after: did behavior change?
CHANGED  apply_discount#3  (apply_discount)
         args: ((100.0, 'GOLD'), {})
         was:  85.0
         now:  90.0
BEHAVIOR CHANGED: 24 records — 1 CHANGED, 23 OK

Exit code 1 — the merge gate closes. If the change was intentional: stillworks accept applydiscount#3, and it becomes the new baseline. Name each record you mean; stillworks accept --all blesses every change in one go, which is the right answer after a rewrite you have already read and the wrong one at any other time.

The other codes exist so nothing can impersonate that one: 0 nothing moved, 2 the check could not be made — the lockfile is unreadable, or every record in it was excluded so nothing was compared — 130 stopped by ctrl-c, 141 the reader hung up (stillworks check | head, or | less quit with q). All of those mean the check never finished comparing, which is neither a pass nor a fail — and stillworks check && deploy needs to be able to tell.

For the same reason, a read-only .stillworks does not fail the check. The comparison is the verdict; saving a receipt of it for accept and report is bookkeeping, so it warns on stderr and still answers 0 if nothing moved. accept goes the other way — writing the baseline is the whole job, so if that write fails it says which file and exits 2 rather than reporting behavior it did not bless.

Should you just write tests instead?

Often, yes — and you should. A real test suite (pytest, plus approvaltests, syrupy or pytest-regressions for snapshots) says what the code is meant to do. That's more valuable than what it happens to do today, and it's worth keeping around. If you can write those tests, or have an AI write them for you — that works, and it beats this tool.

Use stillworks when you're not there yet:

  • The code has no tests and you're changing it today. Snapshot it, make the

change, check, delete the snapshot. Nothing left to maintain.

  • You don't actually know what it's supposed to do. Nobody does; the person

who wrote it left. What it does now is the only thing you can hold on to.