<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://aqlkzf.github.io/JishuaiMIAO/feed.xml" rel="self" type="application/atom+xml"/><link href="https://aqlkzf.github.io/JishuaiMIAO/" rel="alternate" type="text/html" hreflang="en"/><updated>2026-05-20T12:36:26+00:00</updated><id>https://aqlkzf.github.io/JishuaiMIAO/feed.xml</id><title type="html">blank</title><subtitle>A math student, a data novice. </subtitle><entry><title type="html">Hello World</title><link href="https://aqlkzf.github.io/JishuaiMIAO/blog/2026/hello-world/" rel="alternate" type="text/html" title="Hello World"/><published>2026-05-19T00:00:00+00:00</published><updated>2026-05-20T12:35:49+00:00</updated><id>https://aqlkzf.github.io/JishuaiMIAO/blog/2026/hello-world</id><content type="html" xml:base="https://aqlkzf.github.io/JishuaiMIAO/blog/2026/hello-world/"><![CDATA[<p>This is my first blog post. I plan to write about tools and workflows for machine learning and bioinformatics.</p> <p>The idea came from watching <a href="https://youtu.be/I0DrcsDf3Os?si=ySp-hc6WUuopRZre">Jiayi Weng’s invitation talk</a> — a candid walkthrough of his journey through open-source projects (Tianshou), research infrastructure, and post-training at OpenAI. It reminded me that writing things down, even informally, is a worthwhile habit.</p>]]></content><author><name></name></author><category term="meta"/><summary type="html"><![CDATA[First post — tools and workflows for machine learning and bioinformatics]]></summary></entry><entry><title type="html">Install Claude Code and Codex on ITSC Cluster (No sudo)</title><link href="https://aqlkzf.github.io/JishuaiMIAO/blog/2026/install-claude-codex/" rel="alternate" type="text/html" title="Install Claude Code and Codex on ITSC Cluster (No sudo)"/><published>2026-05-19T00:00:00+00:00</published><updated>2026-05-20T12:35:49+00:00</updated><id>https://aqlkzf.github.io/JishuaiMIAO/blog/2026/install-claude-codex</id><content type="html" xml:base="https://aqlkzf.github.io/JishuaiMIAO/blog/2026/install-claude-codex/"><![CDATA[<blockquote> <p>Since we don’t have sudo access, we need to install npm via conda in a dedicated environment. Also, we need to set up global access to the npm binaries to avoid conda env PATH conflicts.</p> </blockquote> <h2 id="install-npm-via-conda">Install npm via conda</h2> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>conda create <span class="nt">-n</span> basic_tools <span class="nv">python</span><span class="o">=</span>3.11
conda activate basic_tools
conda <span class="nb">install </span>npm
</code></pre></div></div> <h2 id="set-up-global-access">Set up global access</h2> <p>Create a dedicated tool directory and symlink only the needed binaries, avoiding conda env PATH conflicts:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">mkdir</span> <span class="nt">-p</span> ~/toolsmiao

<span class="c"># symlink node and npm</span>
<span class="nb">ln</span> <span class="nt">-s</span> <span class="si">$(</span>conda <span class="nb">env </span>list | <span class="nb">grep </span>basic_tools | <span class="nb">awk</span> <span class="s1">'{print $NF}'</span><span class="si">)</span>/bin/node ~/toolsmiao/node
<span class="nb">ln</span> <span class="nt">-s</span> <span class="si">$(</span>conda <span class="nb">env </span>list | <span class="nb">grep </span>basic_tools | <span class="nb">awk</span> <span class="s1">'{print $NF}'</span><span class="si">)</span>/bin/npm ~/toolsmiao/npm
</code></pre></div></div> <p>Add to your shell config (<code class="language-plaintext highlighter-rouge">~/.bashrc</code>):</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">PATH</span><span class="o">=</span><span class="nv">$HOME</span>/toolsmiao:<span class="nv">$HOME</span>/toolsmiao/bin:<span class="nv">$PATH</span>
</code></pre></div></div> <h2 id="install-claude-code-and-codex">Install Claude Code and Codex</h2> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># set global install prefix to ~/toolsmiao</span>
npm config <span class="nb">set </span>prefix ~/toolsmiao

npm <span class="nb">install</span> <span class="nt">-g</span> @anthropic-ai/claude-code
npm <span class="nb">install</span> <span class="nt">-g</span> @openai/codex
</code></pre></div></div> <p>This way <code class="language-plaintext highlighter-rouge">claude</code> and <code class="language-plaintext highlighter-rouge">codex</code> binaries land directly in <code class="language-plaintext highlighter-rouge">~/toolsmiao/bin/</code> — no conda activation needed after the initial setup.</p>]]></content><author><name></name></author><category term="tools"/><category term="hpc"/><summary type="html"><![CDATA[How to install npm via conda and set up Claude Code and Codex on a shared HPC cluster without root access.]]></summary></entry><entry><title type="html">Run Claude Code / Codex on a Remote Server via SSH Proxy</title><link href="https://aqlkzf.github.io/JishuaiMIAO/blog/2026/run-claude-codex/" rel="alternate" type="text/html" title="Run Claude Code / Codex on a Remote Server via SSH Proxy"/><published>2026-05-19T00:00:00+00:00</published><updated>2026-05-20T12:35:49+00:00</updated><id>https://aqlkzf.github.io/JishuaiMIAO/blog/2026/run-claude-codex</id><content type="html" xml:base="https://aqlkzf.github.io/JishuaiMIAO/blog/2026/run-claude-codex/"><![CDATA[<p>HPC clusters can’t reach <code class="language-plaintext highlighter-rouge">openai.com</code> or <code class="language-plaintext highlighter-rouge">claude.ai</code>, and without <code class="language-plaintext highlighter-rouge">sudo</code> we can’t install a VPN on the cluster. The workaround: tunnel your <strong>local</strong> proxy (e.g. Clash) to the remote server over SSH with <code class="language-plaintext highlighter-rouge">RemoteForward</code>, so Claude Code and Codex can phone home with no firewall changes on either side.</p> <h2 id="prerequisites">Prerequisites</h2> <table> <thead> <tr> <th>Item</th> <th>Details</th> </tr> </thead> <tbody> <tr> <td><strong>Local proxy</strong></td> <td>Running on your local machine (e.g. Clash); note the port (default: <code class="language-plaintext highlighter-rouge">7890</code>)</td> </tr> <tr> <td><strong>VS Code + Remote SSH</strong></td> <td>Connected to the remote server — see the <a href="https://doc.sta.cuhk.edu.hk/vs-code-remote-ssh-guide">VS Code Remote SSH Guide</a> if not yet set up</td> </tr> <tr> <td><strong>Claude Code / Codex</strong></td> <td>Installed on the remote server — see <a href="/JishuaiMIAO/blog/2026/install-claude-codex/">Install Claude Code &amp; Codex on ITSC Cluster</a></td> </tr> </tbody> </table> <h2 id="1-add-remoteforward-to-your-ssh-config">1. Add RemoteForward to Your SSH Config</h2> <p>Open <code class="language-plaintext highlighter-rouge">~/.ssh/config</code> on your <strong>local</strong> machine.</p> <p>Add <code class="language-plaintext highlighter-rouge">RemoteForward 7890 127.0.0.1:7890</code> to every <code class="language-plaintext highlighter-rouge">Host</code> block you connect to:</p> <pre><code class="language-sshconfig">Host chpc-login
    HostName chpc-login.itsc.cuhk.edu.hk
    User YOUR_COMPUTING_ID
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes
    ControlMaster auto
    ControlPersist 10m
    RemoteForward 7890 127.0.0.1:7890   # ← add this line

Host chpc-gpu0?? chpc-gpu0??.rc.cuhk.edu.hk
    HostName %h.rc.cuhk.edu.hk
    User YOUR_COMPUTING_ID
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes
    ProxyJump chpc-login
    RemoteForward 7890 127.0.0.1:7890   # ← add this line

Host chpc-cn??? chpc-cn???.rc.cuhk.edu.hk
    HostName %h.rc.cuhk.edu.hk
    User YOUR_COMPUTING_ID
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes
    ProxyJump chpc-login
    RemoteForward 7890 127.0.0.1:7890   # ← add this line
</code></pre> <blockquote> <p><strong>Note:</strong> <code class="language-plaintext highlighter-rouge">7890</code> must match your local proxy’s mixed port. In Clash, check <strong>Settings → Mixed Port</strong>.</p> </blockquote> <p><code class="language-plaintext highlighter-rouge">RemoteForward</code> makes port <code class="language-plaintext highlighter-rouge">7890</code> on the remote machine forward traffic back to <code class="language-plaintext highlighter-rouge">127.0.0.1:7890</code> on your laptop. Combined with <code class="language-plaintext highlighter-rouge">ProxyJump</code>, the forward propagates through the jump chain, so compute nodes get the proxy too.</p> <h2 id="2-export-proxy-variables-on-the-remote-server">2. Export Proxy Variables on the Remote Server</h2> <p>For <strong>bash</strong> or <strong>zsh</strong>, append to <code class="language-plaintext highlighter-rouge">~/.bashrc</code> / <code class="language-plaintext highlighter-rouge">~/.zshrc</code>:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">HTTP_PROXY</span><span class="o">=</span><span class="s2">"http://127.0.0.1:7890"</span>
<span class="nb">export </span><span class="nv">HTTPS_PROXY</span><span class="o">=</span><span class="s2">"http://127.0.0.1:7890"</span>
<span class="nb">export </span><span class="nv">ALL_PROXY</span><span class="o">=</span><span class="s2">"socks5://127.0.0.1:7890"</span>
</code></pre></div></div> <p>Reload the config (<code class="language-plaintext highlighter-rouge">source ~/.bashrc</code>, etc.) or open a fresh terminal.</p> <h2 id="3-verify">3. Verify</h2> <p>Reconnect to the server via VS Code Remote SSH, then run:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>curl <span class="nt">-x</span> http://127.0.0.1:7890 https://api.anthropic.com
<span class="c"># or, for Codex:</span>
curl <span class="nt">-x</span> http://127.0.0.1:7890 https://api.openai.com
</code></pre></div></div> <p>Any response — even an HTTP error body — means the tunnel is alive. Claude Code and Codex can now reach the internet.</p> <h2 id="alternative-codex-specific-env-if-shell-variables-fail">Alternative: Codex-Specific <code class="language-plaintext highlighter-rouge">.env</code> (If Shell Variables Fail)</h2> <p>If Codex still can’t reach the API after setting shell variables (e.g. when launched from an IDE plugin or non-interactive context), create <code class="language-plaintext highlighter-rouge">~/.codex/.env</code>:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">tee</span> ~/.codex/.env <span class="o">&lt;&lt;</span><span class="sh">'</span><span class="no">EOF</span><span class="sh">'
http_proxy="http://127.0.0.1:7890"
https_proxy="http://127.0.0.1:7890"
all_proxy="socks5://127.0.0.1:7890"
</span><span class="no">EOF
</span><span class="nb">chmod </span>600 ~/.codex/.env
</code></pre></div></div> <p>This file is loaded automatically when Codex starts — independent of your shell environment.</p> <p><strong>Format rules:</strong></p> <ul> <li>One variable per line, values in double quotes</li> <li>Do <strong>not</strong> use <code class="language-plaintext highlighter-rouge">export</code></li> <li>Do <strong>not</strong> omit the quotes</li> </ul> <p>This approach is process-level rather than session-level, so it won’t pollute other tools (<code class="language-plaintext highlighter-rouge">curl</code>, <code class="language-plaintext highlighter-rouge">apt</code>, etc.) in the same shell.</p> <h2 id="faq">FAQ</h2> <table> <thead> <tr> <th>Question</th> <th>Answer</th> </tr> </thead> <tbody> <tr> <td><strong>Connection refused on port 7890</strong></td> <td>Check that your local proxy is running and the port matches. Also confirm <code class="language-plaintext highlighter-rouge">RemoteForward</code> is under the correct <code class="language-plaintext highlighter-rouge">Host</code> block.</td> </tr> <tr> <td><strong><code class="language-plaintext highlighter-rouge">bind: Address already in use</code> warning</strong></td> <td>Another SSH session already forwarded <code class="language-plaintext highlighter-rouge">7890</code> to this host. Disconnect the stale session (or pick a different port) and reconnect.</td> </tr> <tr> <td><strong>Proxy variables set but tools still fail</strong></td> <td>Reload your shell config or open a new terminal — the variables only take effect in new shells.</td> </tr> <tr> <td><strong>Using a different port</strong></td> <td>Replace every <code class="language-plaintext highlighter-rouge">7890</code> with your actual proxy port in both the SSH config and the shell config.</td> </tr> </tbody> </table>]]></content><author><name></name></author><category term="tools"/><category term="hpc"/><category term="ssh"/><summary type="html"><![CDATA[Use SSH RemoteForward to tunnel your local proxy to an HPC cluster, so Claude Code and Codex can reach the internet without direct outbound access.]]></summary></entry><entry><title type="html">Capture tmux Output for Debugging</title><link href="https://aqlkzf.github.io/JishuaiMIAO/blog/2026/tmux-debug/" rel="alternate" type="text/html" title="Capture tmux Output for Debugging"/><published>2026-05-19T00:00:00+00:00</published><updated>2026-05-20T12:35:49+00:00</updated><id>https://aqlkzf.github.io/JishuaiMIAO/blog/2026/tmux-debug</id><content type="html" xml:base="https://aqlkzf.github.io/JishuaiMIAO/blog/2026/tmux-debug/"><![CDATA[<blockquote> <p>Easily save tmux scrollback to a file so you can review logs or share them with AI for debugging.</p> </blockquote> <h2 id="the-problem">The Problem</h2> <p>When running programs inside tmux, viewing and copying output is cumbersome — you have to enter scroll mode, navigate manually, and copy-paste is unreliable for large outputs.</p> <h2 id="solution-capture-pane-to-file">Solution: Capture Pane to File</h2> <p>In your tmux session, press <code class="language-plaintext highlighter-rouge">Ctrl+B</code> then <code class="language-plaintext highlighter-rouge">:</code> to open the command prompt, and run:</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>capture-pane -S -2000 ; save-buffer log.txt
</code></pre></div></div> <table> <thead> <tr> <th>Flag</th> <th>Meaning</th> </tr> </thead> <tbody> <tr> <td><code class="language-plaintext highlighter-rouge">-S -2000</code></td> <td>Capture from 2000 lines above the current screen</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">save-buffer log.txt</code></td> <td>Save the captured content to <code class="language-plaintext highlighter-rouge">log.txt</code> in the current directory</td> </tr> </tbody> </table> <p>Adjust <code class="language-plaintext highlighter-rouge">-2000</code> to capture more or fewer lines (e.g. <code class="language-plaintext highlighter-rouge">-S -5000</code> for 5000 lines, or <code class="language-plaintext highlighter-rouge">-S -</code> for the entire scrollback history).</p> <h2 id="use-case">Use Case</h2> <p>This is particularly useful when you need to debug errors but aren’t sure how to fix them — save the output to a file, then feed it to an AI tool for analysis:</p> <div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># Inside tmux: Ctrl+B : capture-pane -S -2000 ; save-buffer log.txt</span>

<span class="c"># Then ask Claude Code to help debug</span>
claude <span class="s2">"check log.txt and help me fix the errors"</span>
</code></pre></div></div>]]></content><author><name></name></author><category term="tools"/><category term="tmux"/><summary type="html"><![CDATA[Save tmux scrollback to a file so you can review logs or feed them to an AI tool for debugging.]]></summary></entry></feed>