Skip to content

feat(clipboard): add Zellij support to OSC 52 fallback - #1737

Merged
shunkakinoki merged 1 commit into
mainfrom
feat/clipboard-zellij
May 10, 2026
Merged

feat(clipboard): add Zellij support to OSC 52 fallback#1737
shunkakinoki merged 1 commit into
mainfrom
feat/clipboard-zellij

Conversation

@shunkakinoki

@shunkakinoki shunkakinoki commented May 10, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add ZELLIJ env var detection to clipboard-copy OSC 52 fallback
  • Add test case for Zellij multiplexer environment
  • Unset ZELLIJ in the "no backend" test to prevent false passes

Test plan

  • Verify pwd | copy works inside a Zellij session
  • Verify existing clipboard backends (pbcopy, wl-copy, xclip, xsel) still take priority
  • Run shellspec tests

Summary by cubic

Add Zellij support to the OSC 52 clipboard fallback so copy works inside Zellij sessions when no native clipboard backend is available.

  • New Features
    • Detect ZELLIJ in clipboard-copy.sh to enable OSC 52 fallback.
    • Tests: add a Zellij environment test; unset ZELLIJ in the "no backend" test to avoid false passes.

Written for commit 2bc99d5. Summary will update on new commits.

@mesa-dot-dev

mesa-dot-dev Bot commented May 10, 2026

Copy link
Copy Markdown

You do not have enough credits to review this pull request. Please purchase more credits to continue.

@indent-zero

indent-zero Bot commented May 10, 2026

Copy link
Copy Markdown
Contributor
PR Summary

Bundles two unrelated changes: enables OSC 52 clipboard fallback inside Zellij sessions (Zellij doesn't set TMUX, so the existing condition skipped it), and adds Tailscale tls-san entries to k3s plus a helper for generating a remote kubeconfig over Tailscale. The activate script is also made idempotent so k3s only restarts when the rendered config actually changed.

  • home-manager/modules/local-scripts/clipboard-copy.sh: add ZELLIJ to the OSC 52 trigger condition alongside TMUX/SSH_TTY.
  • spec/clipboard_copy_spec.sh: new Describe block covering the ZELLIJ branch; existing "no backend" cleanup extended to unset ZELLIJ.
  • config/k3s/config.yaml: append tls-san with the kyber Tailscale IP and MagicDNS name so the apiserver cert is valid for remote kubectl.
  • config/k3s/activate.sh: wrap cp in a diff -q guard and conditionally systemctl restart k3s only when content changed and the unit is active.
  • config/k3s/generate-remote-kubeconfig.sh (new): rewrites 127.0.0.1:6443 → Tailscale DNS, renames default cluster/context/user to kyber-remote, writes to ~/.kube/config-kyber-remote with mode 0600.

Issues

4 potential issues found:

  • Nit: the new Describe 'when no clipboard backend but ZELLIJ is set' block does not unset TMUX SSH_TTY, so if the spec runs inside a tmux pane or over SSH the assertion would still pass even if the new ZELLIJ branch were broken — the test doesn't actually isolate the trigger. → Autofix
  • Latent: config/k3s/activate.sh calls bare diff and systemctl, but the sibling home-manager/services/k3s/activate.sh deliberately substitutes @diff@/@systemctl@ via pkgs.replaceVars because home-manager activation PATH may not include them — when missing, if !/if swallows exit 127 and the new restart-on-change logic silently no-ops, so this PR's tls-san entries never take effect. → Autofix
  • Nit: TAILSCALE_IP="100.72.158.65" is declared in generate-remote-kubeconfig.sh but never referenced — only TAILSCALE_DNS is used in the sed rewrite, so the variable is dead and misleadingly suggests an IP fallback that doesn't exist. → Autofix
  • Latent: sed "s|default|kyber-remote|g" in generate-remote-kubeconfig.sh rewrites every literal default, including any occurrence inside the single-line base64 cert/key blobs in k3s.yaml — when (rarely) hit, the cert silently corrupts and kubectl fails with a confusing TLS/PEM error instead of a clean diagnostic. → Autofix

CI Checks

Waiting for CI checks...


⚡ Autofix All Issues

@coderabbitai

coderabbitai Bot commented May 10, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds k3s cluster remote access configuration and extends clipboard clipboard support for ZELLIJ terminal multiplexer. The k3s changes conditionally apply TLS Subject Alternative Names and intelligently restart the service only on config changes. A new kubeconfig generation script enables remote access via Tailscale. The clipboard utility now recognizes ZELLIJ as a valid terminal for OSC 52 escape sequence fallback, with corresponding test coverage.

Changes

K3S Remote Access Setup

Layer / File(s) Summary
K3S Configuration
config/k3s/config.yaml
Adds tls-san block with Tailscale IP (100.72.158.65) and DNS name (kyber.tail950b36.ts.net) for TLS certificate validation.
K3S Activation Logic
config/k3s/activate.sh
Introduces diff -q guard before copying config; restarts k3s service only when source and destination differ.
Remote Kubeconfig Generation
config/k3s/generate-remote-kubeconfig.sh
New Bash script reads k3s server kubeconfig, rewrites API server URL to Tailscale DNS name, renames context to kyber-remote, writes to ~/.kube/config-kyber-remote, and prints usage instructions.

Clipboard ZELLIJ Terminal Multiplexer Support

Layer / File(s) Summary
Clipboard Fallback Logic
home-manager/modules/local-scripts/clipboard-copy.sh
Expands OSC 52 fallback condition to include ZELLIJ environment variable alongside existing TTY/TMUX/SSH checks.
Test Coverage
spec/clipboard_copy_spec.sh
Adds test scenario for OSC 52 emission when ZELLIJ is set and no clipboard backend exists; updates existing failure test to unset ZELLIJ for isolation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Poem

🐰 A kubeconfig takes flight,
Over Tailscale through the night,
Zellij's whisper, clipboard's song,
Terminal multiplexing all along!
Remote access, ZELLIJ bright,
Every fallback done just right. 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding Zellij support to the OSC 52 clipboard fallback, which is the primary feature of the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed The pull request description clearly describes the changes: adding Zellij environment variable detection to the clipboard-copy OSC 52 fallback, adding a test case for Zellij, and unsetting ZELLIJ in the 'no backend' test. All changes in the raw summary align with these described objectives.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/clipboard-zellij

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@mesa-dot-dev

mesa-dot-dev Bot commented May 10, 2026

Copy link
Copy Markdown

Mesa Description

TL;DR

Improved clipboard functionality by adding Zellij support to the OSC 52 fallback mechanism, and enhanced k3s remote access by integrating Tailscale SANs, providing a remote kubeconfig generator, and optimizing k3s restarts.

What changed?

  • config/k3s/activate.sh: Optimized k3s config.yaml handling to only copy if content changes and restart k3s service intelligently to apply new configurations.
  • config/k3s/config.yaml: Updated to include tls-san entries for "100.72.158.65" and "kyber.tail950b36.ts.net".
  • config/k3s/generate-remote-kubeconfig.sh: Added a new script to generate a remote Kubeconfig for k3s clusters accessible via Tailscale, modifying the API server address and context.
  • home-manager/modules/local-scripts/clipboard-copy.sh: Enhanced clipboard copying over SSH by adding ZELLIJ environment variable detection to its OSC 52 fallback mechanism.
  • spec/clipboard_copy_spec.sh: Introduced a new test case for Zellij support with OSC 52 fallback and modified an existing "no backend" test to explicitly unset ZELLIJ.

Description generated by Mesa. Update settings

@shunkakinoki
shunkakinoki force-pushed the feat/clipboard-zellij branch from 3e29837 to 2bc99d5 Compare May 10, 2026 06:53

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
spec/clipboard_copy_spec.sh (1)

164-184: ⚡ Quick win

Restore TMUX and ZELLIJ in cleanup for full test isolation.

Setup unsets both vars (Line 171), but cleanup doesn’t restore prior values. This can leak state across specs as this file evolves.

Suggested patch
 setup() {
   MOCK_BIN="$(mktemp -d)"
   MOCK_ORIGINAL_PATH="${PATH:-}"
   MOCK_ORIGINAL_WAYLAND="${WAYLAND_DISPLAY:-}"
   MOCK_ORIGINAL_SSH_TTY="${SSH_TTY:-}"
+  MOCK_ORIGINAL_TMUX="${TMUX:-}"
+  MOCK_ORIGINAL_ZELLIJ="${ZELLIJ:-}"
   ln -sf "$(command -v bash)" "$MOCK_BIN/bash"
   export PATH="$MOCK_BIN"
   unset WAYLAND_DISPLAY SSH_TTY TMUX ZELLIJ
-  export MOCK_BIN MOCK_ORIGINAL_PATH MOCK_ORIGINAL_WAYLAND MOCK_ORIGINAL_SSH_TTY
+  export MOCK_BIN MOCK_ORIGINAL_PATH MOCK_ORIGINAL_WAYLAND MOCK_ORIGINAL_SSH_TTY MOCK_ORIGINAL_TMUX MOCK_ORIGINAL_ZELLIJ
 }
 cleanup() {
   export PATH="$MOCK_ORIGINAL_PATH"
   if [ -n "$MOCK_ORIGINAL_WAYLAND" ]; then
     export WAYLAND_DISPLAY="$MOCK_ORIGINAL_WAYLAND"
   fi
   if [ -n "$MOCK_ORIGINAL_SSH_TTY" ]; then
     export SSH_TTY="$MOCK_ORIGINAL_SSH_TTY"
+  else
+    unset SSH_TTY
+  fi
+  if [ -n "$MOCK_ORIGINAL_TMUX" ]; then
+    export TMUX="$MOCK_ORIGINAL_TMUX"
+  else
+    unset TMUX
+  fi
+  if [ -n "$MOCK_ORIGINAL_ZELLIJ" ]; then
+    export ZELLIJ="$MOCK_ORIGINAL_ZELLIJ"
+  else
+    unset ZELLIJ
   fi
   rm -rf "$MOCK_BIN"
-  unset MOCK_BIN MOCK_ORIGINAL_PATH MOCK_ORIGINAL_WAYLAND MOCK_ORIGINAL_SSH_TTY
+  unset MOCK_BIN MOCK_ORIGINAL_PATH MOCK_ORIGINAL_WAYLAND MOCK_ORIGINAL_SSH_TTY MOCK_ORIGINAL_TMUX MOCK_ORIGINAL_ZELLIJ
 }

As per coding guidelines, "**/*.{sh,bash}: Always use non-interactive flags with file operations (cp -f, mv -f, rm -f, rm -rf, cp -rf) to avoid hanging on confirmation prompts".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@spec/clipboard_copy_spec.sh` around lines 164 - 184, The cleanup function
fails to restore TMUX and ZELLIJ which setup unsets, causing env leakage; update
setup to save originals (e.g., MOCK_ORIGINAL_TMUX="${TMUX:-}" and
MOCK_ORIGINAL_ZELLIJ="${ZELLIJ:-}" and export them) and update cleanup to
restore them if non-empty (or unset otherwise) similar to how
MOCK_ORIGINAL_WAYLAND and MOCK_ORIGINAL_SSH_TTY are handled; reference the setup
and cleanup functions and the TMUX and ZELLIJ variable names when making the
changes.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@config/k3s/activate.sh`:
- Line 21: The cp invocation using $SUDO_CMD (the line: $SUDO_CMD cp
"$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml) is missing the
non-interactive flag; update this command to use cp -f to ensure file copying is
forced/non-interactive (i.e., change to use $SUDO_CMD cp -f ...), preserving the
existing paths and variables.
- Around line 20-24: The diff check can fail with permission errors when reading
/etc/rancher/k3s/config.yaml causing unnecessary copy/restart; change the check
to run diff under sudo (use $SUDO_CMD) so it can read the target file reliably
(i.e., replace the current diff invocation with $SUDO_CMD diff -q
"$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml >/dev/null 2>&1)
and keep the surrounding logic (the cp and systemctl restart calls) unchanged so
restarts only occur when contents actually differ.

---

Nitpick comments:
In `@spec/clipboard_copy_spec.sh`:
- Around line 164-184: The cleanup function fails to restore TMUX and ZELLIJ
which setup unsets, causing env leakage; update setup to save originals (e.g.,
MOCK_ORIGINAL_TMUX="${TMUX:-}" and MOCK_ORIGINAL_ZELLIJ="${ZELLIJ:-}" and export
them) and update cleanup to restore them if non-empty (or unset otherwise)
similar to how MOCK_ORIGINAL_WAYLAND and MOCK_ORIGINAL_SSH_TTY are handled;
reference the setup and cleanup functions and the TMUX and ZELLIJ variable names
when making the changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f7f801e2-7ab3-4dbb-8d38-329fcb6f4282

📥 Commits

Reviewing files that changed from the base of the PR and between 4b82003 and 3e29837.

📒 Files selected for processing (5)
  • config/k3s/activate.sh
  • config/k3s/config.yaml
  • config/k3s/generate-remote-kubeconfig.sh
  • home-manager/modules/local-scripts/clipboard-copy.sh
  • spec/clipboard_copy_spec.sh

Comment thread config/k3s/activate.sh Outdated
Comment on lines +20 to +24
if ! diff -q "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml >/dev/null 2>&1; then
$SUDO_CMD cp "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml
if systemctl is-active --quiet k3s; then
$SUDO_CMD systemctl restart k3s
echo "k3s restarted to apply config changes"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Run the change-detection diff with sudo to avoid false-positive restarts.

At Line 20, diff may fail on permission denied for /etc/rancher/k3s/config.yaml, which makes this block copy/restart even when contents are unchanged.

Proposed fix
-  if ! diff -q "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml >/dev/null 2>&1; then
+  if ! $SUDO_CMD diff -q "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml >/dev/null 2>&1; then
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if ! diff -q "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml >/dev/null 2>&1; then
$SUDO_CMD cp "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml
if systemctl is-active --quiet k3s; then
$SUDO_CMD systemctl restart k3s
echo "k3s restarted to apply config changes"
if ! $SUDO_CMD diff -q "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml >/dev/null 2>&1; then
$SUDO_CMD cp "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml
if systemctl is-active --quiet k3s; then
$SUDO_CMD systemctl restart k3s
echo "k3s restarted to apply config changes"
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@config/k3s/activate.sh` around lines 20 - 24, The diff check can fail with
permission errors when reading /etc/rancher/k3s/config.yaml causing unnecessary
copy/restart; change the check to run diff under sudo (use $SUDO_CMD) so it can
read the target file reliably (i.e., replace the current diff invocation with
$SUDO_CMD diff -q "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml
>/dev/null 2>&1) and keep the surrounding logic (the cp and systemctl restart
calls) unchanged so restarts only occur when contents actually differ.

Comment thread config/k3s/activate.sh Outdated
$SUDO_CMD mkdir -p /etc/rancher/k3s
$SUDO_CMD cp "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml
if ! diff -q "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml >/dev/null 2>&1; then
$SUDO_CMD cp "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Use non-interactive copy flag for consistency with repo shell rules.

At Line 21, switch to cp -f to keep file operations non-interactive.

As per coding guidelines, "Always use non-interactive flags with file operations (cp -f, mv -f, rm -f, rm -rf, cp -rf) to avoid hanging on confirmation prompts".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@config/k3s/activate.sh` at line 21, The cp invocation using $SUDO_CMD (the
line: $SUDO_CMD cp "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml)
is missing the non-interactive flag; update this command to use cp -f to ensure
file copying is forced/non-interactive (i.e., change to use $SUDO_CMD cp -f
...), preserving the existing paths and variables.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the k3s configuration to include Tailscale SANs, adds a script for generating remote kubeconfigs, and extends the clipboard copy utility to support Zellij. Feedback was provided regarding a permission issue in the k3s activation script that could cause unnecessary restarts and a security improvement for the kubeconfig generation script to ensure sensitive files are not created with world-readable permissions.

I am having trouble creating individual review comments. Click here to see my feedback.

config/k3s/generate-remote-kubeconfig.sh (22-27)

security-high high

The kubeconfig file is created with default permissions before chmod 600 is called. Since kubeconfigs contain sensitive credentials (CA data and tokens), they should not be world-readable at any point. It is safer to set the umask or create the file with restricted permissions from the start to avoid this race condition.

(umask 077; $SUDO_CMD cat "$K3S_KUBECONFIG" | sed "s|https://127.0.0.1:6443|https://${TAILSCALE_DNS}:6443|g" | sed "s|default|kyber-remote|g" > "$OUTPUT")

config/k3s/activate.sh (20)

medium

The diff command is executed as the current user. Since /etc/rancher/k3s/config.yaml is typically root-owned and restricted (mode 600), this check will likely fail with a 'Permission denied' error (exit code 2). This causes the script to always copy the file and restart k3s, even if the configuration hasn't changed. Using $SUDO_CMD diff ensures the comparison works correctly.

  if ! $SUDO_CMD diff -q "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml >/dev/null 2>&1; then

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 issues found across 5 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="config/k3s/activate.sh">

<violation number="1" location="config/k3s/activate.sh:20">
P2: The change-detection check treats `diff` errors as config changes, so comparison failures can incorrectly trigger a copy and k3s restart. Run the comparison with sudo (at minimum) so permission failures don’t look like content changes.</violation>
</file>

<file name="spec/clipboard_copy_spec.sh">

<violation number="1" location="spec/clipboard_copy_spec.sh:136">
P2: The new Zellij test is not isolated: `SSH_TTY`/`TMUX` are left untouched, so it can false-pass via another OSC 52 trigger instead of validating Zellij detection.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread config/k3s/activate.sh Outdated
if [ -n "$SUDO_CMD" ]; then
$SUDO_CMD mkdir -p /etc/rancher/k3s
$SUDO_CMD cp "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml
if ! diff -q "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml >/dev/null 2>&1; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The change-detection check treats diff errors as config changes, so comparison failures can incorrectly trigger a copy and k3s restart. Run the comparison with sudo (at minimum) so permission failures don’t look like content changes.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At config/k3s/activate.sh, line 20:

<comment>The change-detection check treats `diff` errors as config changes, so comparison failures can incorrectly trigger a copy and k3s restart. Run the comparison with sudo (at minimum) so permission failures don’t look like content changes.</comment>

<file context>
@@ -17,7 +17,13 @@ fi
 if [ -n "$SUDO_CMD" ]; then
   $SUDO_CMD mkdir -p /etc/rancher/k3s
-  $SUDO_CMD cp "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml
+  if ! diff -q "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml >/dev/null 2>&1; then
+    $SUDO_CMD cp "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml
+    if systemctl is-active --quiet k3s; then
</file context>
Suggested change
if ! diff -q "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml >/dev/null 2>&1; then
if ! $SUDO_CMD diff -q "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml >/dev/null 2>&1; then

ln -sf "$(command -v "$cmd")" "$MOCK_BIN/$cmd"
done
export PATH="$MOCK_BIN"
unset WAYLAND_DISPLAY

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The new Zellij test is not isolated: SSH_TTY/TMUX are left untouched, so it can false-pass via another OSC 52 trigger instead of validating Zellij detection.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At spec/clipboard_copy_spec.sh, line 136:

<comment>The new Zellij test is not isolated: `SSH_TTY`/`TMUX` are left untouched, so it can false-pass via another OSC 52 trigger instead of validating Zellij detection.</comment>

<file context>
@@ -120,6 +120,46 @@ The output should start with $'\033]52;c;'
+    ln -sf "$(command -v "$cmd")" "$MOCK_BIN/$cmd"
+  done
+  export PATH="$MOCK_BIN"
+  unset WAYLAND_DISPLAY
+  export ZELLIJ=0
+  export MOCK_BIN MOCK_ORIGINAL_PATH MOCK_ORIGINAL_WAYLAND MOCK_ORIGINAL_ZELLIJ
</file context>

Comment thread config/k3s/activate.sh Outdated
$SUDO_CMD cp "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml
if ! diff -q "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml >/dev/null 2>&1; then
$SUDO_CMD cp "$HOME/.config/k3s/config.yaml" /etc/rancher/k3s/config.yaml
if systemctl is-active --quiet k3s; then

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bare systemctl/diff may not resolve in the home-manager activation PATH. The sibling script home-manager/services/k3s/activate.sh is built via pkgs.replaceVars substituting @diff@/@systemctl@ (see home-manager/services/k3s/default.nix:11-14) precisely because activation PATH can't be relied on. This script is wired in config/k3s/default.nix as ${./activate.sh} with no substitution, so it ships bare commands.

With set -euo pipefail, both if ! diff … and if systemctl is-active … consume the exit code, so a missing binary returns 127 and the wrappers silently degrade: diff missing → cp always runs (mostly harmless), but systemctl missing → restart is skipped without any error. The net effect on a host where systemctl isn't on activation PATH is that the new tls-san: entries get copied to /etc/rancher/k3s/config.yaml but k3s is never restarted, so remote kubectl over Tailscale continues to fail TLS verification.

Fix by rendering this script through pkgs.replaceVars in config/k3s/default.nix and switching to @diff@/@systemctl@, matching the established pattern.


$SUDO_CMD cat "$K3S_KUBECONFIG" \
| sed "s|https://127.0.0.1:6443|https://${TAILSCALE_DNS}:6443|g" \
| sed "s|default|kyber-remote|g" \

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Global sed s|default|kyber-remote|g can corrupt cert data. k3s.yaml stores certificate-authority-data, client-certificate-data, and client-key-data as single-line base64 in the alphabet [A-Za-z0-9+/=], which contains every character of default. The substring can (rarely) appear inside the encoded blob, in which case this rewrite silently mangles the cert and kubectl fails later with a tls: failed to find any PEM data style error rather than a clean diagnostic.

Probability is low per cert, but the failure mode is hard to debug. Prefer targeted YAML-aware rename, e.g.:

sed -E 's/(name|user|cluster|current-context):[[:space:]]*default$/\1: kyber-remote/'

or pipe through yq to mutate only the cluster/user/context name fields. That keeps certificate-authority-data byte-identical no matter what the random base64 ends up containing.

# Generate a kubeconfig for remote access via Tailscale
set -euo pipefail

TAILSCALE_IP="100.72.158.65"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TAILSCALE_IP is declared but never used — only TAILSCALE_DNS is referenced in the sed substitution below. Either drop this line or wire it in (e.g., write a second kubeconfig variant that uses https://${TAILSCALE_IP}:6443 so DNS-less clients still work).

done
export PATH="$MOCK_BIN"
unset WAYLAND_DISPLAY
export ZELLIJ=0

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This setup sets ZELLIJ=0 and unsets WAYLAND_DISPLAY, but doesn't unset TMUX or SSH_TTY. If the suite runs inside a tmux pane or over SSH, the OSC 52 fallback would fire from those variables and the test would pass even if the new ZELLIJ branch in clipboard-copy.sh were broken.

The "no backend" cleanup already does unset WAYLAND_DISPLAY SSH_TTY TMUX ZELLIJ (line 171) for exactly this reason — worth doing the same here:

MOCK_ORIGINAL_TMUX="${TMUX:-}"
MOCK_ORIGINAL_SSH_TTY="${SSH_TTY:-}"unset WAYLAND_DISPLAY TMUX SSH_TTY
export ZELLIJ=0

and restore both in cleanup(). The pre-existing SSH_TTY block (lines 83–121) has the same gap and would benefit from the same treatment.

@shunkakinoki
shunkakinoki merged commit 1df2eaa into main May 10, 2026
21 of 22 checks passed
@shunkakinoki
shunkakinoki deleted the feat/clipboard-zellij branch May 10, 2026 06:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant