<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bobo Yang</title>
    <description>The latest articles on DEV Community by Bobo Yang (@yangbobo2021).</description>
    <link>https://dev.to/yangbobo2021</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4093070%2F8d08cf12-9c7b-4d6e-8976-42d1dc0fc556.png</url>
      <title>DEV Community: Bobo Yang</title>
      <link>https://dev.to/yangbobo2021</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yangbobo2021"/>
    <language>en</language>
    <item>
      <title>New to Linux Operations? Install DeepSeek Harness on a Remote Host Over SSH</title>
      <dc:creator>Bobo Yang</dc:creator>
      <pubDate>Thu, 03 Sep 2026 14:10:09 +0000</pubDate>
      <link>https://dev.to/yangbobo2021/new-to-linux-operations-install-deepseek-harness-on-a-remote-host-over-ssh-2nag</link>
      <guid>https://dev.to/yangbobo2021/new-to-linux-operations-install-deepseek-harness-on-a-remote-host-over-ssh-2nag</guid>
      <description>&lt;p&gt;&lt;em&gt;If you can SSH into a Linux host but do not yet know which commands are safe, a remote agent can help collect evidence on the machine itself. The important part is keeping changes behind a human approval boundary.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: I’m affiliated with KeySync, the remote-access product used in this tutorial.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For someone new to operations, the most stressful moment after an alert may not be the red error message. It may be the first few minutes after SSH login.&lt;/p&gt;

&lt;p&gt;You know something is wrong, but you do not know whether to inspect disk usage, processes, ports, or logs first. Search results offer dozens of commands, yet it is not obvious which ones only inspect state and which ones delete files, restart services, or modify configuration.&lt;/p&gt;

&lt;p&gt;Copying a few log lines into a web chat does not fully solve the problem either. The AI cannot see the host’s actual environment, so it asks for another command and another fragment of output. You return to SSH and run a command you may not completely understand.&lt;/p&gt;

&lt;p&gt;This tutorial has one narrow goal: use SSH to install the KeySync CLI and DeepSeek Harness (DSH) on an Ubuntu host. Afterward, you can find that host in KeySync, open its DSH instance remotely, ask the agent to begin with read-only checks, inspect the evidence, and decide whether any change should be made.&lt;/p&gt;

&lt;p&gt;This workflow does not make unsafe operations impossible, and it does not replace your organization’s change-management process. It gives a new operator a more structured way to investigate before acting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you will have at the end
&lt;/h2&gt;

&lt;p&gt;The workflow is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install the KeySync CLI and DeepSeek Harness over SSH.&lt;/li&gt;
&lt;li&gt;Find the online Linux device in KeySync.&lt;/li&gt;
&lt;li&gt;Select &lt;strong&gt;Remote Open&lt;/strong&gt; to enter the DSH instance running on that host.&lt;/li&gt;
&lt;li&gt;Describe the problem in natural language and request inspection only.&lt;/li&gt;
&lt;li&gt;Review the commands, evidence, and conclusions.&lt;/li&gt;
&lt;li&gt;Keep deletion, restart, upgrade, and configuration changes behind human approval.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;KeySync provides the path to the selected machine. DSH performs the investigation inside that machine’s real environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy40xzijeox5s2jdcx32v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fy40xzijeox5s2jdcx32v.png" alt="KeySync device list with the Remote DSH entry" width="800" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Test environment and limits
&lt;/h2&gt;

&lt;p&gt;This walkthrough was tested with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ubuntu 22.04.5 on x86-64&lt;/li&gt;
&lt;li&gt;A normal SSH user, without root installation&lt;/li&gt;
&lt;li&gt;KeySync CLI 0.1.123&lt;/li&gt;
&lt;li&gt;Node.js 24.18.0&lt;/li&gt;
&lt;li&gt;DeepSeek Harness 0.1.1-rc.2&lt;/li&gt;
&lt;li&gt;About 9.7 GiB free on the root filesystem before installation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The test machine had Ubuntu Desktop components installed, but the procedure used no Linux GUI and the SSH session had no desktop environment variables. This demonstrates a CLI-only installation, not a pristine minimal Ubuntu Server image.&lt;/p&gt;

&lt;p&gt;Do not copy the procedure unchanged to ARM64, another distribution, or a production server. Validate it in a non-production environment or ask an experienced administrator to review it first.&lt;/p&gt;

&lt;p&gt;The commands below use Bash syntax. Run &lt;code&gt;echo "$SHELL"&lt;/code&gt; to check your shell. If it is not Bash, ask an administrator how to switch or adapt the commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Know what will change before you copy a command
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;System, Node.js, and disk checks are read-only.&lt;/li&gt;
&lt;li&gt;Downloading and extracting KeySync writes only to a temporary directory and the current user’s home directory.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;keysync login&lt;/code&gt; stores login state for the current user and registers the device.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;keysync service install&lt;/code&gt; creates a user-level systemd service, not a system service.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;keysync dsh install&lt;/code&gt; downloads and installs DeepSeek Harness.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;keysync dsh remote enable&lt;/code&gt; enables the Remote DSH channel for this device.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This tutorial does not ask you to run &lt;code&gt;sudo rm&lt;/code&gt;, &lt;code&gt;docker system prune&lt;/code&gt;, format a disk, or modify production configuration. If your output differs from the examples, stop instead of trying more commands at random.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Perform read-only preflight checks
&lt;/h2&gt;

&lt;p&gt;These commands do not modify the system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;uname&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt;
&lt;span class="nb"&gt;.&lt;/span&gt; /etc/os-release &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%s %s\n'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$VERSION_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
node &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; /
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They answer four questions: Is the machine x86-64? Which Linux distribution is running? Which Node.js does the current shell use? How much space remains on the root filesystem?&lt;/p&gt;

&lt;p&gt;My test host returned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x86_64
Ubuntu 22.04
v12.22.9
about 9.7 GiB free on /
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first real issue appeared immediately: Node.js 12 could not run the current KeySync CLI. The current Linux CLI requires Node.js 24 or newer on &lt;code&gt;PATH&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The test host already had Node.js 24.18.0 in NVM, so I selected it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.nvm/versions/node/v24.18.0/bin:&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
node &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;span class="c"&gt;# v24.18.0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That NVM path belongs to this test host; it is not a universal location. If &lt;code&gt;node --version&lt;/code&gt; already reports 24 or newer, do not add it. If Node.js is installed elsewhere, use the real path on your host.&lt;/p&gt;

&lt;p&gt;If the version is still below 24, stop here. Do not run a blind &lt;code&gt;apt upgrade&lt;/code&gt; just to continue the tutorial. Use your organization’s approved Node.js installation method or ask an administrator to install Node.js 24.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Download the KeySync CLI
&lt;/h2&gt;

&lt;p&gt;On September 3, 2026, the current Linux x64 release was 0.1.123:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;tmp_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;mktemp&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; /tmp/keysync-install.XXXXXX&lt;span class="si"&gt;)&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'https://keysync.sublang.ai/keysync-updates/cli-linux-x64/keysync-cli-0.1.123-linux-x64.tar.gz'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$tmp_dir&lt;/span&gt;&lt;span class="s2"&gt;/keysync.tar.gz"&lt;/span&gt;
&lt;span class="nb"&gt;stat&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'%s bytes'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$tmp_dir&lt;/span&gt;&lt;span class="s2"&gt;/keysync.tar.gz"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tested file size was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;33124893 bytes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;curl&lt;/code&gt; fails or the size differs, do not extract the archive. Read the current public release manifest instead of guessing a download URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://keysync.sublang.ai/keysync-updates/latest.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Verify the archive
&lt;/h2&gt;

&lt;p&gt;SHA-512 is the archive’s digital fingerprint. The calculated value must match the value in the release manifest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'IdEI49Z7d4rtyFwE6XqMCapDBSo9Us2PwAg+ocK2Mkchu4wrVcF/ExaMzFzfEu5OvcOK4Nu3d3xMl6O3knhJpQ=='&lt;/span&gt;
&lt;span class="nv"&gt;actual&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;node &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"const fs=require('fs'),c=require('crypto');const p=process.argv[1];console.log(c.createHash('sha512').update(fs.readFileSync(p)).digest('base64'))"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$tmp_dir&lt;/span&gt;&lt;span class="s2"&gt;/keysync.tar.gz"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;test&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$actual&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$expected&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'SHA-512 OK'&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Verification failed; stop the installation'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Continue only after seeing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SHA-512 OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If verification fails, do not edit &lt;code&gt;expected&lt;/code&gt; to force a match. Confirm that the version, URL, and digest came from the same current manifest entry.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Install into your home directory
&lt;/h2&gt;

&lt;p&gt;These commands create files under the current user’s home directory and do not overwrite &lt;code&gt;/usr/bin&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/share/keysync/cli"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/bin"&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-xzf&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$tmp_dir&lt;/span&gt;&lt;span class="s2"&gt;/keysync.tar.gz"&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/share/keysync/cli"&lt;/span&gt;
&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/share/keysync/cli/keysync-cli-0.1.123-linux-x64/keysync"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/bin/keysync"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.nvm/versions/node/v24.18.0/bin:&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
keysync &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;0.1.123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;ln&lt;/code&gt; reports that the destination already exists, the machine may already have KeySync installed. Inspect it instead of overwriting it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/bin/keysync"&lt;/span&gt;
keysync &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Log in without writing passwords into shell history
&lt;/h2&gt;

&lt;p&gt;Do not place your real email address and passwords directly in command-line arguments. They may remain in shell history. The CLI can read them from environment variables populated through hidden prompts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-rp&lt;/span&gt; &lt;span class="s1"&gt;'KeySync email: '&lt;/span&gt; KEYSYNC_EMAIL
&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-srp&lt;/span&gt; &lt;span class="s1"&gt;'KeySync login password: '&lt;/span&gt; KEYSYNC_PASSWORD&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo
read&lt;/span&gt; &lt;span class="nt"&gt;-srp&lt;/span&gt; &lt;span class="s1"&gt;'KeySync Vault password: '&lt;/span&gt; KEYSYNC_VAULT_PASSWORD&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo
export &lt;/span&gt;KEYSYNC_EMAIL KEYSYNC_PASSWORD KEYSYNC_VAULT_PASSWORD
keysync login
&lt;span class="nb"&gt;unset &lt;/span&gt;KEYSYNC_EMAIL KEYSYNC_PASSWORD KEYSYNC_VAULT_PASSWORD
keysync status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run this only in your own private SSH session. If login fails, clear the variables with the &lt;code&gt;unset&lt;/code&gt; command before checking the account, password, and network.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Run KeySync as a user-level systemd service
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;keysync service &lt;span class="nb"&gt;install
&lt;/span&gt;keysync service status
systemctl &lt;span class="nt"&gt;--user&lt;/span&gt; is-enabled keysync.service
systemctl &lt;span class="nt"&gt;--user&lt;/span&gt; is-active keysync.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tested result was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;enabled
active
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No &lt;code&gt;sudo&lt;/code&gt; is used here. If someone suggests adding it after an unexpected error, stop and determine why first.&lt;/p&gt;

&lt;p&gt;If the installer reports &lt;code&gt;user lingering is disabled&lt;/code&gt;, the service may run only while that user has an active login session. It may not be online after a reboot before the user logs in. Do not enable linger or add &lt;code&gt;sudo&lt;/code&gt; without approval; ask an administrator to apply the organization’s policy, then test again after logging out or rebooting the test host.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Install DeepSeek Harness
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;keysync dsh &lt;span class="nb"&gt;install
&lt;/span&gt;keysync dsh start
keysync dsh remote &lt;span class="nb"&gt;enable
&lt;/span&gt;keysync dsh status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A clean reinstall took about 118 seconds in this test. A quiet period does not necessarily mean failure, so do not start a second concurrent installation.&lt;/p&gt;

&lt;p&gt;The successful state was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DeepSeek Harness: running
Version: 0.1.1-rc.2
Remote access: connected
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On the test host, DSH listened only on &lt;code&gt;127.0.0.1:3080&lt;/code&gt;; port 3080 was not exposed on every network interface.&lt;/p&gt;

&lt;p&gt;If you do not plan to use remote access yet, omit &lt;code&gt;keysync dsh remote enable&lt;/code&gt; and enable it later.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 8: Open the host and send a safe first instruction
&lt;/h2&gt;

&lt;p&gt;On another computer, open KeySync, select the online Linux host, and choose &lt;strong&gt;Remote Open&lt;/strong&gt; next to DeepSeek Harness.&lt;/p&gt;

&lt;p&gt;Do not begin with “fix it.” Start with an explicit diagnostic boundary:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Perform read-only checks only. Do not delete or move files, install or upgrade software, modify configuration, terminate processes, or start, stop, or restart services. First explain what you plan to inspect. Then run only the read-only commands required. Finally, list every command executed, the important output, the evidence behind your conclusion, remaining uncertainty, and any next action that requires my approval.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I used a similar instruction to investigate a Node.js version problem. DSH checked Node.js, &lt;code&gt;PATH&lt;/code&gt;, and the launcher on the target host, reproduced the syntax error under Node.js 12, and verified that the same CLI worked under Node.js 24.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqfki61oz0anyuslhist5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqfki61oz0anyuslhist5.png" alt="Remote DSH performing the read-only Node.js diagnosis" width="799" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Natural-language “read-only” instructions are not an operating-system sandbox. Important production systems still need low-privilege accounts, restricted &lt;code&gt;sudo&lt;/code&gt;, and explicit approval for deletion, restart, and configuration changes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common failure modes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;keysync: command not found&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Make sure the current shell includes the installation directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.nvm/versions/node/v24.18.0/bin:&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/.local/bin:&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
keysync &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;SyntaxError: Unexpected token '.'&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The test host produced this when it was still using Node.js 12:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;which node
node &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the executable actually selected by the shell, not merely that Node.js 24 exists somewhere on the machine.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Could not resolve host&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Confirm that the URL comes from the current &lt;code&gt;latest.json&lt;/code&gt;, then inspect DNS. Do not disable certificate checking or use an untrusted mirror.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Remote access: disabled&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;If you intend to enable remote access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;keysync dsh remote &lt;span class="nb"&gt;enable
&lt;/span&gt;keysync dsh status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The state may briefly show &lt;code&gt;reconnecting&lt;/code&gt; before becoming &lt;code&gt;connected&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The installer is quiet for a long time
&lt;/h3&gt;

&lt;p&gt;The tested reinstall took about 118 seconds. First wait and confirm that only one installation process is running. If it exceeds a reasonable time, save the error information and ask a colleague or an AI assistant to help interpret it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final verification
&lt;/h2&gt;

&lt;p&gt;Run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;keysync &lt;span class="nt"&gt;--version&lt;/span&gt;
systemctl &lt;span class="nt"&gt;--user&lt;/span&gt; is-active keysync.service
keysync dsh status
ss &lt;span class="nt"&gt;-ltnp&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'127.0.0.1:3080'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then verify all four outcomes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;KeySync returns an explicit version.&lt;/li&gt;
&lt;li&gt;The user-level service is &lt;code&gt;active&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;DSH is &lt;code&gt;running&lt;/code&gt; and Remote is &lt;code&gt;connected&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You can open the real DSH instance from KeySync and complete one read-only investigation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What you now have is not an AI that should be allowed to change a server freely. It is a diagnostic partner that can remain on the target Linux host and collect evidence continuously.&lt;/p&gt;

&lt;p&gt;For a new operator, the goal is not merely to memorize fewer commands. It is to know how to inspect first, when to stop, and which decisions must remain with a human.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try the workflow
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://sublang.ai/zh/keysync/download/?utm_source=multi_platform_bobo&amp;amp;utm_medium=social&amp;amp;utm_content=101" rel="noopener noreferrer"&gt;Download KeySync&lt;/a&gt; to connect a Linux device and remotely open its DSH instance.&lt;/li&gt;
&lt;li&gt;Visit the &lt;a href="https://deepseek.com/harness/" rel="noopener noreferrer"&gt;DeepSeek Harness website&lt;/a&gt; for the official introduction, installation instructions, and open-source project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Version note: tested on September 3, 2026. KeySync and DeepSeek Harness evolve quickly, so read the current public release manifest before installation. This tutorial is for learning and non-production validation; it does not replace your organization’s access-control or change-management procedures.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>linux</category>
      <category>devops</category>
      <category>ai</category>
    </item>
    <item>
      <title>Stop Copying Linux Logs Into AI—Let the Agent Investigate on the Failing Machine</title>
      <dc:creator>Bobo Yang</dc:creator>
      <pubDate>Thu, 03 Sep 2026 09:09:12 +0000</pubDate>
      <link>https://dev.to/yangbobo2021/stop-copying-linux-logs-into-ai-let-the-agent-investigate-on-the-failing-machine-3504</link>
      <guid>https://dev.to/yangbobo2021/stop-copying-linux-logs-into-ai-let-the-agent-investigate-on-the-failing-machine-3504</guid>
      <description>&lt;p&gt;&lt;em&gt;A production release was blocked by a nearly full disk. The useful part of the AI workflow was not a clever command—it was keeping the investigation on the affected host while preserving a human approval boundary.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Disclosure: I’m affiliated with KeySync, the remote-access product used in this incident.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;At 4:09 p.m. on August 31, I triggered the production release for version 0.1.115.&lt;/p&gt;

&lt;p&gt;Builds started for macOS, Windows, Linux x64, Linux ARM64, and the standalone CLI. Installation, startup, signing, and notarization checks passed one after another.&lt;/p&gt;

&lt;p&gt;Thirty-nine minutes later, all five build groups had succeeded.&lt;/p&gt;

&lt;p&gt;But the release did not continue.&lt;/p&gt;

&lt;p&gt;The final CI gate failed:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The server has only 6.5 GiB free. A safe release requires 17.4 GiB.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Every candidate artifact had passed validation, yet production was blocked by a disk that was almost full.&lt;/p&gt;

&lt;p&gt;The most dangerous response was not moving slowly. It was moving too quickly.&lt;/p&gt;

&lt;p&gt;Deleting an old-looking directory might recover enough space, or it might remove a live database, a model, or the rollback package we would need ten minutes later. Expanding the disk would be easy, but if a retention job had silently stopped working, more capacity would only postpone the next incident.&lt;/p&gt;

&lt;p&gt;I needed three answers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What was actually consuming the space?&lt;/li&gt;
&lt;li&gt;Which data was safe to remove, and which data was still in use?&lt;/li&gt;
&lt;li&gt;Was this a one-time capacity problem, or was a process continuously generating garbage?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Two clicks from a failed CI gate to the affected server
&lt;/h2&gt;

&lt;p&gt;I did not start by looking up an IP address or searching for an SSH configuration and key.&lt;/p&gt;

&lt;p&gt;The production Linux server was already connected to KeySync. I opened the device list, selected the server, and clicked &lt;strong&gt;Remote Open&lt;/strong&gt;. DeepSeek Harness (DSH), which was installed on that host, opened in the browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcaphqrnr13txs19czh1g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fcaphqrnr13txs19czh1g.png" alt="KeySync device list showing a production Linux host with a Remote Open action" width="800" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The same production Linux host, online with DSH installed and available to open remotely.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;From the failed CI gate to the correct production server, the only decisions were selecting the device and opening its DSH instance.&lt;/p&gt;

&lt;p&gt;KeySync handled the first part of remote diagnosis: getting the agent to the correct machine. DSH handled the second part: continuing the investigation once it was there.&lt;/p&gt;

&lt;h2&gt;
  
  
  The copy-and-paste version would have taken at least six round trips
&lt;/h2&gt;

&lt;p&gt;In the usual workflow, I would log in, run &lt;code&gt;df&lt;/code&gt;, and paste the output into an AI chat.&lt;/p&gt;

&lt;p&gt;The AI would ask for &lt;code&gt;du&lt;/code&gt;, so I would run that and paste another result. Once Docker and KeySync appeared near the top, the next requests would be container state, mounted volumes, directory details, historical files, and the cleanup scripts.&lt;/p&gt;

&lt;p&gt;The investigation would look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;run df -&amp;gt; copy output -&amp;gt; wait for an answer
run du -&amp;gt; copy output -&amp;gt; wait for an answer
inspect Docker -&amp;gt; copy output -&amp;gt; wait for an answer
expand large directories -&amp;gt; copy output -&amp;gt; wait for an answer
read cleanup scripts -&amp;gt; copy output -&amp;gt; wait for an answer
run validation -&amp;gt; copy the result again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It looks like the human is investigating. In practice, the human is acting as a remote keyboard for the AI.&lt;/p&gt;

&lt;p&gt;Because DSH was running on the target host, it could inspect the disk, directories, processes, containers, and scripts within the permissions I granted.&lt;/p&gt;

&lt;p&gt;My first instruction was deliberately not “clean this up.” It was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Perform a read-only investigation only. Do not delete anything, restart services, or modify configuration. First determine why the disk is full. Separate live data, recoverable duplicates, and backups that must not be removed. Then decide whether the right answer is cleanup or expansion.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I did not prescribe a sequence of commands. I stated the objective and the boundaries. The agent chose each next command from the result of the previous one.&lt;/p&gt;

&lt;h2&gt;
  
  
  One objective, a continuous investigation
&lt;/h2&gt;

&lt;p&gt;DSH first used &lt;code&gt;df&lt;/code&gt; to verify that this was not a false CI alert: the root filesystem was genuinely at 98%.&lt;/p&gt;

&lt;p&gt;It then continued narrowing the scope:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;df confirms the root filesystem is at 98%
  -&amp;gt; du narrows the problem to KeySync and Docker
  -&amp;gt; container and volume inspection rules out blind Docker cleanup
  -&amp;gt; KeySync directories reveal 77.85 GiB of staged uploads
  -&amp;gt; historical version directories show abnormal retention
  -&amp;gt; the release cleanup script is inspected
  -&amp;gt; real directory names are compared with the matching rule
  -&amp;gt; a one-character mismatch is found
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The time saving did not come from typing fewer commands. It came from keeping the investigative context intact. The agent could see the last result and immediately test the next hypothesis.&lt;/p&gt;

&lt;h2&gt;
  
  
  The first branch: do not prune Docker
&lt;/h2&gt;

&lt;p&gt;This Ubuntu production server had been running for more than a year. It hosted KeySync, databases, object storage, monitoring, internal services, and several containerized applications.&lt;/p&gt;

&lt;p&gt;Docker had 37 containers, and every one of them was running. Some test environments had been alive for ten months.&lt;/p&gt;

&lt;p&gt;So “Docker is large” was not enough evidence to run &lt;code&gt;docker system prune&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After checking mounts and volumes, DSH found that the largest volumes were still attached to services. There were no stopped containers that could be reclaimed safely. System logs were not the main consumer, and inode exhaustion was not the problem.&lt;/p&gt;

&lt;p&gt;The important disk consumers were:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Major consumer&lt;/th&gt;
&lt;th&gt;Usage at the time&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;KeySync upload staging&lt;/td&gt;
&lt;td&gt;77.85 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker data, images, and containers&lt;/td&gt;
&lt;td&gt;57.08 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KeySync public downloads&lt;/td&gt;
&lt;td&gt;34.42 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KeySync release and candidate archives&lt;/td&gt;
&lt;td&gt;33.96 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KeySync backups&lt;/td&gt;
&lt;td&gt;18.50 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ollama models&lt;/td&gt;
&lt;td&gt;16.82 GiB&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The disk had a total capacity of 294.9 GiB, with 276.3 GiB used. The system reported 98% usage and only about 6.4 GiB available to a normal process.&lt;/p&gt;

&lt;p&gt;The first conclusion was clear: immediate expansion was unnecessary, and active Docker or database data should not be touched. The 77.85 GiB upload-staging directory deserved the next investigation.&lt;/p&gt;

&lt;h2&gt;
  
  
  A nearly invisible error in the retention rule
&lt;/h2&gt;

&lt;p&gt;If I had pasted only the &lt;code&gt;du&lt;/code&gt; output into a chat, the AI could have told me that the directory was large.&lt;/p&gt;

&lt;p&gt;But DSH was still on the machine. It could follow the evidence from the large directory to its file structure, and from the file structure to the release script responsible for cleaning it.&lt;/p&gt;

&lt;p&gt;Production upload directories were named like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;client-0.1.113
client-0.1.114
client-0.1.115
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The cleanup rule matched this instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;client-v*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The configuration said to keep only the newest two versions, and the cleanup script completed without an error. But it never matched the real directories.&lt;/p&gt;

&lt;p&gt;No alert fired. No red status appeared. Fifteen upload sets accumulated over time.&lt;/p&gt;

&lt;p&gt;There was a second problem: the public-download cleanup script scanned only the top level. Old installers under the Windows, macOS, and Linux subdirectories were never considered.&lt;/p&gt;

&lt;p&gt;All the tests had passed. The test fixtures used names such as &lt;code&gt;client-v...&lt;/code&gt;, exactly matching the incorrect rule, and never represented the real &lt;code&gt;client-...&lt;/code&gt; production convention.&lt;/p&gt;

&lt;p&gt;One letter—&lt;code&gt;v&lt;/code&gt;—turned “keep the latest two” into “never clean anything.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding deletable data did not mean deleting it
&lt;/h2&gt;

&lt;p&gt;DSH remained inside the read-only boundary after identifying the likely cause.&lt;/p&gt;

&lt;p&gt;It selected three upload directories for which complete release copies already existed elsewhere, then calculated hashes for the files in both locations. All 5,487 files matched.&lt;/p&gt;

&lt;p&gt;Only then did it recommend a concrete action:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Delete only the three verified duplicate upload directories. Expected recovery: approximately 15.4 GiB. Release artifacts, databases, and backups are outside the scope of this operation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This distinction matters. Allowing an agent to enter a production server is not the same as allowing it to delete production data.&lt;/p&gt;

&lt;p&gt;The investigation could proceed continuously. Destructive action still required a human decision about scope and consequences.&lt;/p&gt;

&lt;p&gt;After I approved that exact scope, the cleanup removed only those three duplicate directories.&lt;/p&gt;

&lt;p&gt;Available space increased from 6.41 GiB to 21.84 GiB. The other 39,392 protected files, 11 business-configuration tables, database backups, and deployed versions were unchanged.&lt;/p&gt;

&lt;p&gt;At 5:22 p.m., free space exceeded the 17.40 GiB release budget and CI resumed. Ten minutes later, eight classes of downloadable packages, six platform-update configurations, and 24 web files passed validation. Version 0.1.115 went live.&lt;/p&gt;

&lt;h2&gt;
  
  
  A green release did not end the investigation
&lt;/h2&gt;

&lt;p&gt;Recovering 15.4 GiB solved the immediate release failure, but it did not answer why retention had failed or whether the directory would keep growing.&lt;/p&gt;

&lt;p&gt;In the same DSH conversation, I asked a follow-up:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Why is KeySync using so much disk space? Find the process that will cause it to continue growing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The conversation still had the server’s directory layout, container state, release paths, and scripts in context. There was no need to reconstruct the incident in a new chat.&lt;/p&gt;

&lt;p&gt;Using the real production naming convention, DSH reproduced the bug: with four upload directories present and retention set to two, the script deleted none of them.&lt;/p&gt;

&lt;p&gt;It also found nine independent copies of the same Windows portable package across three release locations. Their hashes were identical, and together they consumed 1.62 GiB.&lt;/p&gt;

&lt;p&gt;The real problem was not an undersized disk. Release files were duplicated, and the automatic cleanup rules did not cover the names and directory structure used in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  A one-line fix required much more than a one-line safety process
&lt;/h2&gt;

&lt;p&gt;The matching rule needed a one-line change. Production remediation required much more:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add ten focused tests covering old and new naming conventions, retention counts, protection of the current version, unrelated directories, and symbolic links.&lt;/li&gt;
&lt;li&gt;Check 20,083 files in eleven historical upload sets.&lt;/li&gt;
&lt;li&gt;Create recoverable deduplicated backups for 1,512 files whose contents were not duplicated elsewhere.&lt;/li&gt;
&lt;li&gt;Preserve approximately 7.89 GiB of unique data.&lt;/li&gt;
&lt;li&gt;Limit the operation to upload staging instead of opportunistically cleaning public downloads, Docker, databases, or model files.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After the rule passed its tests and the recovery data was verified, I approved the final execution scope.&lt;/p&gt;

&lt;p&gt;Eleven historical upload sets were removed, leaving only the two newest. The operation recovered 48.46 GiB, bringing sampled free space to approximately 63.19 GiB.&lt;/p&gt;

&lt;p&gt;DSH then verified the current downloads, update feeds, web files, and business configuration on the same host. Protected files were unchanged except for the expected hard-link differences.&lt;/p&gt;

&lt;p&gt;The result was a complete operational chain:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;detect the anomaly -&amp;gt; rule out unsafe shortcuts -&amp;gt; locate the root cause -&amp;gt; control risk -&amp;gt; wait for authorization -&amp;gt; execute -&amp;gt; verify&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Space the agent correctly refused to reclaim
&lt;/h2&gt;

&lt;p&gt;The investigation also found several running containers with names beginning with &lt;code&gt;test-&lt;/code&gt;. Some had been running for about ten months, alongside even older testing and tooling services.&lt;/p&gt;

&lt;p&gt;That exposed a separate lifecycle problem: temporary deployments had gradually become part of a production server without a consistent retirement process.&lt;/p&gt;

&lt;p&gt;But old does not mean safe to delete.&lt;/p&gt;

&lt;p&gt;The containers were running, and some of their volumes contained real data. DSH classified them as systems requiring owner review, not as immediately reclaimable garbage.&lt;/p&gt;

&lt;p&gt;Each service needs its dependencies, data value, and shutdown window confirmed before migration, archival, or deletion. Otherwise, an attempt to improve a disk-usage number simply trades a capacity risk for data loss.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where remote agents are useful—and where authority should stop
&lt;/h2&gt;

&lt;p&gt;If I already know the exact command I need, SSH remains simple and reliable.&lt;/p&gt;

&lt;p&gt;The strongest case for a remote agent is the unknown phase of an incident: a Linux host is unhealthy, but nobody yet knows whether to start with logs, storage, containers, processes, configuration, or source code.&lt;/p&gt;

&lt;p&gt;In this workflow, KeySync answers “how does the agent reach the correct machine?” DSH answers “once it is there, how does it continue the investigation?”&lt;/p&gt;

&lt;p&gt;The convenience is that I do not need a separate remote-operation setup for every Linux host. The intelligence is that the agent does not wait passively for the next copied fragment of evidence.&lt;/p&gt;

&lt;p&gt;The safety model is equally important:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start with a read-only objective and explicit prohibitions.&lt;/li&gt;
&lt;li&gt;Let the agent choose investigative commands based on evidence.&lt;/li&gt;
&lt;li&gt;Keep deletion, restarts, and configuration changes behind human approval.&lt;/li&gt;
&lt;li&gt;Define exact targets and expected effects before approval.&lt;/li&gt;
&lt;li&gt;Verify protected data and service health after execution.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My view is that agents operating directly on remote hosts will become an increasingly common part of operations work. The concern is equally obvious: a single incorrect command on a production system can cause an outage or irreversible data loss.&lt;/p&gt;

&lt;p&gt;Would you allow an AI agent to investigate or maintain production systems remotely? What safeguards would you require—read-only credentials, restricted shells, &lt;code&gt;sudoers&lt;/code&gt; policies, command allowlists, sandboxes, approval gateways, snapshots, or something else?&lt;/p&gt;

&lt;h2&gt;
  
  
  Try the workflow
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://sublang.ai/zh/keysync/download/?utm_source=multi_platform_bobo&amp;amp;utm_medium=social&amp;amp;utm_content=100" rel="noopener noreferrer"&gt;Download KeySync&lt;/a&gt; to connect a Linux device and remotely open its DSH instance.&lt;/li&gt;
&lt;li&gt;Visit the &lt;a href="https://deepseek.com/harness/" rel="noopener noreferrer"&gt;DeepSeek Harness website&lt;/a&gt; for the official introduction, installation instructions, and open-source project.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>ai</category>
      <category>security</category>
    </item>
    <item>
      <title>After DSH Added Browser Tokens, I Tested 7 Remote Access Approaches</title>
      <dc:creator>Bobo Yang</dc:creator>
      <pubDate>Tue, 01 Sep 2026 14:03:23 +0000</pubDate>
      <link>https://dev.to/yangbobo2021/after-dsh-added-browser-tokens-i-tested-7-remote-access-approaches-3o9g</link>
      <guid>https://dev.to/yangbobo2021/after-dsh-added-browser-tokens-i-tested-7-remote-access-approaches-3o9g</guid>
      <description>&lt;p&gt;Someone recently asked me a fair question: if DeepSeek Harness already has a native interface, why would anyone need KeySync?&lt;/p&gt;

&lt;p&gt;If DSH only runs on the computer in front of you, the answer is simple: use native DSH. There is no reason to add a remote layer for a problem you do not have.&lt;/p&gt;

&lt;p&gt;KeySync is for a different situation. DSH is running on a home computer, a work machine, or a headless Linux server, and you want to continue using the complete DSH interface from a phone or another computer.&lt;/p&gt;

&lt;p&gt;That used to sound like a port-forwarding problem. With the new DSH browser-token flow, however, making port 3080 reachable is no longer enough.&lt;/p&gt;

&lt;p&gt;Rather than compare feature lists subjectively, I defined one acceptance set for a regular user and evaluated seven remote-access approaches against it: SSH, Tailscale plus a gateway, reverse-proxy plugins, dedicated mobile projects, a P2P-oriented DSH transport, and KeySync.&lt;/p&gt;

&lt;p&gt;The result is clear for this target: &lt;strong&gt;KeySync currently offers the most complete combination of low setup effort, the full native DSH UI, no public inbound port, end-to-end confidentiality, and tested support for the new DSH browser-auth flow.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It does not win every possible category. It wins the combination that matters to a regular user who wants to open a remote DSH safely and get back to work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Define the user before defining “best”
&lt;/h2&gt;

&lt;p&gt;This comparison targets someone who:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;may run DSH on a Linux server with no graphical desktop;&lt;/li&gt;
&lt;li&gt;wants to continue a task from a phone or another computer;&lt;/li&gt;
&lt;li&gt;does not want to configure SSH tunnels, VPNs, frp, DNS, certificates, or reverse proxies;&lt;/li&gt;
&lt;li&gt;wants the complete DSH Web UI, not a partial reimplementation;&lt;/li&gt;
&lt;li&gt;will not expose an agent control plane that can read files and execute tools directly to the public Internet.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I turned those needs into nine checks:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Networking knowledge:&lt;/strong&gt; no need to understand port forwarding, NAT, VPN policy, reverse proxies, or certificates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Headless Linux:&lt;/strong&gt; the host can run without a desktop environment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Access device:&lt;/strong&gt; a normal browser is sufficient on a phone or computer.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI fidelity:&lt;/strong&gt; the remote interface is the complete native DSH Web UI.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public exposure:&lt;/strong&gt; the host opens no public inbound DSH or proxy port.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content confidentiality:&lt;/strong&gt; a relay or cloud service cannot decrypt DSH pages, prompts, responses, cookies, or files.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication integrity:&lt;/strong&gt; the solution preserves DSH's own token/cookie boundary instead of replacing it with an outer login page.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Current compatibility evidence:&lt;/strong&gt; the project has a version statement, implementation path, or real test for the &lt;code&gt;0.1.2-alpha&lt;/code&gt; line.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ongoing operations:&lt;/strong&gt; certificates, reconnection, device revocation, launch URLs, and version changes are handled by the product.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Direct P2P is intentionally not a hard requirement. P2P is a route, not a security outcome. A regular user ultimately cares whether the connection is dependable, whether the relay can read the content, and how much infrastructure must be maintained.&lt;/p&gt;

&lt;h2&gt;
  
  
  The new browser token raises the compatibility bar
&lt;/h2&gt;

&lt;p&gt;As of September 1, 2026, the npm &lt;code&gt;latest&lt;/code&gt; tag for &lt;code&gt;@deepseek-ai/dsh&lt;/code&gt; is &lt;code&gt;0.1.1-rc.2&lt;/code&gt;, while the &lt;code&gt;alpha&lt;/code&gt; tag is &lt;code&gt;0.1.2-alpha.3&lt;/code&gt;. The browser-auth change discussed here belongs to the &lt;code&gt;0.1.2-alpha&lt;/code&gt; line.&lt;/p&gt;

&lt;p&gt;According to the &lt;a href="https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/connection/README.md#browser-authentication-and-request-trust" rel="noopener noreferrer"&gt;official DSH connection documentation&lt;/a&gt;, the new flow works roughly like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;DSH creates a random launch token on startup.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dsh web&lt;/code&gt; prints a loopback URL containing &lt;code&gt;?token=...&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The browser may exchange that token only at the root path for a signed cookie.&lt;/li&gt;
&lt;li&gt;Every later Host RPC and WebSocket stream requires a valid browser session.&lt;/li&gt;
&lt;li&gt;The cookie is bound to the normalized hostname and port and uses &lt;code&gt;HttpOnly&lt;/code&gt; and &lt;code&gt;SameSite=Strict&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Host, Origin, and &lt;code&gt;Sec-Fetch-Site&lt;/code&gt; checks remain, but they do not replace identity authentication.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is a sensible security improvement. DSH Web can start agents, read and write workspaces, and invoke tools. It is a code-execution control plane, not a read-only dashboard.&lt;/p&gt;

&lt;p&gt;It also means a remote solution must now complete three layers: network reachability, remote-user authorization, and DSH's own browser session. Solving only the first layer is no longer sufficient.&lt;/p&gt;

&lt;h2&gt;
  
  
  Round one: can a regular user actually operate it?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;No networking expertise&lt;/th&gt;
&lt;th&gt;Headless Linux&lt;/th&gt;
&lt;th&gt;Normal browser&lt;/th&gt;
&lt;th&gt;Complete native UI&lt;/th&gt;
&lt;th&gt;No public inbound port&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SSH local forwarding&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Partial: an SSH entry point is usually required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tailscale + DSH-aware gateway&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Partial: access devices normally join the tailnet&lt;/td&gt;
&lt;td&gt;Depends on the gateway&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reverse-proxy / frp plugins&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Depends on deployment&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DSH Remote&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;WebUI or Android&lt;/td&gt;
&lt;td&gt;Partial: dedicated control UI&lt;/td&gt;
&lt;td&gt;Yes with LAN/Tailscale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DSH Mobile Suite&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Web/mobile client&lt;/td&gt;
&lt;td&gt;Partial: mobile-oriented experience&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ds-harness-remote&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Partial&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No: paired client required&lt;/td&gt;
&lt;td&gt;Strong on Desktop; dedicated Android UI&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KeySync&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;SSH remains reliable, but the user must know how to reach the server, establish and keep an &lt;code&gt;ssh -L&lt;/code&gt; tunnel alive, and obtain the launch-token URL produced by DSH.&lt;/p&gt;

&lt;p&gt;Tailscale is an excellent encrypted network, but it does not automatically turn a remote &lt;code&gt;127.0.0.1:3080&lt;/code&gt; listener into a DSH-compatible browser endpoint. A gateway must still bridge loopback and correctly handle DSH authentication.&lt;/p&gt;

&lt;p&gt;Dedicated mobile projects make a different tradeoff. They reimplement approvals, questions, files, notifications, or session views for a phone. That can be better for rapid mobile intervention, but it is not the same outcome as opening the complete native DSH interface in any browser.&lt;/p&gt;

&lt;p&gt;The KeySync path is closer to ordinary software:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install and sign in to KeySync on the machine running DSH.&lt;/li&gt;
&lt;li&gt;Sign in with the same account from another computer or a phone browser.&lt;/li&gt;
&lt;li&gt;Select the online device and choose &lt;strong&gt;Open remotely&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Continue in the complete DSH Web UI.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The user does not need to know which port DSH uses or configure a public IP, router, VPN, frp server, DNS record, or TLS certificate. A Linux CLI build covers servers without a graphical desktop, while the access device needs only a browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Round two: does security and current compatibility hold up?
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;End-to-end network confidentiality&lt;/th&gt;
&lt;th&gt;Preserves DSH auth boundary&lt;/th&gt;
&lt;th&gt;
&lt;code&gt;0.1.2-alpha&lt;/code&gt; evidence&lt;/th&gt;
&lt;th&gt;Certificate/reconnect/version maintenance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SSH local forwarding&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;Yes in principle&lt;/td&gt;
&lt;td&gt;Yes in principle&lt;/td&gt;
&lt;td&gt;User-managed tunnel and launch URL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tailscale + gateway&lt;/td&gt;
&lt;td&gt;Yes at the network layer&lt;/td&gt;
&lt;td&gt;Depends on gateway&lt;/td&gt;
&lt;td&gt;Depends on gateway&lt;/td&gt;
&lt;td&gt;User maintains network and gateway&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reverse-proxy / frp plugins&lt;/td&gt;
&lt;td&gt;Depends where TLS terminates&lt;/td&gt;
&lt;td&gt;Current inspected versions do not&lt;/td&gt;
&lt;td&gt;No public evidence in inspected versions&lt;/td&gt;
&lt;td&gt;User maintains proxy, certificate, and plugin&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DSH Remote&lt;/td&gt;
&lt;td&gt;Depends on LAN/Tailscale setup&lt;/td&gt;
&lt;td&gt;Uses its own gateway model&lt;/td&gt;
&lt;td&gt;No explicit alpha statement found&lt;/td&gt;
&lt;td&gt;Plugin and client maintenance required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DSH Mobile Suite&lt;/td&gt;
&lt;td&gt;Application-layer E2EE&lt;/td&gt;
&lt;td&gt;Uses a plugin path&lt;/td&gt;
&lt;td&gt;Public baseline is &lt;code&gt;0.1.0-rc.6&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Companion, relay, and client required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ds-harness-remote&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Noise IK E2EE&lt;/td&gt;
&lt;td&gt;Uses DSH Remote/API transport&lt;/td&gt;
&lt;td&gt;Explicit alpha.1-alpha.2 support&lt;/td&gt;
&lt;td&gt;Plugin, paired client, and matching transport generation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KeySync&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Browser-to-device TLS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;KeySync and DSH sessions coexist&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Alpha.2 acceptance completed&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Client-managed&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  SSH and Tailscale are secure foundations, not zero-configuration DSH products
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://man.openbsd.org/ssh" rel="noopener noreferrer"&gt;OpenSSH &lt;code&gt;-L&lt;/code&gt;&lt;/a&gt; forwards a local listener through an encrypted SSH channel to a host and port on the remote side. For one developer who already maintains SSH keys and server access, it is hard to beat.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://tailscale.com/docs/concepts/tailscale-encryption" rel="noopener noreferrer"&gt;Tailscale&lt;/a&gt; uses WireGuard end-to-end encryption. Even when traffic uses a DERP relay, the relay sees encrypted WireGuard traffic. Grants and ACLs add strong device and organization policy.&lt;/p&gt;

&lt;p&gt;Neither one completes the DSH application layer. With Tailscale in particular, DSH remains bound to loopback. A gateway still has to handle the launch token, cookies, Host, Origin, WebSocket traffic, and future DSH changes.&lt;/p&gt;

&lt;p&gt;Their weakness here is not cryptography. It is the technical and operational work required to finish the user's actual task.&lt;/p&gt;

&lt;h3&gt;
  
  
  Generic proxy plugins expose the new compatibility gap
&lt;/h3&gt;

&lt;p&gt;I inspected the current implementations of two public proxy plugins.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/siberiah2o/dsh-plugin-remote" rel="noopener noreferrer"&gt;&lt;code&gt;dsh-plugin-remote@0.5.12&lt;/code&gt;&lt;/a&gt; includes scrypt credentials, an HttpOnly session cookie, allowlists, and HTTP/WebSocket proxying. Its &lt;a href="https://github.com/siberiah2o/dsh-plugin-remote/blob/19ffcc2914ee063b081eb8088be32256faf9402f/gateway/server.mjs#L780-L880" rel="noopener noreferrer"&gt;current proxy path&lt;/a&gt;, however, removes browser cookies before upstream forwarding and rewrites Host/Origin. It does not read the DSH launch-token URL.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/xiaosenho/dsh-plugin-remote-access" rel="noopener noreferrer"&gt;&lt;code&gt;@xiaosenho/dsh-plugin-remote-access@0.1.4&lt;/code&gt;&lt;/a&gt; offers LAN and frpc modes. Its outer access token becomes an HttpOnly, SameSite=Strict cookie, but its &lt;a href="https://github.com/xiaosenho/dsh-plugin-remote-access/blob/40cee2c77fd56b0920b1f0ed96c44e94165e9b22/src/proxy.ts#L53-L66" rel="noopener noreferrer"&gt;proxy implementation&lt;/a&gt; also deletes upstream cookies and has no alpha launch-token bootstrap path.&lt;/p&gt;

&lt;p&gt;The precise conclusion is limited to those versions: they provide no public evidence for the &lt;code&gt;0.1.2-alpha&lt;/code&gt; browser-auth flow, and their current proxy logic cannot complete it. They may remain useful on rc.2 and can be updated in the future. The important lesson is that an outer login page and a successful HTTP 200 do not prove that DSH RPC and WebSocket sessions work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dedicated clients are strong, but optimize a different outcome
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/Blank-not-black/dsh-Remote" rel="noopener noreferrer"&gt;DSH Remote&lt;/a&gt; provides Android/WebUI access, device keys, approvals, questions, files, and offline history. It behaves more like a purpose-built mobile agent console. That can be valuable, but it is not a transparent copy of the full DSH Web UI. Its public README does not currently make an explicit &lt;code&gt;0.1.2-alpha&lt;/code&gt; compatibility claim.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/april-jk/dsh-mobile-suite" rel="noopener noreferrer"&gt;DSH Mobile Suite&lt;/a&gt; uses an outbound Companion-to-Relay connection and documents an application-layer E2EE design. Its security documentation also identifies a real browser boundary: JavaScript served by the relay-hosted web application is still a trusted endpoint, so E2EE cannot protect against a malicious deployment replacing that code. Its &lt;a href="https://github.com/april-jk/dsh-mobile-plugin#compatibility" rel="noopener noreferrer"&gt;plugin compatibility statement&lt;/a&gt; currently says it was tested with &lt;code&gt;@deepseek-ai/dsh@0.1.0-rc.6&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/liguobao/ds-harness-remote" rel="noopener noreferrer"&gt;&lt;code&gt;ds-harness-remote@0.4.2&lt;/code&gt;&lt;/a&gt; is the most technically distinctive direct competitor in this set. It integrates with DSH communication transports rather than proxying the browser page. It documents legacy &lt;code&gt;ApiProxy&lt;/code&gt; support for rc.2 and Typert Remote Gateway support for alpha.1 through alpha.2. Its Noise IK data path negotiates LAN, P2P, TURN, and WebSocket Relay routes.&lt;/p&gt;

&lt;p&gt;That is attractive when direct-connect preference or a dedicated Android experience is the priority. The tradeoff is that the host and access side need paired components, and both Desktop ends must use the same DSH transport generation. It solves “connect a dedicated client to remote DSH.” KeySync solves “open the complete DSH in any normal browser.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Why KeySync passes the complete acceptance set
&lt;/h2&gt;

&lt;p&gt;KeySync is not merely another reverse proxy in front of a public port. It separates user authorization, encrypted transport, and DSH authentication into distinct boundaries.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. User and device authorization
&lt;/h3&gt;

&lt;p&gt;Only an authenticated owner can select an online device. Each remote open operation creates a short-lived, single-use grant scoped to the user and device. After device-side verification, the Gateway creates an HttpOnly, Secure, SameSite=Strict remote session.&lt;/p&gt;

&lt;p&gt;Cross-user access, expired grants, replayed grants, and wrong-device claims fail closed. This layer answers: who is allowed to reach this device?&lt;/p&gt;

&lt;h3&gt;
  
  
  2. End-to-end TLS from browser to device
&lt;/h3&gt;

&lt;p&gt;The DSH host creates a certificate private key and CSR locally. The private key remains on that device. The remote browser's HTTPS connection passes through KeySync Relay, but TLS terminates at the Gateway running on the user's device.&lt;/p&gt;

&lt;p&gt;The Relay can route connections, enforce limits, and observe connection metadata. It cannot decrypt DSH HTML, prompts, model responses, cookies, or attachments.&lt;/p&gt;

&lt;p&gt;KeySync's release acceptance matrix covers SNI routing, TLS byte passthrough, slow-stream isolation, flow limits, reconnects, and authenticated same-device process takeover.&lt;/p&gt;

&lt;p&gt;This is &lt;strong&gt;relay-assisted end-to-end TLS&lt;/strong&gt;, not direct network P2P. The topology includes Relay, while the plaintext endpoints remain the browser and the user's device.&lt;/p&gt;

&lt;p&gt;For a regular user, that is a practical tradeoff. Direct P2P may lower latency and relay cost, but NAT, firewalls, and network changes often require TURN or relay fallback. KeySync chooses a consistently reachable relay path while TLS passthrough preserves the property that the relay cannot read the content.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. DSH's launch token is preserved, not bypassed
&lt;/h3&gt;

&lt;p&gt;For &lt;code&gt;0.1.2-alpha.2&lt;/code&gt;, KeySync captures the loopback launch-token URL from DSH startup output, validates its host and port, and redacts the token from logs.&lt;/p&gt;

&lt;p&gt;On the first authenticated browser request to the root path, the device Gateway forwards the request to the DSH token URL. DSH performs its normal exchange and creates its authority-bound cookie. Later HTTP and WebSocket requests keep the DSH cookie. The KeySync remote-session cookie is stripped before upstream forwarding, and the DSH launch token is not replayed after the DSH session exists.&lt;/p&gt;

&lt;p&gt;The two authentication layers therefore have separate jobs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;KeySync decides who may connect to the device.&lt;/li&gt;
&lt;li&gt;DSH decides whether this browser owns a valid DSH session.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is more work than placing one password page in front of a proxy, but it preserves the security boundary DSH intentionally added.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The product manages more than a tunnel
&lt;/h3&gt;

&lt;p&gt;Users maintain an entire workflow, not just a TCP port. KeySync brings these pieces into one entry point:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;install or detect DSH on Windows, macOS, and Linux;&lt;/li&gt;
&lt;li&gt;configure a model service and start DSH;&lt;/li&gt;
&lt;li&gt;capture the correct access URL produced by the installed DSH version;&lt;/li&gt;
&lt;li&gt;show device, DSH, and tunnel status;&lt;/li&gt;
&lt;li&gt;manage device identity, certificates, routes, and reconnects;&lt;/li&gt;
&lt;li&gt;open remote DSH from another KeySync Client or any phone browser;&lt;/li&gt;
&lt;li&gt;preserve the complete DSH page, streaming responses, WebSocket traffic, and attachments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;SSH, Tailscale, frp, and reverse proxies can each be part of a working system. KeySync's advantage is that a regular user does not have to assemble and maintain that system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There is no reason to add a remote layer when DSH is used only on the local machine.&lt;/p&gt;

&lt;p&gt;For a developer who already operates SSH and needs occasional access to one server, &lt;code&gt;ssh -L&lt;/code&gt; remains an excellent answer.&lt;/p&gt;

&lt;p&gt;For an organization that already runs Tailscale or Cloudflare Zero Trust and has people maintaining identity, policy, and gateways, extending that infrastructure may be the right choice.&lt;/p&gt;

&lt;p&gt;For direct-P2P-first networking, dedicated Android interaction, or mobile approval workflows, &lt;code&gt;ds-harness-remote&lt;/code&gt;, DSH Remote, and DSH Mobile Suite deserve serious evaluation, with close attention to the DSH versions they support.&lt;/p&gt;

&lt;p&gt;But consider this requirement set:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DSH runs on a home computer, work machine, or headless Linux server.&lt;/li&gt;
&lt;li&gt;The user is not a network engineer.&lt;/li&gt;
&lt;li&gt;The host exposes no public inbound port.&lt;/li&gt;
&lt;li&gt;Phones and other computers use only a normal browser.&lt;/li&gt;
&lt;li&gt;The remote interface is the complete native DSH UI.&lt;/li&gt;
&lt;li&gt;Relay cannot decrypt the content.&lt;/li&gt;
&lt;li&gt;DSH's new browser-token boundary remains intact.&lt;/li&gt;
&lt;li&gt;The user does not maintain tunnels, certificates, and version adapters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For that user, &lt;strong&gt;KeySync is currently the most complete and practical option in this comparison.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It does not replace DSH with a new interface. It keeps native DSH safe, complete, and usable after you leave the host computer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it and inspect the sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sublang.ai/keysync/download" rel="noopener noreferrer"&gt;Download KeySync&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sublang.ai/keysync/" rel="noopener noreferrer"&gt;KeySync product page&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/deepseek-ai/deepseek-harness" rel="noopener noreferrer"&gt;DeepSeek Harness repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/deepseek-ai/deepseek-harness/blob/master/packages/client/connection/README.md#browser-authentication-and-request-trust" rel="noopener noreferrer"&gt;DSH browser authentication and request trust&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Remote access answers “where can I open DSH?” If you also want Codex or Claude Code as DSH conversation backends, we maintain two optional, separate plugins:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Codex DSH plugin: &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-codex" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; / &lt;a href="https://www.npmjs.com/package/relay-dsh-plugin-codex" rel="noopener noreferrer"&gt;npm&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Claude Code DSH plugin: &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-claude" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; / &lt;a href="https://www.npmjs.com/package/relay-dsh-plugin-claude" rel="noopener noreferrer"&gt;npm&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The plugins add conversation backends to DSH. KeySync handles installation, configuration, device management, and remote access. They are independent layers, and neither plugin is required when you do not need that backend.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Research date: September 1, 2026. DSH remains in Developer Preview, so versions and compatibility can change quickly. Third-party conclusions are limited to the linked versions, commits, and public materials. KeySync security and compatibility claims are based on the current implementation and release acceptance tests, not an independent third-party security audit.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>deepseek</category>
      <category>security</category>
      <category>ai</category>
      <category>linux</category>
    </item>
    <item>
      <title>Why I still wanted a DSH Codex plugin when the native Codex app is already good</title>
      <dc:creator>Bobo Yang</dc:creator>
      <pubDate>Tue, 01 Sep 2026 09:29:26 +0000</pubDate>
      <link>https://dev.to/yangbobo2021/why-i-still-wanted-a-dsh-codex-plugin-when-the-native-codex-app-is-already-good-2oh0</link>
      <guid>https://dev.to/yangbobo2021/why-i-still-wanted-a-dsh-codex-plugin-when-the-native-codex-app-is-already-good-2oh0</guid>
      <description>&lt;p&gt;A few people have asked a fair question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If the native Codex desktop experience is already good, why build a DSH Codex plugin?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My answer is simple: if I only work on my own machine, in front of my own desktop, I would use the native Codex app too.&lt;/p&gt;

&lt;p&gt;The DSH Codex plugin is not trying to prove that the native app is bad. It solves a different problem: &lt;strong&gt;remote access and headless/server-side agent workspaces&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real problem: agent work is not always tied to one desktop
&lt;/h2&gt;

&lt;p&gt;Many agent tasks are no longer just one prompt and one answer.&lt;/p&gt;

&lt;p&gt;In practice, I often want to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;start a coding task on one machine;&lt;/li&gt;
&lt;li&gt;leave that machine but still check progress from another device;&lt;/li&gt;
&lt;li&gt;run work inside a remote Linux project environment;&lt;/li&gt;
&lt;li&gt;keep using a conversation-style workbench instead of only a terminal;&lt;/li&gt;
&lt;li&gt;open the same agent workspace through a browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The native desktop experience is excellent when I am sitting in front of that machine.&lt;/p&gt;

&lt;p&gt;But once I want to open the same workspace remotely, or work with a server that has no desktop environment, I need another layer.&lt;/p&gt;

&lt;p&gt;That is where KeySync + DSH becomes useful.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F43v5xmn1vhn71iblr5wi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F43v5xmn1vhn71iblr5wi.png" alt="KeySync Web open remotely" width="800" height="113"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reason 1: I want remote access to a running DSH workspace
&lt;/h2&gt;

&lt;p&gt;KeySync provides a device entry point. From KeySync Web, I can open DeepSeek Harness running on another device through an &lt;code&gt;Open remotely&lt;/code&gt; action.&lt;/p&gt;

&lt;p&gt;The important part is not that this is "another chat UI".&lt;/p&gt;

&lt;p&gt;The important part is that I can enter the agent workbench on that machine without physically sitting in front of it.&lt;/p&gt;

&lt;p&gt;Once opened in the browser, DSH still gives me the familiar workbench shape: sessions, workspaces, mode selection, model selection, permission mode, tool feedback, and conversation history.&lt;/p&gt;

&lt;p&gt;It feels closer to bringing the existing workbench into a remote browser than starting a separate web chat from scratch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F20hbeas04exkthkjzu7b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F20hbeas04exkthkjzu7b.png" alt="Remote DSH conversation" width="800" height="482"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reason 2: many Linux servers are SSH-only
&lt;/h2&gt;

&lt;p&gt;This point needs to be phrased carefully.&lt;/p&gt;

&lt;p&gt;I am not saying Linux desktop support does not exist. The better distinction is that many real development servers are not desktop machines.&lt;/p&gt;

&lt;p&gt;They are often:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SSH-only;&lt;/li&gt;
&lt;li&gt;headless;&lt;/li&gt;
&lt;li&gt;not meant to run a long-lived GUI app;&lt;/li&gt;
&lt;li&gt;where the project dependencies, build tools, data, and runtime live;&lt;/li&gt;
&lt;li&gt;still places where a visual agent conversation can be helpful.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In that environment, a pure CLI workflow can be great, but it is not the same interaction model as a desktop-style agent workbench.&lt;/p&gt;

&lt;p&gt;DSH + KeySync fills that gap: it gives me a browser-accessible conversation workspace for machines and environments where a desktop app is not the natural fit.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4pbltwtmqa8skitcm92b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F4pbltwtmqa8skitcm92b.png" alt="Linux SSH no desktop evidence" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What role does the DSH Codex plugin play?
&lt;/h2&gt;

&lt;p&gt;My mental model is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DSH owns the workbench: sessions, workspace navigation, input, tool presentation, and side panels.&lt;/li&gt;
&lt;li&gt;Codex owns the coding-agent capability.&lt;/li&gt;
&lt;li&gt;The DSH Codex plugin connects the Codex-style agent backend into the DSH workbench.&lt;/li&gt;
&lt;li&gt;KeySync provides the remote device entry point.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is deliberately modest architecture. It is not a full IDE rewrite, and it is not trying to replace every native workflow.&lt;/p&gt;

&lt;p&gt;It is a plugin-based way to bring coding-agent capability into a remote-friendly DSH environment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8via11co0jywszodd5wj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F8via11co0jywszodd5wj.png" alt="Codex conversation in DSH" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  This is not a replacement argument
&lt;/h2&gt;

&lt;p&gt;I do not think the right question is "which tool replaces which?"&lt;/p&gt;

&lt;p&gt;The better questions are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where is the task actually running?&lt;/li&gt;
&lt;li&gt;Can I sit in front of that machine right now?&lt;/li&gt;
&lt;li&gt;Does the machine have a desktop session?&lt;/li&gt;
&lt;li&gt;Do I need terminal automation, or a conversation workbench?&lt;/li&gt;
&lt;li&gt;Do I need to resume the same work from another device?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My current split is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If I am doing local desktop development, the native Codex app is a great default.&lt;/li&gt;
&lt;li&gt;If I need remote access to an agent workbench, DSH + KeySync fits better.&lt;/li&gt;
&lt;li&gt;If I am working with an SSH-only or headless Linux server, the DSH Codex plugin gives me a more desktop-like conversation entry point.&lt;/li&gt;
&lt;li&gt;If I only need scripted execution, CLI tools are still excellent.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;KeySync download: &lt;a href="https://sublang.ai/keysync/download" rel="noopener noreferrer"&gt;https://sublang.ai/keysync/download&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DSH Codex plugin on GitHub: &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-codex" rel="noopener noreferrer"&gt;https://github.com/yangbobo2021/relay-dsh-plugin-codex&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DSH Codex plugin on npm: &lt;a href="https://www.npmjs.com/package/relay-dsh-plugin-codex" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/relay-dsh-plugin-codex&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DSH Claude plugin on GitHub: &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-claude" rel="noopener noreferrer"&gt;https://github.com/yangbobo2021/relay-dsh-plugin-claude&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DSH Claude plugin on npm: &lt;a href="https://www.npmjs.com/package/relay-dsh-plugin-claude" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/relay-dsh-plugin-claude&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DSH Plugin Manager on GitHub: &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-manager" rel="noopener noreferrer"&gt;https://github.com/yangbobo2021/relay-dsh-plugin-manager&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DSH Plugin Manager on npm: &lt;a href="https://www.npmjs.com/package/relay-dsh-plugin-manager" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/relay-dsh-plugin-manager&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;OpenAI Codex desktop app: &lt;a href="https://developers.openai.com/codex/app" rel="noopener noreferrer"&gt;https://developers.openai.com/codex/app&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;ChatGPT release notes: &lt;a href="https://help.openai.com/en/articles/6825453-chatgpt-release-notes" rel="noopener noreferrer"&gt;https://help.openai.com/en/articles/6825453-chatgpt-release-notes&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>remote</category>
      <category>ai</category>
      <category>devtools</category>
      <category>linux</category>
    </item>
    <item>
      <title>Not Just a Working Demo: Why We Ran 162 Migration Tests for Two DSH Plugins</title>
      <dc:creator>Bobo Yang</dc:creator>
      <pubDate>Sun, 30 Aug 2026 00:37:49 +0000</pubDate>
      <link>https://dev.to/yangbobo2021/not-just-a-working-demo-why-we-ran-162-migration-tests-for-two-dsh-plugins-5f34</link>
      <guid>https://dev.to/yangbobo2021/not-just-a-working-demo-why-we-ran-162-migration-tests-for-two-dsh-plugins-5f34</guid>
      <description>&lt;p&gt;We use Codex and Claude Code to build Relay. They are also part of the routine work behind the plugin repositories: implementation, tests, review, and debugging. When we started using DeepSeek Harness (DSH) as a project entry point, we wanted that work to continue. Moving to a different interface should not mean giving up the capabilities and sessions we already rely on.&lt;/p&gt;

&lt;p&gt;That is why we maintain two independently installable plugins for official DSH:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;relay-dsh-plugin-codex&lt;/code&gt;&lt;/strong&gt; (&lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-codex" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/relay-dsh-plugin-codex" rel="noopener noreferrer"&gt;npm&lt;/a&gt;) adds Codex App Server as a DSH conversation backend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;relay-dsh-plugin-claude&lt;/code&gt;&lt;/strong&gt; (&lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-claude" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/relay-dsh-plugin-claude" rel="noopener noreferrer"&gt;npm&lt;/a&gt;) adds the Claude Code Agent SDK as a DSH conversation backend.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Neither plugin patches DSH core or requires a Relay checkout. After installation, Codex and Claude Code appear as conversation modes inside DSH and continue using its project, history, composer, and tool surfaces.&lt;/p&gt;

&lt;p&gt;If the goal were only a demo, that would be enough: select a backend, send a prompt, and record the answer. We intend to use these plugins over time, so “it answered once” is not a useful acceptance standard.&lt;/p&gt;

&lt;h2&gt;
  
  
  We Did Not Want Users to Find the Boundaries for Us
&lt;/h2&gt;

&lt;p&gt;A successful chat hides many of the failures that matter in real work.&lt;/p&gt;

&lt;p&gt;Did the model actually receive the attached image? Can a user watch a ten-minute command make progress? Does Stop terminate the process, or only change the UI? Can a session survive a host restart? Do project Skills, MCP servers, and settings still apply? Can a secret used by a tool remain on disk even when it never appears in the visible conversation?&lt;/p&gt;

&lt;p&gt;Those paths decide whether a plugin can become part of daily development. Because we use the plugins ourselves, we did not want to claim broad Codex or Claude support and wait for users to identify every exception.&lt;/p&gt;

&lt;p&gt;We chose to map the boundary first. A workflow that completes is supported. A workflow that only partly completes is marked partial. A workflow that does not complete remains a failure. The purpose is not to produce a flattering score. It is to decide what to fix next and to tell users what work they can safely move.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where the 162 Tests Came From
&lt;/h2&gt;

&lt;p&gt;We split real development work into 162 atomic requirements: 76 for Codex and 86 for Claude. Every requirement has its own case, run record, and reviewed result.&lt;/p&gt;

&lt;p&gt;The matrix covers conversation and multi-turn context, images and files, code and shell tools, tests and Git, Skills, MCP, project configuration, permissions, environment variables, session import, host restarts, and long-context continuation. These are not names collected for a checklist. They are paths we reach while using Codex and Claude Code on actual repositories.&lt;/p&gt;

&lt;p&gt;By August 29, 2026, all 162 cases had results. We retained 167 runs in total; five were reviewed Codex reruns and do not inflate the requirement count.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Plugin&lt;/th&gt;
&lt;th&gt;Atomic capabilities&lt;/th&gt;
&lt;th&gt;Supported&lt;/th&gt;
&lt;th&gt;Partial&lt;/th&gt;
&lt;th&gt;Unsupported&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;relay-dsh-plugin-codex&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;76&lt;/td&gt;
&lt;td&gt;59&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;relay-dsh-plugin-claude&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;86&lt;/td&gt;
&lt;td&gt;78&lt;/td&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The cases, run evidence, and support matrices remain in the repositories: &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-codex/tree/main/validation/migration-compatibility" rel="noopener noreferrer"&gt;Codex validation&lt;/a&gt; and &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-claude/tree/main/validation/migration-compatibility" rel="noopener noreferrer"&gt;Claude validation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This table is the &lt;strong&gt;August 29 problem-discovery snapshot&lt;/strong&gt;, not the current pass rate. Codex &lt;code&gt;0.1.3&lt;/code&gt; and Claude &lt;code&gt;0.1.4&lt;/code&gt;, released the following day, fixed several of those failures. We will publish new counts after the complete 162-case suite has run again.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the Failures Made Us Reconsider
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Migration Is More Than Connecting an Interface
&lt;/h3&gt;

&lt;p&gt;One test produced a result that was easy to misread. DSH stored and displayed the user's image correctly, but the actual Codex rollout contained no image input. The interface looked healthy while the model received incomplete information.&lt;/p&gt;

&lt;p&gt;Claude exposed a related continuity gap. The plugin could create a new Session, but it did not yet have a reliable path for importing an existing native Session. Moving into DSH still meant starting over.&lt;/p&gt;

&lt;p&gt;Those failures led us to repair Codex image transport and improve existing-session selection and import in both plugins. The point is not to add two names to a mode menu. It is to let users carry existing work forward.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Control Must Reflect the Real State
&lt;/h3&gt;

&lt;p&gt;In another case, DSH reported a Codex task as interrupted, but a child process still wrote its delayed file several seconds later. That is worse than having no Stop button because the interface gives false certainty.&lt;/p&gt;

&lt;p&gt;We changed targeted process termination and long-command output handling. The rule is straightforward: running work should expose progress, and work reported as stopped must actually stop. If cleanup cannot be confirmed, the plugin should report a failure instead of displaying a successful cancellation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Invisible State Needs Testing Too
&lt;/h3&gt;

&lt;p&gt;A secret missing from the chat transcript can still be present on disk. Validation found persistence paths in Codex shell snapshots and Claude tool results.&lt;/p&gt;

&lt;p&gt;Codex &lt;code&gt;0.1.3&lt;/code&gt; disables persistent shell snapshots by default. Claude &lt;code&gt;0.1.4&lt;/code&gt; redacts sensitive environment values before tool results enter history. These changes do not replace least-privilege configuration or prove that every third-party tool is safe. They close the paths we could reproduce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validation Is Part of Development, Not a Release Ceremony
&lt;/h2&gt;

&lt;p&gt;The August 29 results did not end as a report. The two releases published the next day addressed failures in image transport, process interruption, long-command output, sensitive-value persistence, existing-session import, and tool routing.&lt;/p&gt;

&lt;p&gt;This is the development loop we want to keep:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use the plugins on real projects.&lt;/li&gt;
&lt;li&gt;Reduce a problem to a repeatable case.&lt;/li&gt;
&lt;li&gt;Repair the boundary between DSH and the native backend.&lt;/li&gt;
&lt;li&gt;Run the case again and retain what remains unresolved.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That takes longer than writing a feature list, but it matches what we are trying to build. &lt;code&gt;relay-dsh-plugin-codex&lt;/code&gt; and &lt;code&gt;relay-dsh-plugin-claude&lt;/code&gt; are not proofs that two backends can be wired into DSH. We want them to carry continuous project work and to keep an accurate account of what they do and do not support after upgrades.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Boundary Is Still Visible
&lt;/h2&gt;

&lt;p&gt;The plugins cover the main conversation, coding, configuration, extension, and session-continuation paths. They are not complete replacements for the native Codex and Claude Code products.&lt;/p&gt;

&lt;p&gt;Current boundaries include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;DSH does not yet provide a general document and file attachment path.&lt;/li&gt;
&lt;li&gt;An imported Codex Thread or Claude Session should not have two active writers.&lt;/li&gt;
&lt;li&gt;An existing Codex Thread does not automatically refresh DSH tools installed later.&lt;/li&gt;
&lt;li&gt;Claude's CLI fallback remains a conservative text path and does not inherit all Agent SDK capabilities.&lt;/li&gt;
&lt;li&gt;The complete post-release 162-case regression has not yet produced a new public matrix.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These limits stay in the documentation. Users should decide whether to migrate a task based on the capabilities it needs, not on a successful video alone.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install and Follow the Work
&lt;/h2&gt;

&lt;p&gt;Stop the running DSH Web process, then install either or both plugins:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dsh plugin &lt;span class="nt"&gt;--profile&lt;/span&gt; web add relay-dsh-plugin-codex@0.1.3
dsh plugin &lt;span class="nt"&gt;--profile&lt;/span&gt; web add relay-dsh-plugin-claude@0.1.4
dsh web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Codex plugin: &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-codex" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/relay-dsh-plugin-codex" rel="noopener noreferrer"&gt;npm&lt;/a&gt; · &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-codex/releases/tag/v0.1.3" rel="noopener noreferrer"&gt;v0.1.3&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Claude plugin: &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-claude" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://www.npmjs.com/package/relay-dsh-plugin-claude" rel="noopener noreferrer"&gt;npm&lt;/a&gt; · &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-claude/releases/tag/v0.1.4" rel="noopener noreferrer"&gt;v0.1.4&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Relay: &lt;a href="https://github.com/yangbobo2021/Relay" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; · &lt;a href="https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/dsh-plugins.md" rel="noopener noreferrer"&gt;plugin guide&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;DeepSeek Harness: &lt;a href="https://github.com/deepseek-ai/deepseek-harness" rel="noopener noreferrer"&gt;official repository&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We want to keep using these plugins on real projects months from now, not merely record a successful launch-day video. The 162 tests are not proof that the work is finished. They move it from “this seems to work” to “we know where it works and where we still have work to do.”&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>testing</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I Built a DeepSeek Harness Plugin That Installs Other Plugins from Chat</title>
      <dc:creator>Bobo Yang</dc:creator>
      <pubDate>Wed, 26 Aug 2026 15:14:36 +0000</pubDate>
      <link>https://dev.to/yangbobo2021/i-built-a-deepseek-harness-plugin-that-installs-other-plugins-from-chat-pk3</link>
      <guid>https://dev.to/yangbobo2021/i-built-a-deepseek-harness-plugin-that-installs-other-plugins-from-chat-pk3</guid>
      <description>&lt;p&gt;DeepSeek Harness supports plugins, but installing one usually means finding the&lt;br&gt;
right package name, running a command, checking the profile, and deciding&lt;br&gt;
whether DSH needs a restart.&lt;/p&gt;

&lt;p&gt;I built a standalone plugin called &lt;code&gt;relay-dsh-plugin-manager&lt;/code&gt;. Install it once,&lt;br&gt;
and you can search for and manage other DSH plugins directly from a&lt;br&gt;
conversation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F62tmclgcrqm6owdp6yr0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F62tmclgcrqm6owdp6yr0.gif" alt="Plugin Manager searching for, confirming, and installing the Codex plugin in DSH" width="720" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;19-second demo: search for the Codex plugin, inspect the installation plan, confirm it separately, and finish the installation. &lt;a href="https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/media/dsh-plugin-manager-codex-install-demo.mp4?raw=1" rel="noopener noreferrer"&gt;Watch the full 38-second MP4 at normal speed&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;You can write requests such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Find a workspace file browser plugin
Install relay-dsh-plugin-codex
List my installed plugins and their status
Disable example-dsh-plugin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plugin Manager can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;search npm and GitHub from a description of the capability you need;&lt;/li&gt;
&lt;li&gt;show a plugin's source, version, and basic information;&lt;/li&gt;
&lt;li&gt;install, update, enable, disable, or remove a plugin;&lt;/li&gt;
&lt;li&gt;show a plan first and wait for a separate confirmation before changing DSH.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Search and inspection are read-only. A vague request cannot immediately start&lt;br&gt;
an installation.&lt;/p&gt;
&lt;h2&gt;
  
  
  How it differs from a typical plugin marketplace
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Typical plugin marketplace&lt;/th&gt;
&lt;th&gt;DSH Plugin Manager&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Browse categories and lists&lt;/td&gt;
&lt;td&gt;Describe the capability you need&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Click an install button&lt;/td&gt;
&lt;td&gt;Ask from the current conversation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Search mainly by name&lt;/td&gt;
&lt;td&gt;Search with a natural-language requirement&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start after the click&lt;/td&gt;
&lt;td&gt;Review a plan, then confirm separately&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is not meant to replace a visual marketplace. A traditional marketplace is&lt;br&gt;
better for browsing. Plugin Manager is useful when you are already working in&lt;br&gt;
DSH and want to find or install something without leaving the conversation.&lt;/p&gt;
&lt;h2&gt;
  
  
  Install it
&lt;/h2&gt;

&lt;p&gt;The current release is a preview. Stop DSH Web, then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dsh plugin &lt;span class="nt"&gt;--profile&lt;/span&gt; web add relay-dsh-plugin-manager@next
dsh web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The manager itself still needs this one command. After that, other plugins can&lt;br&gt;
be managed from Chat. KeySync's one-click DSH setup installs Plugin Manager&lt;br&gt;
automatically.&lt;/p&gt;

&lt;p&gt;The current release manages the running &lt;code&gt;web&lt;/code&gt; profile. Some plugin changes may&lt;br&gt;
still require a DSH restart.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-manager" rel="noopener noreferrer"&gt;GitHub: relay-dsh-plugin-manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/relay-dsh-plugin-manager" rel="noopener noreferrer"&gt;npm: relay-dsh-plugin-manager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/dsh-plugins.md" rel="noopener noreferrer"&gt;Relay DSH plugin catalog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/deepseek-ai/deepseek-harness" rel="noopener noreferrer"&gt;Official DeepSeek Harness repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The plugin is developed in Relay but installs independently on official DSH. It&lt;br&gt;
does not require a Relay fork.&lt;/p&gt;

</description>
      <category>tools</category>
    </item>
    <item>
      <title>Leave the Work PC Running: One Remote Workbench for DSH, Codex, and Claude</title>
      <dc:creator>Bobo Yang</dc:creator>
      <pubDate>Tue, 25 Aug 2026 20:13:17 +0000</pubDate>
      <link>https://dev.to/yangbobo2021/leave-the-work-pc-running-one-remote-workbench-for-dsh-codex-and-claude-i3b</link>
      <guid>https://dev.to/yangbobo2021/leave-the-work-pc-running-one-remote-workbench-for-dsh-codex-and-claude-i3b</guid>
      <description>&lt;p&gt;In an earlier KeySync demo, we filmed an intentionally ridiculous opening: someone cycling home while a laptop was still running an agent in the bike basket. Please do not copy that. The problem behind the shot is real, though: what happens to an active task after you leave your desk?&lt;/p&gt;

&lt;p&gt;I do not want a fresh chat box on my phone. I want the same project, the same session, and a place to continue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6s5nbrkbvf6983ll4v4s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6s5nbrkbvf6983ll4v4s.png" alt="The same DSH task recorded on Mac, Windows, and a phone" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A composite made from the real three-device recording: the task runs on the Mac, is checked from a phone, and is continued from Windows. This earlier test used a native DSH conversation. Codex and Claude Code use the same DSH entry point described below, but keep separate sessions.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why remote DSH alone was not enough
&lt;/h2&gt;

&lt;p&gt;I do not use one agent for every job.&lt;/p&gt;

&lt;p&gt;My current habit is simple. I start ordinary questions in native DSH. I use Codex when a task needs sustained code reading, shell commands, and file changes. I often use Claude Code for a second view on a document, design, or review. That is not a model ranking. It is a practical choice based on the task, price, and result I need.&lt;/p&gt;

&lt;p&gt;The awkward part is everything around the answer. Conversations end up scattered across separate apps. Once I leave the work computer, each tool also needs its own way back in.&lt;/p&gt;

&lt;p&gt;The setup I now use has three parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;KeySync&lt;/strong&gt; installs and runs official DeepSeek Harness (DSH) on the work computer, then provides a remote entry to that computer's DSH Web UI.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Codex and Claude plugins&lt;/strong&gt; add two optional conversation backends to DSH.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;Workbench, Files, and Terminal plugins&lt;/strong&gt; keep the project files and shell next to the conversation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;KeySync does not bundle the Relay plugins. It installs DSH first; the plugins are added separately through DSH's own plugin system.&lt;/p&gt;

&lt;h2&gt;
  
  
  First, install official DSH
&lt;/h2&gt;

&lt;p&gt;DeepSeek Harness has its own one-click install entry under KeySync's Devices and Apps page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fka657dlsdzjsyoc0bul6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fka657dlsdzjsyoc0bul6.jpg" alt="The DeepSeek Harness install action in KeySync" width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Real KeySync screen on macOS, ready to install DeepSeek Harness. This is the official DSH package, not a Relay-maintained fork.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After DSH is running, install the conversation plugins you need. Restart DSH, open New Session, and the mode menu keeps Standard mode while adding Codex and Claude Code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1fu7h70ofrqstl1m02eg.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F1fu7h70ofrqstl1m02eg.jpg" alt="Standard mode, Codex, and Claude Code in official DSH" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Real mode menu from official DSH &lt;code&gt;0.1.1-rc.2&lt;/code&gt; with both conversation plugins installed. Installing only one plugin adds only that backend.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Three agents together, without mixing their context
&lt;/h2&gt;

&lt;p&gt;For the recording, I created three sessions under one workspace. Codex checked a code boundary. Claude Code reviewed a remote-handoff document. Native DSH analyzed test results.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwk8fwst9fqy9aulowm1z.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fwk8fwst9fqy9aulowm1z.jpg" alt="A real Codex App Server conversation inside DSH" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Codex session recording: its tool call, reasoning, and answer stay visible in this DSH session.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhq84gbeqh67j5nc2g1uu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhq84gbeqh67j5nc2g1uu.jpg" alt="A real Claude Agent SDK conversation inside DSH" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Claude Code session recording: it reads a document and returns two review findings in its own session.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The three sessions can sit next to each other under the same project, but they do not automatically share context. To continue one, open that original session. What is unified is the project entry and session management, not the agents' memory.&lt;/p&gt;

&lt;h2&gt;
  
  
  The project is next to the conversation
&lt;/h2&gt;

&lt;p&gt;Collecting chats is only half the job. When an agent mentions a file, I want to inspect it immediately. When I need to verify a command, I do not want to hunt for another terminal window.&lt;/p&gt;

&lt;p&gt;Files shows the current workspace tree and text preview on the right. Terminal opens a real shell at the bottom. Workbench is only the shared panel host; it does not read files or start commands itself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl0znkngeh5y78mvsvzqn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fl0znkngeh5y78mvsvzqn.png" alt="The Files panel previewing a real workspace file" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Official DSH running the Files plugin and previewing the Relay workspace's &lt;code&gt;README.md&lt;/code&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo6v41bw43gh7g9gz2diz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fo6v41bw43gh7g9gz2diz.png" alt="The Terminal panel running a real command" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Official DSH running &lt;code&gt;echo&lt;/code&gt; in the current workspace. The screenshot keeps the real environment's zsh history permission warning instead of replacing the output with a mock.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Terminal is provider-neutral and needs another plugin to supply the actual shell. In this combination, the Codex plugin provides that shell backend. Files does not depend on Codex or Claude.&lt;/p&gt;

&lt;h2&gt;
  
  
  Change devices, keep the original session
&lt;/h2&gt;

&lt;p&gt;After leaving the work computer, I can open its DSH instance from another KeySync desktop client or from the KeySync web page on a phone, tablet, or computer.&lt;/p&gt;

&lt;p&gt;The important step is to open the existing session, not create a new one. Reopen the Codex session and a follow-up can depend on the earlier code review. The same rule applies to Claude Code and native DSH sessions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6yfymwsbsbda79786qm7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6yfymwsbsbda79786qm7.png" alt="Continuing the original Codex session from the remote web entry" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Real remote recording: the browser reopens the original Codex session with the same workspace and session list. The outer frame and heading were added only to identify the recording context.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Three boundaries matter here:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The project, shell, and agents still run on the work computer. They are not moved to the phone or to a cloud runtime.&lt;/li&gt;
&lt;li&gt;The work computer must remain online and awake enough to keep the programs running. KeySync and DSH must also stay active.&lt;/li&gt;
&lt;li&gt;This opens the designated DSH Web UI; it is not general remote control of the computer. Use it only where the device owner and organization permit it.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;The current public validation baseline is official DSH &lt;code&gt;0.1.1-rc.2&lt;/code&gt;. This command installs both conversation backends, the file panel, and the terminal panel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx @deepseek-ai/dsh@0.1.1-rc.2 plugin &lt;span class="nt"&gt;--profile&lt;/span&gt; web add &lt;span class="se"&gt;\&lt;/span&gt;
  relay-dsh-plugin-codex@next &lt;span class="se"&gt;\&lt;/span&gt;
  relay-dsh-plugin-claude@next &lt;span class="se"&gt;\&lt;/span&gt;
  relay-dsh-plugin-workbench@latest &lt;span class="se"&gt;\&lt;/span&gt;
  relay-dsh-plugin-files@latest &lt;span class="se"&gt;\&lt;/span&gt;
  relay-dsh-plugin-terminal@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Codex and Claude Code can each be installed on their own. They are standalone npm packages, do not depend on Relay Events, and do not require a Relay checkout. Workbench is needed only by panel plugins such as Files and Terminal.&lt;/p&gt;

&lt;p&gt;Restart DSH after installation. Codex and Claude Code still require their normal account authentication on the work computer.&lt;/p&gt;

&lt;p&gt;As of August 26, 2026, the Codex &lt;code&gt;next&lt;/code&gt; tag points to &lt;code&gt;0.1.1-rc.4&lt;/code&gt;, Claude &lt;code&gt;next&lt;/code&gt; points to &lt;code&gt;0.1.1-rc.2&lt;/code&gt;, and the &lt;code&gt;latest&lt;/code&gt; tag for Workbench, Files, and Terminal points to &lt;code&gt;0.1.0&lt;/code&gt;. Check the npm pages before installation because these tags will move.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this is, and what it is not
&lt;/h2&gt;

&lt;p&gt;This setup already handles four ordinary problems: I no longer search several interfaces for a project's conversations; DSH, Codex, and Claude sessions can be grouped by project; files and a shell remain beside the conversation; and I can return to the original session after leaving my desk.&lt;/p&gt;

&lt;p&gt;It is not automatic multi-agent orchestration. I still decide which agent gets each task. Clear project, session, and backend boundaries give future handoffs a sensible foundation, but I do not want to market unfinished coordination as a current feature.&lt;/p&gt;

&lt;p&gt;The useful change is much less grand: I can still choose a tool for cost, quality, and task fit without changing the entire place where I work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sublang.ai/keysync/download/" rel="noopener noreferrer"&gt;Download KeySync&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/deepseek-ai/deepseek-harness" rel="noopener noreferrer"&gt;Official DeepSeek Harness repository&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/dsh-plugins.md" rel="noopener noreferrer"&gt;Relay and the complete DSH plugin list&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-codex" rel="noopener noreferrer"&gt;Codex plugin&lt;/a&gt; · &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-claude" rel="noopener noreferrer"&gt;Claude Code plugin&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-workbench" rel="noopener noreferrer"&gt;Workbench&lt;/a&gt; · &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-files" rel="noopener noreferrer"&gt;Files&lt;/a&gt; · &lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-terminal" rel="noopener noreferrer"&gt;Terminal&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bilibili.com/video/BV1pthK6TEa9/" rel="noopener noreferrer"&gt;Chinese video: installing DSH with KeySync and handing off across three devices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.bilibili.com/video/BV1t2h36bE9H/" rel="noopener noreferrer"&gt;Chinese video: adding Codex and Claude Code to DSH&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://merico.feishu.cn/docx/HiSKd8V9qopI19x55aSchW8onHe" rel="noopener noreferrer"&gt;Chinese beginner tutorial: from installation to remote continuation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>deepseek</category>
      <category>ai</category>
      <category>opensource</category>
      <category>codex</category>
    </item>
    <item>
      <title>Don't Start Over: Import Existing Codex Conversations into DeepSeek Harness</title>
      <dc:creator>Bobo Yang</dc:creator>
      <pubDate>Tue, 25 Aug 2026 09:53:22 +0000</pubDate>
      <link>https://dev.to/yangbobo2021/dont-start-over-import-existing-codex-conversations-into-deepseek-harness-55pf</link>
      <guid>https://dev.to/yangbobo2021/dont-start-over-import-existing-codex-conversations-into-deepseek-harness-55pf</guid>
      <description>&lt;p&gt;I want to use DSH as the front door to a project. I do not want a new interface&lt;br&gt;
to make me repeat every requirement, test idea, and implementation decision that&lt;br&gt;
is already in Codex.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;relay-dsh-plugin-codex@0.1.1-rc.4&lt;/code&gt; adds Workspace-level import. It finds the&lt;br&gt;
Codex Threads that belong to a project and turns them into normal DSH Sessions.&lt;br&gt;
Open one to read its history, then continue the same Thread.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fggp0xf6ckhr9akory8un.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fggp0xf6ckhr9akory8un.png" alt="Continuing the same Codex Thread in DSH after importing its history" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is not a mockup. The screenshot comes from official DSH &lt;code&gt;0.1.1-rc.2&lt;/code&gt;, the&lt;br&gt;
published npm plugin, and real Codex App Server conversations.&lt;/p&gt;
&lt;h2&gt;
  
  
  Install the plugin
&lt;/h2&gt;

&lt;p&gt;Stop the running DSH Web process, then install the npm prerelease:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dsh plugin &lt;span class="nt"&gt;--profile&lt;/span&gt; web add relay-dsh-plugin-codex@next
dsh web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;next&lt;/code&gt; currently points to &lt;code&gt;0.1.1-rc.4&lt;/code&gt;. Replace &lt;code&gt;@next&lt;/code&gt; with&lt;br&gt;
&lt;code&gt;@0.1.1-rc.4&lt;/code&gt; when you need the exact version tested in this article.&lt;/p&gt;

&lt;p&gt;You can also install the current development build from GitHub:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dsh plugin &lt;span class="nt"&gt;--profile&lt;/span&gt; web add &lt;span class="se"&gt;\&lt;/span&gt;
  github:yangbobo2021/relay-dsh-plugin-codex#main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The plugin bundles a pinned official Codex App Server runtime for macOS,&lt;br&gt;
Windows, and Linux, so it does not normally need a global &lt;code&gt;codex&lt;/code&gt; command.&lt;br&gt;
Codex authentication is still required. Start DSH as the same operating-system&lt;br&gt;
user whose Codex profile contains the conversations you want to import.&lt;/p&gt;

&lt;h2&gt;
  
  
  Import one Workspace at a time
&lt;/h2&gt;

&lt;p&gt;Add or open the project Workspace in DSH, then select &lt;strong&gt;Import Codex Sessions&lt;/strong&gt;&lt;br&gt;
near the bottom of the sidebar. The plugin scans Codex conversations by project&lt;br&gt;
path and shows the totals before it changes anything.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fic86hrlbvwkvpqifzlf8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fic86hrlbvwkvpqifzlf8.png" alt="Three Codex conversations found for the Release Notes CLI Workspace" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The current release imports the entire Workspace; it does not offer per-Thread&lt;br&gt;
checkboxes. Select &lt;strong&gt;Import all&lt;/strong&gt; to continue. This run found three conversations,&lt;br&gt;
imported all three, and reported zero failures.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3jbuvbwv22ig6qgdkzdt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F3jbuvbwv22ig6qgdkzdt.png" alt="All three Codex conversations imported successfully" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep the useful titles and order
&lt;/h2&gt;

&lt;p&gt;Imported Sessions show their Codex titles immediately and stay ordered by the&lt;br&gt;
source activity time. You do not have to open every row to work out what it was.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6cfoigcuj3sihcrjypao.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6cfoigcuj3sihcrjypao.png" alt="Imported Codex Sessions retaining their titles and activity order" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The operation is idempotent. Running it again in this test produced &lt;code&gt;Found 3&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;Existing 3&lt;/code&gt;, and &lt;code&gt;Ready 0&lt;/code&gt;, with no duplicate Sessions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open the history and keep going
&lt;/h2&gt;

&lt;p&gt;When an imported Session opens, the plugin performs one &lt;code&gt;thread/read&lt;/code&gt; and adds&lt;br&gt;
missing terminal user and assistant messages to DSH's presentation history.&lt;br&gt;
The original answer, tool activity, model, and reasoning effort remain visible.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn9hzofj81kjkrrrnxeir.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fn9hzofj81kjkrrrnxeir.png" alt="Real Codex history and tool activity restored inside DSH" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I then asked which step from the earlier four-step plan should come first. Codex&lt;br&gt;
answered from that existing context instead of starting a blank conversation.&lt;br&gt;
After switching to another Session and back, both turns were still present.&lt;/p&gt;

&lt;h2&gt;
  
  
  What moves, and what does not
&lt;/h2&gt;

&lt;p&gt;DSH stores normal presentation history plus a durable one-to-one binding between&lt;br&gt;
the DSH Session and the Codex Thread. Codex App Server still owns model context,&lt;br&gt;
tool state, and compaction. The plugin does not copy private Codex runtime records&lt;br&gt;
into a second database.&lt;/p&gt;

&lt;p&gt;Three limits are worth knowing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Import currently works on a whole Workspace, not selected Threads.&lt;/li&gt;
&lt;li&gt;A Session synchronizes once when it opens. There is no background polling or manual refresh action.&lt;/li&gt;
&lt;li&gt;One Codex Thread cannot have two App Server writers. Fully quit the Codex client or process that owns the Thread before continuing it in DSH.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The practical result is simple: adopting DSH does not mean abandoning work that&lt;br&gt;
already happened in Codex. Native DSH, Codex, and Claude conversations can live&lt;br&gt;
under one project, while each task still uses the backend that makes sense for&lt;br&gt;
its quality, cost, and tool needs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-codex" rel="noopener noreferrer"&gt;Codex plugin on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/relay-dsh-plugin-codex" rel="noopener noreferrer"&gt;npm package: relay-dsh-plugin-codex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/yangbobo2021/Relay" rel="noopener noreferrer"&gt;Relay: multi-backend conversations and event-driven agent workflows&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/deepseek-ai/deepseek-harness" rel="noopener noreferrer"&gt;Official DeepSeek Harness repository&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>productivity</category>
      <category>ai</category>
      <category>opensource</category>
      <category>programming</category>
    </item>
    <item>
      <title>One Project, Three AI Conversations: Why I Put DSH, Codex, and Claude Together</title>
      <dc:creator>Bobo Yang</dc:creator>
      <pubDate>Mon, 24 Aug 2026 23:55:58 +0000</pubDate>
      <link>https://dev.to/yangbobo2021/one-project-three-ai-conversations-why-i-put-dsh-codex-and-claude-together-5eek</link>
      <guid>https://dev.to/yangbobo2021/one-project-three-ai-conversations-why-i-put-dsh-codex-and-claude-together-5eek</guid>
      <description>&lt;p&gt;I did not bring Codex and Claude Code into DeepSeek Harness because either tool&lt;br&gt;
was disappointing. I did it because each is useful, and I no longer wanted my&lt;br&gt;
day to be organized around their separate applications.&lt;/p&gt;

&lt;p&gt;A normal task can start as a requirements discussion in DSH, move to Codex when&lt;br&gt;
the change becomes implementation-heavy, then end in Claude Code for an&lt;br&gt;
independent review. Files and a terminal sit in two more windows. A few hours&lt;br&gt;
later, the hard part is often not the code. It is remembering which window owns&lt;br&gt;
the conclusion that matters.&lt;/p&gt;

&lt;p&gt;I wanted to invert that arrangement: keep the project in place and choose the&lt;br&gt;
tool for the task.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk7rc06an9oeppheomz64.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fk7rc06an9oeppheomz64.gif" alt="Codex, Claude Code, Files, and Terminal running in DSH" width="720" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  DSH is the front door, not the only answer
&lt;/h2&gt;

&lt;p&gt;Native DSH conversations remain useful. Routine questions, short jobs, and work&lt;br&gt;
already handled well by the installed DSH stack do not need another agent. When&lt;br&gt;
a task reaches a capability limit, however, leaving the project workspace and&lt;br&gt;
rebuilding context in another application is a poor handoff.&lt;/p&gt;

&lt;p&gt;With the plugins installed, a new DSH session can use the native mode, Codex, or&lt;br&gt;
Claude Code. DSH still owns the session, workspace, and interface. A Codex&lt;br&gt;
session is driven by a Codex App Server Thread; a Claude session is driven by&lt;br&gt;
the Claude Agent SDK. These are not generic API replies wearing different&lt;br&gt;
labels. Each backend keeps its own execution model and conversation continuity.&lt;/p&gt;

&lt;p&gt;The useful change is not merely two extra menu entries. Sessions still belong&lt;br&gt;
to a project. Requirements, implementation, review, and verification for one&lt;br&gt;
repository can live under one Workspace group instead of being recalled by&lt;br&gt;
application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cost and quality are not a binary choice
&lt;/h2&gt;

&lt;p&gt;"Which agent is strongest?" is rarely the question I need to answer during a&lt;br&gt;
working day. The practical question is which backend this task deserves.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A routine question that should take ten minutes can begin in native DSH.&lt;/li&gt;
&lt;li&gt;A change that requires repeated file edits, commands, and test repair can use
a Codex session.&lt;/li&gt;
&lt;li&gt;An independent review, a second design angle, or a difficult analysis can use
a Claude Code session.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not a permanent division of labor or a model leaderboard. Subscription&lt;br&gt;
terms, model versions, task shape, and team habits all affect cost and quality.&lt;br&gt;
One entry point preserves the choice: inexpensive work does not need the most&lt;br&gt;
expensive route, and important work does not have to accept a weaker result to&lt;br&gt;
save a small amount.&lt;/p&gt;

&lt;h2&gt;
  
  
  What works today
&lt;/h2&gt;

&lt;p&gt;The published plugins currently provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Codex and Claude Code choices in DSH's new-session mode menu;&lt;/li&gt;
&lt;li&gt;continued Codex Threads and Claude Sessions across their respective DSH turns;&lt;/li&gt;
&lt;li&gt;DSH input, history, approvals, and tool presentation;&lt;/li&gt;
&lt;li&gt;a Workbench host for the Files side view and Terminal bottom view;&lt;/li&gt;
&lt;li&gt;a project working directory attached to the session.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Codex and Claude plugins install independently and do not require Relay&lt;br&gt;
Events:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-codex" rel="noopener noreferrer"&gt;relay-dsh-plugin-codex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/yangbobo2021/relay-dsh-plugin-claude" rel="noopener noreferrer"&gt;relay-dsh-plugin-claude&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/yangbobo2021/Relay/blob/codex/relay-foundation/docs/dsh-plugins.md" rel="noopener noreferrer"&gt;All Relay DSH plugins&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What has not happened yet
&lt;/h2&gt;

&lt;p&gt;The user still decides which agent should take a task and creates the sessions&lt;br&gt;
separately. The system does not yet compress a DSH conversation and hand it to&lt;br&gt;
Codex automatically. It does not ask Claude to review a Codex implementation&lt;br&gt;
when the implementation finishes. A shared interface is not the same thing as&lt;br&gt;
multi-agent orchestration.&lt;/p&gt;

&lt;p&gt;What has changed is the boundary. Projects, user-facing sessions, and execution&lt;br&gt;
backends are no longer one inseparable choice. That is a prerequisite for later&lt;br&gt;
coordination: a task can belong to a project, an agent can be selected, and a&lt;br&gt;
future Relay event or handoff has a clear destination.&lt;/p&gt;

&lt;p&gt;I prefer to treat the current release as a useful project workbench, not a grand&lt;br&gt;
multi-agent diagram. Today it reduces application switching, organizes sessions,&lt;br&gt;
and lets cost and quality guide backend choice. Automated coordination can earn&lt;br&gt;
its place after a real end-to-end loop exists.&lt;/p&gt;

&lt;p&gt;The next article opens the Codex plugin: who starts App Server, how one DSH&lt;br&gt;
session binds to a Thread, and why the integration is not simply a shell call to&lt;br&gt;
&lt;code&gt;codex&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>claude</category>
      <category>openai</category>
    </item>
  </channel>
</rss>
