fix(cli): honor --force on unresponsive engine; detect listening PIDs on Windows#624
fix(cli): honor --force on unresponsive engine; detect listening PIDs on Windows#624yanniedog wants to merge 1 commit into
Conversation
… on Windows
Two related bugs surface when an iii-engine listening socket is wedged
after sleep/wake on Windows:
1. `agentmemory stop --force` checks --force only after deciding the
engine is reachable. When the engine is unresponsive but its socket
still listens, runStop took the early-exit path and printed
"Preserving ~/.agentmemory/iii.pid. Investigate before manual
cleanup", ignoring --force entirely. The user is told the exact
flag for this situation does nothing.
2. findEnginePidsByPort short-circuits with `return []` on Windows, so
--force has no PIDs to signal even if it were honored. The only
survivor list comes from the pidfile, which itself is often stale.
The combination meant a Windows user with a hung engine could not stop
it from the CLI at all - manual netstat + taskkill was the only way.
Changes:
- runStop: when !running and survivors exist, honor --force by
SIGTERM/SIGKILL-ing every PID and clearing pidfile + engine state so
the next start is not refused by a stale-state guard. Without --force
the message is updated to point at the flag rather than only at
manual triage.
- findEnginePidsByPort: on Windows, parse `netstat -ano -p TCP` for
PIDs whose local address ends in :PORT and whose foreign address is
the unspecified peer (LISTENING rows). The state column is ignored
because it is locale-translated ("ABHOEREN" on de-DE, etc).
- parseNetstatListeningPids: extracted as a pure exported helper so the
parser can be unit-tested without spawning netstat.
- Help text for `stop --force` now mentions netstat and the
unresponsive-engine case.
Test plan: test/cli-stop-port-detection.test.ts covers IPv4 + IPv6
listeners, CLOSE_WAIT / ESTABLISHED filtering (the browser ghost-tab
case), selfPid exclusion, port-prefix collisions, dedup, blank input,
UDP input, and locale-translated state words.
Signed-off-by: Jonathan Koka <yanniedog@users.noreply.github.com>
|
@yanniedog is attempting to deploy a commit to the rohitg00's projects Team on Vercel. A member of the Team first needs to authorize it. |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (2)
📝 WalkthroughWalkthroughThis PR improves the ChangesWindows PID Detection and Forced Stop
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint skipped: no ESLint configuration detected in root package.json. To enable, add Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
Two related bugs make
agentmemory stop --forceuseless on Windows when the iii-engine listening socket is wedged after sleep/wake. Together they leave the user with no CLI path to recover: the engine listens but does not respond,--forceis silently dropped, and the only Windows code path for finding port owners returns an empty array.This PR makes
--forceactually force, and adds first-class Windows support for finding the listening PID vianetstat -ano.Bugs
runStopchecks--forceonly after deciding the engine is reachable. When the engine listens but is unresponsive,runStoptakes the early-exit branch and printsPreserving ~/.agentmemory/iii.pid. Investigate before manual cleanup, ignoring--forceentirely. The exact flag that should rescue this scenario does nothing.findEnginePidsByPortshort-circuits withreturn []on Windows, so--forcehas no PIDs to signal even if it were honored. The only candidate left is the pidfile, which is typically stale.The combined effect on Windows: a hung engine cannot be stopped from the CLI at all. The user must run
netstat -ano | findstr :3111thentaskkill /F /PID <pid>by hand.Repro (Windows 11, Node 22, agentmemory 0.9.21)
After this PR:
Changes
runStop: when!runningand survivors exist, honor--forceby SIGTERM/SIGKILL-ing every PID via the existingsignalAndWaithelper, then clear pidfile + engine state so the next start is not refused by the stale-state guard. The non---forcemessage now points at the--forceflag in addition to manual triage commands.findEnginePidsByPort: on Windows, parsenetstat -ano -p TCPfor PIDs whose local address ends in:PORTand whose foreign address is the unspecified peer (0.0.0.0:0,[::]:0,*:*). The state column is ignored because it is locale-translated (de-DE renders LISTENING as ABHOEREN, fr-FR as ECOUTER, etc) - keying off the peer address is locale-stable.parseNetstatListeningPids: extracted as a pure exported function so the parser is unit-testable without spawning netstat.stop --forcenow mentions netstat and the unresponsive-engine case.Test plan
New file
test/cli-stop-port-detection.test.ts(Vitest) covers:0.0.0.0:3111) + IPv6 ([::]:3111) listeners on the requested port--forcewould kill an unrelated browser process):3111vs:31111vs:13111)ABHOERENon de-DE)Local run:
Full suite: my branch reduces overall failures from 24 to 17 on a Windows 11 host (the remaining 17 are pre-existing path-related failures unaffected by this change; same set fails on
main). Build passes (npm run buildclean).Non-goals (deliberate)
lsofpath - it already works.netstat.exeships with every Windows install.Notes
I hit this while writing a Windows supervisor for agentmemory (yanniedog/agentmemory-keeper). The supervisor works around the bug by killing port holders directly via PowerShell, but the right fix is to make
agentmemory stop --forcedo what its name promises. Happy to scope down further if you want this split into two PRs (one per bug).Summary by CodeRabbit
Release Notes
Bug Fixes
agentmemory stop --forceto handle unresponsive engines more effectivelyDocumentation
--forceoption to clarify behaviorTests