caproom 0.5.0 → 0.6.0
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/bin/caproom +247 -0
- package/bin/caproom-mcp.js +5 -2
- package/bin/caproom.ps1 +58 -0
- package/package.json +4 -1
package/bin/caproom
CHANGED
|
@@ -71,6 +71,8 @@ examples:
|
|
|
71
71
|
caproom wake 12345
|
|
72
72
|
caproom top --json [--pid <pid>] [--park-min-mb <mb>]
|
|
73
73
|
caproom watch [--threshold-mb <mb>] [--auto-park] [--auto-wake-free-pct <pct>] [--json] <pid...>
|
|
74
|
+
caproom setup [--guard] [--threshold <pct>] [--uninstall]
|
|
75
|
+
caproom freemem
|
|
74
76
|
caproom init claude --limit 6144 --grace 10
|
|
75
77
|
EOF
|
|
76
78
|
exit "$code"
|
|
@@ -443,9 +445,254 @@ cmd_guard() {
|
|
|
443
445
|
done
|
|
444
446
|
}
|
|
445
447
|
|
|
448
|
+
# ---- terminal bind: setup / unbind ------------------------------------
|
|
449
|
+
# Binds headroom management to every interactive shell in ANY terminal
|
|
450
|
+
# (Terminal.app, iTerm2, Ghostty, ...) by writing ONE integration file
|
|
451
|
+
# per shell under ~/.caproom/ and marker-patching the rc files. Idempotent,
|
|
452
|
+
# backed up, reversible with `caproom unbind`. Never runs automatically:
|
|
453
|
+
# npm postinstall only prints a hint.
|
|
454
|
+
|
|
455
|
+
CAPROOM_DIR="${CAPROOM_DIR:-$HOME/.caproom}"
|
|
456
|
+
|
|
457
|
+
setup_shell_sh() {
|
|
458
|
+
cat > "$CAPROOM_DIR/shell.sh" << 'EOF'
|
|
459
|
+
# caproom shell integration — regenerated by `caproom setup`; edits here
|
|
460
|
+
# are overwritten. Source of truth: bin/caproom (setup_shell_sh).
|
|
461
|
+
|
|
462
|
+
caproom_freemem_pct() { command caproom freemem 2>/dev/null; }
|
|
463
|
+
|
|
464
|
+
caproom_headroom_check() {
|
|
465
|
+
local pct last now
|
|
466
|
+
pct=$(caproom_freemem_pct) || return 0
|
|
467
|
+
[ -n "$pct" ] || return 0
|
|
468
|
+
[ "$pct" -lt "${CAPROOM_HEADROOM_WARN:-20}" ] || return 0
|
|
469
|
+
last=$(cat "${TMPDIR:-/tmp}/caproom-headroom-last" 2>/dev/null || echo 0)
|
|
470
|
+
now=$(date +%s)
|
|
471
|
+
[ $(( now - ${last:-0} )) -ge 60 ] || return 0
|
|
472
|
+
echo "$now" > "${TMPDIR:-/tmp}/caproom-headroom-last" 2>/dev/null
|
|
473
|
+
echo "caproom: headroom low (${pct}% free) — check 'caproom top' before launching heavy work"
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
if [ -n "$ZSH_VERSION" ]; then
|
|
477
|
+
autoload -Uz add-zsh-hook
|
|
478
|
+
add-zsh-hook precmd caproom_headroom_check
|
|
479
|
+
elif [ -n "$BASH_VERSION" ]; then
|
|
480
|
+
case ";$PROMPT_COMMAND;" in
|
|
481
|
+
*caproom_headroom_check*) ;;
|
|
482
|
+
*) PROMPT_COMMAND="caproom_headroom_check${PROMPT_COMMAND:+;$PROMPT_COMMAND}" ;;
|
|
483
|
+
esac
|
|
484
|
+
fi
|
|
485
|
+
|
|
486
|
+
# Opt-in auto-wrap: CAPROOM_AUTO_WRAP="claude,codex,opencode" gives every
|
|
487
|
+
# listed command a <name>_capped twin running under $CAPROOM_LIMIT_MB.
|
|
488
|
+
# The bare name is aliased ONLY with CAPROOM_AUTO_ALIAS=1 — never hijack a
|
|
489
|
+
# command the user did not consent to wrap.
|
|
490
|
+
if [ -n "${CAPROOM_AUTO_WRAP:-}" ]; then
|
|
491
|
+
for _cr_cmd in $(echo "${CAPROOM_AUTO_WRAP}" | tr ',' ' '); do
|
|
492
|
+
_cr_fn="$(printf '%s' "$_cr_cmd" | sed 's/[-.]/_/g')_capped"
|
|
493
|
+
eval "$(printf "%s() { command caproom --limit \"\${CAPROOM_LIMIT_MB:-4096}\" --grace \"\${CAPROOM_GRACE:-5}\" -- '%s' \"\$@\"; }" "$_cr_fn" "$(printf '%s' "$_cr_cmd" | sed "s/'/'\\\\''/g")")"
|
|
494
|
+
if [ "${CAPROOM_AUTO_ALIAS:-0}" = "1" ]; then
|
|
495
|
+
alias "$_cr_cmd=$_cr_fn"
|
|
496
|
+
fi
|
|
497
|
+
done
|
|
498
|
+
unset _cr_cmd _cr_fn
|
|
499
|
+
fi
|
|
500
|
+
EOF
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
setup_shell_fish() {
|
|
504
|
+
cat > "$CAPROOM_DIR/shell.fish" << 'EOF'
|
|
505
|
+
# caproom fish integration — regenerated by `caproom setup`.
|
|
506
|
+
function __caproom_freemem
|
|
507
|
+
command caproom freemem 2>/dev/null
|
|
508
|
+
end
|
|
509
|
+
|
|
510
|
+
function __caproom_headroom_check --on-event fish_prompt
|
|
511
|
+
set -l pct (__caproom_freemem)
|
|
512
|
+
or return
|
|
513
|
+
test -n "$pct"; or return
|
|
514
|
+
set -l warn 20
|
|
515
|
+
if set -q CAPROOM_HEADROOM_WARN
|
|
516
|
+
set warn $CAPROOM_HEADROOM_WARN
|
|
517
|
+
end
|
|
518
|
+
if test "$pct" -lt "$warn"
|
|
519
|
+
set -l stamp /tmp/caproom-headroom-last
|
|
520
|
+
set -l now (date +%s)
|
|
521
|
+
set -l last 0
|
|
522
|
+
if test -f $stamp
|
|
523
|
+
set last (cat $stamp)
|
|
524
|
+
end
|
|
525
|
+
if test (math "$now - $last") -ge 60
|
|
526
|
+
echo $now > $stamp
|
|
527
|
+
echo "caproom: headroom low ($pct% free) — check 'caproom top' before launching heavy work"
|
|
528
|
+
end
|
|
529
|
+
end
|
|
530
|
+
end
|
|
531
|
+
EOF
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
setup_shell_ps1() {
|
|
535
|
+
cat > "$CAPROOM_DIR/shell.ps1" << 'EOF'
|
|
536
|
+
# caproom PowerShell integration — regenerated by `caproom setup` (Windows).
|
|
537
|
+
function global:caproom_freemem_pct {
|
|
538
|
+
$os = Get-CimInstance Win32_OperatingSystem
|
|
539
|
+
[int]($os.FreePhysicalMemory * 100 / $os.TotalVisibleMemorySize)
|
|
540
|
+
}
|
|
541
|
+
$global:__caproomLastWarn = 0
|
|
542
|
+
function global:prompt {
|
|
543
|
+
$pct = caproom_freemem_pct
|
|
544
|
+
$now = [DateTimeOffset]::Now.ToUnixTimeSeconds()
|
|
545
|
+
if ($pct -lt (${CAPROOM_HEADROOM_WARN:-20}) -and ($now - $script:__caproomLastWarn) -ge 60) {
|
|
546
|
+
$script:__caproomLastWarn = $now
|
|
547
|
+
Write-Host "caproom: headroom low ($pct% free) — check 'caproom top' before launching heavy work" -ForegroundColor Yellow
|
|
548
|
+
}
|
|
549
|
+
"PS $($executionContext.SessionState.Path.CurrentLocation)> "
|
|
550
|
+
}
|
|
551
|
+
EOF
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
rc_targets() {
|
|
555
|
+
# Prints "path<TAB>required" pairs for every rc we manage. Only rcs that
|
|
556
|
+
# already exist are patched, EXCEPT the login shell's own rc which is
|
|
557
|
+
# created if missing — never invent configs for shells you don't use.
|
|
558
|
+
local zshrc="${ZDOTDIR:-$HOME/.zshrc}"
|
|
559
|
+
printf '%s\t%s\n' "$zshrc" "shell"
|
|
560
|
+
[[ -f "$HOME/.bashrc" ]] && printf '%s\t%s\n' "$HOME/.bashrc" "optional"
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
patch_rc_file() {
|
|
564
|
+
local rc="$1"
|
|
565
|
+
[[ -f "$rc" ]] || touch "$rc"
|
|
566
|
+
grep -q "# >>> caproom >>>" "$rc" && return 0
|
|
567
|
+
cp "$rc" "$rc.caproom.bak.$(date +%Y%m%d%H%M%S)"
|
|
568
|
+
{
|
|
569
|
+
echo ""
|
|
570
|
+
echo "# >>> caproom >>>"
|
|
571
|
+
echo '[ -f ~/.caproom/shell.sh ] && source ~/.caproom/shell.sh'
|
|
572
|
+
echo "# <<< caproom <<<"
|
|
573
|
+
} >> "$rc"
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
patch_rc_file_fish() {
|
|
577
|
+
local rc="$HOME/.config/fish/config.fish"
|
|
578
|
+
mkdir -p "$(dirname "$rc")" 2>/dev/null
|
|
579
|
+
[[ -f "$rc" ]] || return 0 # don't invent fish config unless it exists
|
|
580
|
+
grep -q "# caproom (fish)" "$rc" && return 0
|
|
581
|
+
cp "$rc" "$rc.caproom.bak.$(date +%Y%m%d%H%M%S)"
|
|
582
|
+
{
|
|
583
|
+
echo ""
|
|
584
|
+
echo "# caproom (fish)"
|
|
585
|
+
echo '[ -f ~/.caproom/shell.fish ] && source ~/.caproom/shell.fish'
|
|
586
|
+
} >> "$rc"
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
install_guard_daemon() {
|
|
590
|
+
local threshold="$1"
|
|
591
|
+
local bin_path
|
|
592
|
+
bin_path=$(command -v caproom || true)
|
|
593
|
+
[[ -n "$bin_path" ]] || { echo "caproom setup: cannot resolve caproom binary for daemon" >&2; return 1; }
|
|
594
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
595
|
+
local plist="$HOME/Library/LaunchAgents/com.caproom.guard.plist"
|
|
596
|
+
mkdir -p "$HOME/Library/LaunchAgents"
|
|
597
|
+
cat > "$plist" << EOF
|
|
598
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
599
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
600
|
+
<plist version="1.0"><dict>
|
|
601
|
+
<key>Label</key><string>com.caproom.guard</string>
|
|
602
|
+
<key>ProgramArguments</key><array>
|
|
603
|
+
<string>/usr/bin/env</string><string>bash</string><string>$bin_path</string>
|
|
604
|
+
<string>guard</string><string>--threshold</string><string>$threshold</string><string>--interval</string><string>15</string>
|
|
605
|
+
</array>
|
|
606
|
+
<key>RunAtLoad</key><true/>
|
|
607
|
+
<key>KeepAlive</key><true/>
|
|
608
|
+
</dict></plist>
|
|
609
|
+
EOF
|
|
610
|
+
echo "caproom setup: guard daemon installed -> $plist"
|
|
611
|
+
echo " load now: launchctl load $plist"
|
|
612
|
+
echo " unload: launchctl unload $plist"
|
|
613
|
+
else
|
|
614
|
+
local unit="$HOME/.config/systemd/user/caproom-guard.service"
|
|
615
|
+
mkdir -p "$HOME/.config/systemd/user"
|
|
616
|
+
cat > "$unit" << EOF
|
|
617
|
+
[Unit]
|
|
618
|
+
Description=caproom memory guard
|
|
619
|
+
|
|
620
|
+
[Service]
|
|
621
|
+
ExecStart=/usr/bin/env bash $bin_path guard --threshold $threshold --interval 15
|
|
622
|
+
Restart=on-failure
|
|
623
|
+
|
|
624
|
+
[Install]
|
|
625
|
+
WantedBy=default.target
|
|
626
|
+
EOF
|
|
627
|
+
echo "caproom setup: guard service installed -> $unit"
|
|
628
|
+
echo " start now: systemctl --user enable --now caproom-guard.service"
|
|
629
|
+
echo " stop: systemctl --user disable --now caproom-guard.service"
|
|
630
|
+
fi
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
cmd_setup() {
|
|
634
|
+
local guard="" threshold=10 do_unbind=0
|
|
635
|
+
while [[ $# -gt 0 ]]; do
|
|
636
|
+
case "$1" in
|
|
637
|
+
--guard) guard="$threshold"; shift ;;
|
|
638
|
+
--threshold) threshold="$2"; shift 2 ;;
|
|
639
|
+
--uninstall|--unbind) do_unbind=1; shift ;;
|
|
640
|
+
*) echo "caproom setup: unknown option $1" >&2; exit 1 ;;
|
|
641
|
+
esac
|
|
642
|
+
done
|
|
643
|
+
|
|
644
|
+
if [[ "$do_unbind" -eq 1 ]]; then
|
|
645
|
+
local rc removed=0
|
|
646
|
+
while IFS=$'\t' read -r rc _req; do
|
|
647
|
+
[[ -f "$rc" ]] || continue
|
|
648
|
+
if grep -q "# >>> caproom >>>" "$rc"; then
|
|
649
|
+
awk '/^# >>> caproom >>>$/{skip=1;next} /^# <<< caproom <<<$/{skip=0;next} !skip' "$rc" > "$rc.cr.tmp" && mv "$rc.cr.tmp" "$rc"
|
|
650
|
+
removed=$(( removed + 1 ))
|
|
651
|
+
fi
|
|
652
|
+
done < <(rc_targets)
|
|
653
|
+
if grep -q "# caproom (fish)" "$HOME/.config/fish/config.fish" 2>/dev/null; then
|
|
654
|
+
awk '/^# caproom \(fish\)$/{getline; skip=1; next} !skip' "$HOME/.config/fish/config.fish" > /tmp/cr-fish.tmp 2>/dev/null \
|
|
655
|
+
&& mv /tmp/cr-fish.tmp "$HOME/.config/fish/config.fish"
|
|
656
|
+
removed=$(( removed + 1 ))
|
|
657
|
+
fi
|
|
658
|
+
echo "caproom unbind: markers removed from $removed file(s); backups kept as *.caproom.bak.*"
|
|
659
|
+
echo " integration files left in $CAPROOM_DIR (rm -rf to purge)"
|
|
660
|
+
return 0
|
|
661
|
+
fi
|
|
662
|
+
|
|
663
|
+
mkdir -p "$CAPROOM_DIR"
|
|
664
|
+
setup_shell_sh
|
|
665
|
+
setup_shell_fish
|
|
666
|
+
[[ "$(uname)" != "Darwin" ]] || setup_shell_ps1
|
|
667
|
+
|
|
668
|
+
local rc req patched=0
|
|
669
|
+
while IFS=$'\t' read -r rc req; do
|
|
670
|
+
if patch_rc_file "$rc"; then patched=$(( patched + 1 )); fi
|
|
671
|
+
done < <(rc_targets)
|
|
672
|
+
patch_rc_file_fish
|
|
673
|
+
|
|
674
|
+
echo "caproom setup: bound to your shells via $CAPROOM_DIR/"
|
|
675
|
+
echo " shell.sh zsh + bash (headroom warning on every prompt, opt-in auto-wrap)"
|
|
676
|
+
echo " shell.fish fish equivalent"
|
|
677
|
+
echo " patched rc files: $patched (backups alongside as *.caproom.bak.*)"
|
|
678
|
+
echo ""
|
|
679
|
+
echo "auto-wrap usage:"
|
|
680
|
+
echo ' export CAPROOM_AUTO_WRAP="claude,codex,opencode" # creates <cmd>_capped twins'
|
|
681
|
+
echo ' export CAPROOM_AUTO_ALIAS=1 # ALSO shadow bare names (explicit consent)'
|
|
682
|
+
echo " export CAPROOM_LIMIT_MB=8192 # per-shell budget"
|
|
683
|
+
echo ""
|
|
684
|
+
echo "new terminals pick this up immediately; current ones: source ~/.caproom/shell.sh"
|
|
685
|
+
|
|
686
|
+
if [[ -n "$guard" ]]; then
|
|
687
|
+
echo ""
|
|
688
|
+
install_guard_daemon "$threshold"
|
|
689
|
+
fi
|
|
690
|
+
}
|
|
446
691
|
case "${1:-}" in
|
|
447
692
|
park) shift; cmd_park "$@"; exit 0 ;;
|
|
448
693
|
wake) shift; cmd_wake "$@"; exit 0 ;;
|
|
694
|
+
freemem) mem_free_pct; exit 0 ;;
|
|
695
|
+
setup|bind|unbind) shift; cmd_setup "$@"; exit 0 ;;
|
|
449
696
|
status) shift; cmd_status "$@"; exit 0 ;;
|
|
450
697
|
top) shift; cmd_top "$@"; exit 0 ;;
|
|
451
698
|
watch) shift; cmd_watch "$@"; exit 0 ;;
|
package/bin/caproom-mcp.js
CHANGED
|
@@ -131,11 +131,14 @@ function callTool(name, args) {
|
|
|
131
131
|
if (args.docker) { a.push('--docker'); if (args.image) a.push('--image', String(args.image)); }
|
|
132
132
|
a.push('--');
|
|
133
133
|
const r = caproom(a.concat(cmd), { timeout: Math.max(60000, (args.timeout_ms || 300000)) });
|
|
134
|
-
|
|
134
|
+
const errText = (r.stderr || '');
|
|
135
|
+
const capped = /exceeded .* cap/.test(errText);
|
|
136
|
+
let verdict;
|
|
135
137
|
if (r.status === 137 || r.signal === 'SIGKILL') verdict = 'RESULT: KILLED BY CAP (exit 137)';
|
|
138
|
+
else if (capped && (r.status === 143 || r.signal === 'SIGTERM')) verdict = 'RESULT: CAPPED — tree killed during grace (SIGTERM honored, exit 143)';
|
|
136
139
|
else if (r.status === 143 || r.signal === 'SIGTERM') verdict = 'RESULT: terminated during grace (SIGTERM honored)';
|
|
137
140
|
else verdict = 'RESULT: exit=' + r.status;
|
|
138
|
-
return text(verdict + '\n--- stderr ---\n' + (
|
|
141
|
+
return text(verdict + '\n--- stderr ---\n' + (errText.slice(-4000) || '(empty)'));
|
|
139
142
|
}
|
|
140
143
|
default:
|
|
141
144
|
throw new Error('unknown tool: ' + name);
|
package/bin/caproom.ps1
CHANGED
|
@@ -406,10 +406,68 @@ function Invoke-Capped {
|
|
|
406
406
|
|
|
407
407
|
if ($args.Count -eq 0) { Show-Usage }
|
|
408
408
|
|
|
409
|
+
function Invoke-Setup {
|
|
410
|
+
# Bind headroom management to PowerShell sessions in ANY terminal:
|
|
411
|
+
# writes ~/.caproom/shell.ps1 (single source) and marker-patches
|
|
412
|
+
# $PROFILE. Idempotent, backs up the profile, reversible via
|
|
413
|
+
# `caproom setup --uninstall`. Never runs on npm install.
|
|
414
|
+
$dir = Join-Path $HOME '.caproom'
|
|
415
|
+
New-Item -ItemType Directory -Force -Path $dir | Out-Null
|
|
416
|
+
|
|
417
|
+
@'
|
|
418
|
+
# caproom PowerShell integration — regenerated by `caproom setup`.
|
|
419
|
+
function global:caproom_freemem_pct {
|
|
420
|
+
$os = Get-CimInstance Win32_OperatingSystem
|
|
421
|
+
[int]($os.FreePhysicalMemory * 100 / $os.TotalVisibleMemorySize)
|
|
422
|
+
}
|
|
423
|
+
$global:__caproomLastWarn = 0
|
|
424
|
+
function global:prompt {
|
|
425
|
+
try {
|
|
426
|
+
$pct = caproom_freemem_pct
|
|
427
|
+
$now = [DateTimeOffset]::Now.ToUnixTimeSeconds()
|
|
428
|
+
$warn = if ($env:CAPROOM_HEADROOM_WARN) { [int]$env:CAPROOM_HEADROOM_WARN } else { 20 }
|
|
429
|
+
if ($pct -lt $warn -and ($now - $script:__caproomLastWarn) -ge 60) {
|
|
430
|
+
$script:__caproomLastWarn = $now
|
|
431
|
+
Write-Host "caproom: headroom low ($pct% free) - check 'caproom top' before launching heavy work" -ForegroundColor Yellow
|
|
432
|
+
}
|
|
433
|
+
} catch {}
|
|
434
|
+
"PS $($executionContext.SessionState.Path.CurrentLocation)> "
|
|
435
|
+
}
|
|
436
|
+
'@ | Set-Content -Encoding UTF8 (Join-Path $dir 'shell.ps1')
|
|
437
|
+
|
|
438
|
+
$profilePath = $PROFILE.CurrentUserAllHosts
|
|
439
|
+
if (-not (Test-Path $profilePath)) { New-Item -ItemType File -Force -Path $profilePath | Out-Null }
|
|
440
|
+
$content = Get-Content $profilePath -Raw -ErrorAction SilentlyContinue
|
|
441
|
+
if ($content -notmatch '# >>> caproom >>>') {
|
|
442
|
+
Copy-Item $profilePath "$profilePath.caproom.bak.$(Get-Date -Format yyyyMMddHHmmss)"
|
|
443
|
+
Add-Content $profilePath @'
|
|
444
|
+
|
|
445
|
+
# >>> caproom >>>
|
|
446
|
+
. "$HOME\.caproom\shell.ps1"
|
|
447
|
+
# <<< caproom <<<
|
|
448
|
+
'@
|
|
449
|
+
[Console]::Error.WriteLine("caproom setup: patched $profilePath (backup alongside)")
|
|
450
|
+
} else {
|
|
451
|
+
[Console]::Error.WriteLine('caproom setup: profile already bound')
|
|
452
|
+
}
|
|
453
|
+
[Console]::Error.WriteLine('caproom setup: shell.ps1 written to ' + $dir + ' — new terminals pick it up automatically')
|
|
454
|
+
}
|
|
455
|
+
|
|
409
456
|
switch ($args[0]) {
|
|
410
457
|
'help' { Show-Usage -AsHelp }
|
|
411
458
|
'-h' { Show-Usage -AsHelp }
|
|
412
459
|
'--help' { Show-Usage -AsHelp }
|
|
460
|
+
'setup' {
|
|
461
|
+
Invoke-Setup; exit 0
|
|
462
|
+
}
|
|
463
|
+
'bind' {
|
|
464
|
+
Invoke-Setup; exit 0
|
|
465
|
+
}
|
|
466
|
+
'freemem' {
|
|
467
|
+
$os = Get-CimInstance Win32_OperatingSystem
|
|
468
|
+
Write-Output ([int]($os.FreePhysicalMemory * 100 / $os.TotalVisibleMemorySize))
|
|
469
|
+
exit 0
|
|
470
|
+
}
|
|
413
471
|
'park' {
|
|
414
472
|
if ($args.Count -lt 2) { [Console]::Error.WriteLine('usage: caproom park <pid>'); exit 1 }
|
|
415
473
|
Invoke-Park -TargetPid ([int]$args[1]); exit 0
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "caproom",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Memory-cap any command (AI coding agents, builds, background jobs) on macOS, Linux, and Windows — real enforcement via Docker cgroups, Windows Job Objects, or a polling watchdog, plus park/wake to reclaim idle process memory without killing.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"caproom": "bin/caproom.js",
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
"linux",
|
|
29
29
|
"win32"
|
|
30
30
|
],
|
|
31
|
+
"scripts": {
|
|
32
|
+
"postinstall": "node -e \"process.stdout.write('caproom: optional next step — run `caproom setup` to bind headroom management to your shells (never modifies rc files on install)\\n')\""
|
|
33
|
+
},
|
|
31
34
|
"license": "MIT",
|
|
32
35
|
"repository": {
|
|
33
36
|
"type": "git",
|