plc-checkweigher 1.28.1 → 1.29.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/cli.js CHANGED
@@ -86,35 +86,15 @@ function buildBanner() {
86
86
  return lines.join('\n');
87
87
  }
88
88
 
89
- const STAMP_FILE = '/tmp/.plc-checkweigher-postinstall';
90
-
91
89
  function showAccessDenied() {
92
- const banner = buildBanner();
93
- const isPostinstall = process.env.npm_lifecycle_event === 'postinstall';
94
-
95
- if (isPostinstall) {
96
- // npm 7+ pipes away stdout/stderr — write directly to /dev/tty.
97
- try {
98
- const fd = fs.openSync('/dev/tty', 'w');
99
- fs.writeSync(fd, banner + '\n');
100
- fs.closeSync(fd);
101
- } catch (_) {}
102
- // Always stamp regardless of whether /dev/tty was available,
103
- // so the CLI invocation npx runs right after skips the banner.
104
- try { fs.writeFileSync(STAMP_FILE, String(Date.now())); } catch (_) {}
90
+ // During npm install the binary hasn't been invoked yet — exit silently.
91
+ // The banner only makes sense when someone runs the binary directly
92
+ // without a valid subcommand (e.g. bare `npx plc-checkweigher`).
93
+ if (process.env.npm_lifecycle_event === 'postinstall') {
105
94
  process.exit(0);
106
95
  }
107
96
 
108
- // Suppress duplicate: if postinstall printed the banner within the last 3s, skip.
109
- try {
110
- const ts = parseInt(fs.readFileSync(STAMP_FILE, 'utf8'), 10);
111
- if (Date.now() - ts < 3000) {
112
- fs.unlinkSync(STAMP_FILE);
113
- process.exit(1);
114
- }
115
- } catch (_) {}
116
-
117
- console.log(banner);
97
+ console.log(buildBanner());
118
98
  process.exit(1);
119
99
  }
120
100
 
@@ -1450,27 +1450,29 @@ PYEOF
1450
1450
  ulog "CONFIG: journal OK"
1451
1451
  fi
1452
1452
 
1453
- # 9b. Web maintenance sudoers rule (dashboard FIX button)
1453
+ # 9b. Web maintenance sudoers rule (dashboard terminal)
1454
1454
  spin_start "Web maintenance sudoers rule"
1455
1455
  _SUDOERS_F="/etc/sudoers.d/010_plc-web-fix"
1456
- if [[ ! -f "$_SUDOERS_F" ]]; then
1456
+ # Content-aware: rewrite if missing OR still the old fix-only version
1457
+ if [[ ! -f "$_SUDOERS_F" ]] \
1458
+ || ! sudo grep -q "plc_checkweigher update" "$_SUDOERS_F" 2>/dev/null; then
1457
1459
  cat > /tmp/010_plc-web-fix << 'SUDOEOF'
1458
- # Web dashboard maintenance console — allows the locked, root-owned CLI
1459
- # to run its fix command from plc_web (User=pi). Scope: fix only.
1460
- pi ALL=(root) NOPASSWD: /usr/local/bin/plc_checkweigher fix, /usr/local/bin/plc_checkweigher fix *
1460
+ # Web dashboard maintenance terminal — allows the locked, root-owned CLI
1461
+ # to run whitelisted maintenance subcommands from plc_web (User=pi).
1462
+ pi ALL=(root) NOPASSWD: /usr/local/bin/plc_checkweigher fix, /usr/local/bin/plc_checkweigher fix *, /usr/local/bin/plc_checkweigher status, /usr/local/bin/plc_checkweigher restart, /usr/local/bin/plc_checkweigher start, /usr/local/bin/plc_checkweigher stop, /usr/local/bin/plc_checkweigher update
1461
1463
  SUDOEOF
1462
1464
  if sudo visudo -c -f /tmp/010_plc-web-fix &>/dev/null; then
1463
1465
  sudo cp /tmp/010_plc-web-fix "$_SUDOERS_F"
1464
1466
  sudo chmod 440 "$_SUDOERS_F"
1465
- spin_ok "Sudoers rule installed (web FIX button enabled)"
1466
- ulog "FIXED: web maintenance sudoers rule installed"
1467
+ spin_ok "Sudoers rule installed/upgraded (web terminal enabled)"
1468
+ ulog "FIXED: web maintenance sudoers rule installed/upgraded"
1467
1469
  else
1468
1470
  spin_warn "Sudoers rule failed validation — skipped"
1469
1471
  ulog "WARN: sudoers rule validation failed"
1470
1472
  fi
1471
1473
  rm -f /tmp/010_plc-web-fix
1472
1474
  else
1473
- spin_ok "Sudoers rule present"
1475
+ spin_ok "Sudoers rule current"
1474
1476
  ulog "CONFIG: web sudoers OK"
1475
1477
  fi
1476
1478
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plc-checkweigher",
3
- "version": "1.28.1",
3
+ "version": "1.29.0",
4
4
  "description": "One-command installer for the PLC Check-Weigher system on Raspberry Pi (PREEMPT_RT kernel, Python stack, WiFi, SMB, systemd RT services)",
5
5
  "scripts": {
6
6
  "postinstall": "node bin/cli.js"
package/setup.sh CHANGED
@@ -169,19 +169,21 @@ install_cli() {
169
169
  warn "bin/plc_checkweigher not found — skipping CLI install"
170
170
  fi
171
171
 
172
- # Scoped sudoers rule: web dashboard maintenance console can run the
173
- # locked root-owned CLI's fix command (and nothing else) without password.
172
+ # Scoped sudoers rule: web maintenance terminal can run whitelisted
173
+ # subcommands of the locked root-owned CLI and nothing else.
174
+ # Interactive/destructive subcommands (wifi, smb-config, uninstall,
175
+ # hotspot) are deliberately NOT listed.
174
176
  cat > /tmp/010_plc-web-fix << 'EOF'
175
- # Web dashboard maintenance console — allows the locked, root-owned CLI
176
- # to run its fix command from plc_web (User=pi). Scope: fix only.
177
- pi ALL=(root) NOPASSWD: /usr/local/bin/plc_checkweigher fix, /usr/local/bin/plc_checkweigher fix *
177
+ # Web dashboard maintenance terminal — allows the locked, root-owned CLI
178
+ # to run whitelisted maintenance subcommands from plc_web (User=pi).
179
+ pi ALL=(root) NOPASSWD: /usr/local/bin/plc_checkweigher fix, /usr/local/bin/plc_checkweigher fix *, /usr/local/bin/plc_checkweigher status, /usr/local/bin/plc_checkweigher restart, /usr/local/bin/plc_checkweigher start, /usr/local/bin/plc_checkweigher stop, /usr/local/bin/plc_checkweigher update
178
180
  EOF
179
181
  if visudo -c -f /tmp/010_plc-web-fix &>/dev/null; then
180
182
  cp /tmp/010_plc-web-fix /etc/sudoers.d/010_plc-web-fix
181
183
  chmod 440 /etc/sudoers.d/010_plc-web-fix
182
- ok "Web maintenance sudoers rule installed (fix only, validated)"
184
+ ok "Web maintenance sudoers rule installed (whitelisted subcommands)"
183
185
  else
184
- warn "sudoers rule failed validation — web FIX button will not work"
186
+ warn "sudoers rule failed validation — web maintenance terminal limited"
185
187
  fi
186
188
  rm -f /tmp/010_plc-web-fix
187
189
  }
@@ -622,15 +624,27 @@ setup_vscode_priority() {
622
624
 
623
625
  cat > /usr/local/bin/vscode-priority-daemon << 'DAEMON'
624
626
  #!/usr/bin/env bash
625
- # Apply CPU affinity (cores 0-2) and Nice=-5 to VS Code server processes.
627
+ # Apply CPU affinity (cores 0-2) and Nice=-5 to remote-dev processes:
628
+ # - VS Code server + all its extensions (extension host, Claude Code,
629
+ # GitHub, language servers — anything under ~/.vscode-server)
630
+ # - standalone claude CLI sessions (run outside VS Code)
631
+ # - sshd listener + active SSH sessions
626
632
  # Core 3 is reserved exclusively for the SCHED_FIFO PLC process.
627
- # Runs every 60s so newly-spawned extension host processes are caught promptly.
628
- while true; do
629
- mapfile -t pids < <(pgrep -u pi -f '\.vscode-server' 2>/dev/null || true)
630
- for pid in "${pids[@]}"; do
633
+ # Runs every 60s so newly-spawned processes are caught promptly.
634
+ prioritize() {
635
+ local pid
636
+ for pid in "$@"; do
631
637
  taskset -cp 0-2 "$pid" >/dev/null 2>&1 || true
632
638
  renice -n -5 -p "$pid" >/dev/null 2>&1 || true
633
639
  done
640
+ }
641
+ while true; do
642
+ # VS Code server tree — extension binaries live under .vscode-server/extensions/
643
+ prioritize $(pgrep -u pi -f '\.vscode-server' 2>/dev/null)
644
+ # Standalone claude CLI (plain terminal, outside the VS Code tree)
645
+ prioritize $(pgrep -u pi -x claude 2>/dev/null)
646
+ # SSH — listener and per-session processes (keep off the RT core)
647
+ prioritize $(pgrep -x sshd 2>/dev/null) $(pgrep -x sshd-session 2>/dev/null)
634
648
  sleep 60
635
649
  done
636
650
  DAEMON