fix: what an audit of the documented behaviour found
An independent check of every behaviour AGENTS.md was to describe: - `--units ,` and `--only ,` skipped their empty items and so had no filter left: a typo started a run of every unit. They are usage errors now (exit 3). - Two fixes the plan lists were missing: a dry run now clears the prompts a dry run before it left in the dir they share (the report counted them), and `config` reports an absolute functional.mcp.command that is no program here - /usr/bin/npx inside the Flatpak, whose /usr is the Sdk's. - A patch that is not UTF-8 stops `run` at preflight (exit 3), as the plan has it; it exited 1. - An exception no command caught aborted the process (134), e.g. a home that holds no lenses: it ends with its message and exit 1. An error escaping `run` or `freeze` now also clears the signal handler's run and sweeps what is left below the subreaper. - `config -h` printed "unrecognized arguments" (exit 3): it prints the usage, exit 0. - An API seat's .claude.json is linked into place, so a second writer never replaces the first's file and what claude wrote to it since. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
53b7d6de31
commit
32a0de1a07
7 changed files with 114 additions and 11 deletions
|
|
@ -390,6 +390,11 @@ namespace Crafter::Review::Run {
|
|||
built = Inventory::Build("commits", a.artifact);
|
||||
} catch (const Inventory::InvariantError& e) {
|
||||
Die(e.what());
|
||||
} catch (const Dyn::Error& e) {
|
||||
// A patch that is not UTF-8 is no artifact to review: a preflight
|
||||
// failure.
|
||||
if (e.Kind() != "UnicodeDecodeError") throw;
|
||||
Die(std::format("the artifact's patches are not UTF-8 ({}) - re-freeze", e.what()));
|
||||
}
|
||||
units = built.out.at("units");
|
||||
lines = built.lines;
|
||||
|
|
@ -449,6 +454,12 @@ namespace Crafter::Review::Run {
|
|||
}
|
||||
scratch = scratchRoot / std::format("{}-run-{}{}", h8, runN, a.dryRun ? "-dry" : "");
|
||||
fs::create_directories(scratch);
|
||||
if (a.dryRun) {
|
||||
// Every dry run on a hash shares this dir: the report counts
|
||||
// this run's prompts, not the last one's too.
|
||||
std::error_code error;
|
||||
fs::remove_all(scratch / "prompts", error);
|
||||
}
|
||||
if (!a.dryRun) {
|
||||
// A stop meant for a run this dir held before is not this run's.
|
||||
std::error_code error;
|
||||
|
|
@ -2161,6 +2172,16 @@ namespace Crafter::Review::Run {
|
|||
Process::BecomeSubreaper();
|
||||
Run run(std::move(a), cfg);
|
||||
Current = &run;
|
||||
// However this ends - a return, or an exception on its way to Main's
|
||||
// handler - the signal handler loses its run, and whatever is left
|
||||
// below this subreaper (a daemon a git call started) goes with it;
|
||||
// never a process it did not start.
|
||||
struct Cleanup {
|
||||
~Cleanup() {
|
||||
Current = nullptr;
|
||||
Process::KillDescendants();
|
||||
}
|
||||
} const cleanup;
|
||||
// `crafter-review stop`: the file is looked at every 2 s, and a stop
|
||||
// is handled exactly like SIGTERM.
|
||||
std::jthread watcher([&run](const std::stop_token& token) {
|
||||
|
|
@ -2189,10 +2210,6 @@ namespace Crafter::Review::Run {
|
|||
}
|
||||
watcher.request_stop();
|
||||
watcher.join();
|
||||
Current = nullptr;
|
||||
// Whatever is left below this subreaper - a daemon a git call
|
||||
// started - goes with it; never a process it did not start.
|
||||
Process::KillDescendants();
|
||||
return code;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue