@wrongstack/tools 0.274.0 → 0.275.1
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/audit.js +57 -19
- package/dist/audit.js.map +1 -1
- package/dist/bash.js +166 -83
- package/dist/bash.js.map +1 -1
- package/dist/builtin.js +503 -119
- package/dist/builtin.js.map +1 -1
- package/dist/circuit-breaker.js +1 -0
- package/dist/circuit-breaker.js.map +1 -1
- package/dist/edit.js +1 -1
- package/dist/edit.js.map +1 -1
- package/dist/exec.js +136 -38
- package/dist/exec.js.map +1 -1
- package/dist/fetch.js +9 -1
- package/dist/fetch.js.map +1 -1
- package/dist/format.js +57 -19
- package/dist/format.js.map +1 -1
- package/dist/index.d.ts +37 -1
- package/dist/index.js +514 -130
- package/dist/index.js.map +1 -1
- package/dist/install.js +65 -19
- package/dist/install.js.map +1 -1
- package/dist/lint.js +57 -19
- package/dist/lint.js.map +1 -1
- package/dist/pack.js +501 -118
- package/dist/pack.js.map +1 -1
- package/dist/process-registry.d.ts +30 -0
- package/dist/process-registry.js +57 -19
- package/dist/process-registry.js.map +1 -1
- package/dist/search.js.map +1 -1
- package/dist/test.js +57 -19
- package/dist/test.js.map +1 -1
- package/dist/typecheck.js +57 -19
- package/dist/typecheck.js.map +1 -1
- package/dist/write.js +2 -2
- package/dist/write.js.map +1 -1
- package/package.json +2 -2
package/dist/test.js
CHANGED
|
@@ -268,6 +268,7 @@ var CircuitBreaker = class {
|
|
|
268
268
|
if (this.state === "open") return;
|
|
269
269
|
this.state = "open";
|
|
270
270
|
this.openedAt = Date.now();
|
|
271
|
+
this.window = [];
|
|
271
272
|
try {
|
|
272
273
|
this.onTrip?.();
|
|
273
274
|
} catch {
|
|
@@ -307,7 +308,7 @@ var SENSITIVE_FLAG_PATTERNS = [
|
|
|
307
308
|
/--(?:token|password|passwd|pwd|secret|api[-_]?key|api[-_]?secret|auth|credential|private[-_]?key|access[-_]?key|github[-_]?token|gh[-_]?token|bearer|jwt|oauth|pin|pincode|passphrase|access[-_]?token)(?:[=\s,][^\s]*)?/gi,
|
|
308
309
|
// -f "value" style short flags
|
|
309
310
|
/(?<!\w)-t(?:\s+|\s*=\s*)[^\s,]+/,
|
|
310
|
-
/(?<!\w)-
|
|
311
|
+
/(?<!\w)-(?:p|password)(?:\s+|\s*=\s*)[^\s,]+/gi,
|
|
311
312
|
// env var–style secrets: TOKEN=x, API_KEY=y, etc.
|
|
312
313
|
/(?:TOKEN|API_KEY|API_SECRET|AUTH_TOKEN|GITHUB_TOKEN|GH_TOKEN|BEARER|JWT|OAUTH|CREDENTIAL|SECRET|PRIVATE_KEY|PASSWORD|PASSWD)\s*[=:]\s*[^\s,]+/gi,
|
|
313
314
|
// Generic high-entropy look: base64 strings >32 chars or hex strings >32 digits — but only
|
|
@@ -368,12 +369,35 @@ var ProcessRegistryImpl = class {
|
|
|
368
369
|
register(info) {
|
|
369
370
|
this.processes.set(info.pid, { ...info, killed: false, protected: info.protected ?? false });
|
|
370
371
|
}
|
|
372
|
+
_isSafeSignalPid(pid) {
|
|
373
|
+
return Number.isInteger(pid) && pid > 1 && pid !== process.pid && pid !== process.ppid;
|
|
374
|
+
}
|
|
375
|
+
_canSignalProcessGroup(p) {
|
|
376
|
+
return os.platform() !== "win32" && p.processGroupLeader === true && this._isSafeSignalPid(p.pid) && typeof p.child.pid === "number" && p.child.pid === p.pid;
|
|
377
|
+
}
|
|
378
|
+
_killChildDirect(p, signal) {
|
|
379
|
+
try {
|
|
380
|
+
p.child.kill(signal);
|
|
381
|
+
} catch {
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
_killPosix(p, signal) {
|
|
385
|
+
if (this._canSignalProcessGroup(p)) {
|
|
386
|
+
try {
|
|
387
|
+
process.kill(-p.pid, signal);
|
|
388
|
+
return;
|
|
389
|
+
} catch {
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
this._killChildDirect(p, signal);
|
|
393
|
+
}
|
|
371
394
|
/** Unregister a process by PID. Called on 'close' / 'exit' events. */
|
|
372
395
|
unregister(pid) {
|
|
373
396
|
this.processes.delete(pid);
|
|
374
397
|
}
|
|
375
398
|
/** Get a single process by PID. */
|
|
376
399
|
get(pid) {
|
|
400
|
+
this._pruneStale(pid);
|
|
377
401
|
return this.processes.get(pid);
|
|
378
402
|
}
|
|
379
403
|
/** Get all tracked processes. */
|
|
@@ -537,6 +561,7 @@ var ProcessRegistryImpl = class {
|
|
|
537
561
|
* Returns true if the process was found and kill was attempted.
|
|
538
562
|
*/
|
|
539
563
|
kill(pid, opts = {}) {
|
|
564
|
+
this._pruneStale(pid);
|
|
540
565
|
const p = this.processes.get(pid);
|
|
541
566
|
if (!p) return false;
|
|
542
567
|
if (p.killed) return true;
|
|
@@ -566,27 +591,12 @@ var ProcessRegistryImpl = class {
|
|
|
566
591
|
}
|
|
567
592
|
try {
|
|
568
593
|
if (force) {
|
|
569
|
-
|
|
570
|
-
process.kill(-pid, "SIGKILL");
|
|
571
|
-
} catch {
|
|
572
|
-
p.child.kill("SIGKILL");
|
|
573
|
-
}
|
|
594
|
+
this._killPosix(p, "SIGKILL");
|
|
574
595
|
} else {
|
|
575
|
-
|
|
576
|
-
process.kill(-pid, "SIGTERM");
|
|
577
|
-
} catch {
|
|
578
|
-
p.child.kill("SIGTERM");
|
|
579
|
-
}
|
|
596
|
+
this._killPosix(p, "SIGTERM");
|
|
580
597
|
const timer = setTimeout(() => {
|
|
581
598
|
if (this.processes.has(pid) && !p.child.killed) {
|
|
582
|
-
|
|
583
|
-
process.kill(-pid, "SIGKILL");
|
|
584
|
-
} catch {
|
|
585
|
-
try {
|
|
586
|
-
p.child.kill("SIGKILL");
|
|
587
|
-
} catch {
|
|
588
|
-
}
|
|
589
|
-
}
|
|
599
|
+
this._killPosix(p, "SIGKILL");
|
|
590
600
|
}
|
|
591
601
|
}, graceMs);
|
|
592
602
|
timer.unref?.();
|
|
@@ -621,6 +631,34 @@ var ProcessRegistryImpl = class {
|
|
|
621
631
|
}
|
|
622
632
|
return killed;
|
|
623
633
|
}
|
|
634
|
+
/**
|
|
635
|
+
* Check whether a tracked process entry is stale — the child has exited
|
|
636
|
+
* (exitCode !== null) AND it's been in the registry long enough that the
|
|
637
|
+
* OS may have reused the PID for a new, unrelated process.
|
|
638
|
+
*
|
|
639
|
+
* P3 #24 (before-release.md): on POSIX, PIDs are reused after process
|
|
640
|
+
* exit. If a tracked process exits but its 'close' event hasn't fired yet
|
|
641
|
+
* (or was missed), the registry still holds the entry. A new process
|
|
642
|
+
* gets the same PID, and PID-based lookups (get, kill, shouldBlockKill)
|
|
643
|
+
* may incorrectly protect or target the wrong process.
|
|
644
|
+
*
|
|
645
|
+
* The 60s threshold is conservative — the OS typically waits much longer
|
|
646
|
+
* before reusing a PID, but we want to clean up before that becomes a risk.
|
|
647
|
+
*/
|
|
648
|
+
_isStaleEntry(entry) {
|
|
649
|
+
return entry.child.exitCode !== null && Date.now() - entry.startedAt > 6e4;
|
|
650
|
+
}
|
|
651
|
+
/**
|
|
652
|
+
* Remove a stale entry for a specific PID before any PID-based lookup.
|
|
653
|
+
* This prevents PID reuse from causing the registry to act on a dead
|
|
654
|
+
* process that has been replaced by a new one with the same PID.
|
|
655
|
+
*/
|
|
656
|
+
_pruneStale(pid) {
|
|
657
|
+
const entry = this.processes.get(pid);
|
|
658
|
+
if (entry && this._isStaleEntry(entry)) {
|
|
659
|
+
this.processes.delete(pid);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
624
662
|
};
|
|
625
663
|
var _registry;
|
|
626
664
|
function getProcessRegistry() {
|