@icntswm/skillcheck 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/claude.js +27 -4
- package/dist/cli.js +3 -2
- package/package.json +1 -1
package/dist/agents/claude.js
CHANGED
|
@@ -202,22 +202,45 @@ function spawnErrorMessage(e, bin) {
|
|
|
202
202
|
}
|
|
203
203
|
/** Live runs by process group id, with their tmp dirs; see abortActiveRuns. */
|
|
204
204
|
const active = new Map();
|
|
205
|
+
function groupAlive(pid) {
|
|
206
|
+
try {
|
|
207
|
+
process.kill(-pid, 0);
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
205
214
|
/**
|
|
206
215
|
* Kill every running claude group and remove its tmp dir. Runs are detached
|
|
207
216
|
* process groups, so Ctrl+C on skillcheck does not reach them: without this
|
|
208
|
-
* they keep running (and billing) after skillcheck exits.
|
|
217
|
+
* they keep running (and billing) after skillcheck exits. Groups still alive
|
|
218
|
+
* after graceMs get SIGKILL, so a process that ignores SIGTERM dies too.
|
|
209
219
|
*/
|
|
210
|
-
export function abortActiveRuns() {
|
|
211
|
-
|
|
220
|
+
export async function abortActiveRuns(graceMs = KILL_GRACE_MS) {
|
|
221
|
+
const runs = [...active];
|
|
222
|
+
active.clear();
|
|
223
|
+
for (const [pid] of runs) {
|
|
212
224
|
try {
|
|
213
225
|
process.kill(-pid, "SIGTERM");
|
|
214
226
|
}
|
|
215
227
|
catch {
|
|
216
228
|
// already exited
|
|
217
229
|
}
|
|
230
|
+
}
|
|
231
|
+
const deadline = Date.now() + graceMs;
|
|
232
|
+
while (runs.some(([pid]) => groupAlive(pid)) && Date.now() < deadline) {
|
|
233
|
+
await new Promise((r) => setTimeout(r, 50));
|
|
234
|
+
}
|
|
235
|
+
for (const [pid, workdir] of runs) {
|
|
236
|
+
try {
|
|
237
|
+
process.kill(-pid, "SIGKILL");
|
|
238
|
+
}
|
|
239
|
+
catch {
|
|
240
|
+
// already exited
|
|
241
|
+
}
|
|
218
242
|
rmSync(workdir, { recursive: true, force: true });
|
|
219
243
|
}
|
|
220
|
-
active.clear();
|
|
221
244
|
}
|
|
222
245
|
const LOGIN_HINT = " — with --config-dir, auth comes from ANTHROPIC_API_KEY or CLAUDE_CODE_OAUTH_TOKEN (claude setup-token)";
|
|
223
246
|
/** A fresh config dir has no credentials; point the user at the env vars. */
|
package/dist/cli.js
CHANGED
|
@@ -670,8 +670,9 @@ if (invokedDirectly()) {
|
|
|
670
670
|
// agent runs are detached process groups that Ctrl+C does not reach
|
|
671
671
|
for (const [signal, code] of [["SIGINT", 130], ["SIGTERM", 143]]) {
|
|
672
672
|
process.once(signal, () => {
|
|
673
|
-
|
|
674
|
-
process.exit(code);
|
|
673
|
+
// a second Ctrl+C during the grace period exits at once
|
|
674
|
+
process.once(signal, () => process.exit(code));
|
|
675
|
+
void abortActiveRuns().finally(() => process.exit(code));
|
|
675
676
|
});
|
|
676
677
|
}
|
|
677
678
|
main(process.argv.slice(2)).then((code) => {
|