<?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: SimonLi</title>
    <description>The latest articles on DEV Community by SimonLi (@simonli).</description>
    <link>https://dev.to/simonli</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%2F4133116%2F7e4c9c65-f04b-4b39-9242-168938aef2a1.jpg</url>
      <title>DEV Community: SimonLi</title>
      <link>https://dev.to/simonli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/simonli"/>
    <language>en</language>
    <item>
      <title>Learning Vim Swiftly: A Quick Start for Servers</title>
      <dc:creator>SimonLi</dc:creator>
      <pubDate>Tue, 22 Sep 2026 12:55:22 +0000</pubDate>
      <link>https://dev.to/simonli/learning-vim-swiftly-a-quick-start-for-servers-2584</link>
      <guid>https://dev.to/simonli/learning-vim-swiftly-a-quick-start-for-servers-2584</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;When you SSH into a remote server, there is often no GUI editor available, but Vim is almost always installed. This guide covers the minimum you need to edit files confidently on a server.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  1. Modes: The Core Idea
&lt;/h2&gt;

&lt;p&gt;Vim is a &lt;em&gt;modal&lt;/em&gt; editor. When you open a file, you start in &lt;strong&gt;Normal mode&lt;/strong&gt;, where keys are commands rather than text. This is the main reason beginners feel lost.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Mode&lt;/th&gt;
&lt;th&gt;How to enter&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Normal&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Esc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Move, delete, copy, paste&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insert&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;i&lt;/code&gt; (and others, see §4)&lt;/td&gt;
&lt;td&gt;Type text&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Command-line&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;:&lt;/code&gt; in Normal mode&lt;/td&gt;
&lt;td&gt;Save, quit, search &amp;amp; replace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Visual&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;v&lt;/code&gt; / &lt;code&gt;V&lt;/code&gt; / &lt;code&gt;Ctrl+v&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Select text&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; If you ever get lost, press &lt;code&gt;Esc&lt;/code&gt; a few times to return to Normal mode.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Survival Kit
&lt;/h2&gt;

&lt;p&gt;Suppose you want to edit a file named &lt;code&gt;train.py&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vim train.py    open the file (creates it if it doesn't exist)
i               enter Insert mode and start typing
Esc             back to Normal mode
:w              save
:q              quit
:wq  or  :x     save and quit
:q!             quit WITHOUT saving (use it when you mess up)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With just these, you can already edit config files and scripts on a server.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Moving the Cursor (Normal Mode)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;h j k l          left / down / up / right (arrow keys also work)
w / b            next word / previous word
0 / $            start / end of line
gg / G           start / end of file
:42  or  42G     jump to line 42
Ctrl+d / Ctrl+u  scroll down / up half a page
%                jump between matching brackets ( ) [ ] { }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  4. Entering Insert Mode
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;i   insert before the cursor
a   insert after the cursor
I   insert at the start of the line
A   insert at the end of the line (very common)
o   open a new line below
O   open a new line above
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  5. Editing
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;x        delete one character
dd       delete (cut) the whole line
3dd      delete 3 lines
dw       delete a word
D        delete to end of line
yy       copy (yank) the whole line
p / P    paste below / above
u        undo
Ctrl+r   redo
.        repeat the last change (extremely useful)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Grammar of Vim
&lt;/h3&gt;

&lt;p&gt;Vim commands compose: &lt;strong&gt;operator + motion&lt;/strong&gt;. &lt;code&gt;d&lt;/code&gt; means delete and &lt;code&gt;w&lt;/code&gt; means one word, so &lt;code&gt;dw&lt;/code&gt; deletes a word. Once you see this pattern, you no longer need to memorize every command.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Operator&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;d&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;delete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;y&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;yank (copy)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;c&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;change (delete, then enter Insert mode)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A few useful combinations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;y$       copy to end of line
d0       delete to start of line
dG       delete to end of file
ciw      change the word under the cursor
ci"      change everything inside the quotes
ci(      change everything inside the parentheses
dt)      delete up to (but not including) the next )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  6. Visual Mode
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;v        select by character
V        select by line
Ctrl+v   select a block (columns)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After selecting, press &lt;code&gt;d&lt;/code&gt; to delete, &lt;code&gt;y&lt;/code&gt; to copy, or &lt;code&gt;&amp;gt;&lt;/code&gt; / &lt;code&gt;&amp;lt;&lt;/code&gt; to indent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Comment out multiple lines:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Move to the first line, press &lt;code&gt;Ctrl+v&lt;/code&gt;, then press &lt;code&gt;j&lt;/code&gt; to extend the selection down.&lt;/li&gt;
&lt;li&gt;Press &lt;code&gt;I&lt;/code&gt; (capital i) and type &lt;code&gt;#&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Press &lt;code&gt;Esc&lt;/code&gt;. Every selected line now starts with &lt;code&gt;#&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  7. Search and Replace
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/lr                 search forward for "lr"
n / N               next / previous match
*                   search for the word under the cursor
:%s/old/new/g       replace every "old" with "new" in the file
:%s/old/new/gc      replace with confirmation for each match
:noh                clear search highlighting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  8. Server Tips
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Read-only viewing
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;view log.txt
&lt;span class="c"&gt;# or&lt;/span&gt;
vim &lt;span class="nt"&gt;-R&lt;/span&gt; log.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This prevents accidental edits. For large logs, press &lt;code&gt;G&lt;/code&gt; to jump straight to the end.&lt;/p&gt;

&lt;h3&gt;
  
  
  Multiple files
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:vsp other.py    split vertically (side by side)
:sp other.py     split horizontally
Ctrl+w w         switch between windows
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pasting code without broken indentation
&lt;/h3&gt;

&lt;p&gt;When you paste code into Vim through a terminal, auto-indent can stack up and ruin the formatting. Turn on paste mode first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:set paste      before pasting
:set nopaste    after pasting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Forgot &lt;code&gt;sudo&lt;/code&gt;?
&lt;/h3&gt;

&lt;p&gt;If you edited a system file and get a permission error when saving, you don't need to start over:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:w !sudo tee %
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common pitfalls
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Screen frozen?&lt;/strong&gt; You probably pressed &lt;code&gt;Ctrl+s&lt;/code&gt; out of habit, which pauses terminal output. Press &lt;code&gt;Ctrl+q&lt;/code&gt; to resume.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"Found a swap file" warning?&lt;/strong&gt; Vim creates a &lt;code&gt;.swp&lt;/code&gt; file while editing. This warning appears if Vim crashed, your SSH connection dropped, or the file is open elsewhere. Press &lt;code&gt;R&lt;/code&gt; to recover, or &lt;code&gt;D&lt;/code&gt; to delete the old swap file if you're sure it's stale.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Can't copy text to your local machine after &lt;code&gt;set mouse=a&lt;/code&gt;?&lt;/strong&gt; Hold &lt;code&gt;Shift&lt;/code&gt; while dragging to use the terminal's own selection instead.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  9. Configuration: &lt;code&gt;~/.vimrc&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;~/.vimrc&lt;/code&gt; is Vim's config file. Vim reads it at every startup, so settings you put here apply automatically. The default config on most servers is minimal, so start with these:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight viml"&gt;&lt;code&gt;&lt;span class="nb"&gt;syntax&lt;/span&gt; &lt;span class="k"&gt;on&lt;/span&gt;           " &lt;span class="nb"&gt;syntax&lt;/span&gt; highlighting
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="k"&gt;number&lt;/span&gt;          " show &lt;span class="nb"&gt;line&lt;/span&gt; numbers
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;tabstop&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;       " &lt;span class="k"&gt;a&lt;/span&gt; Tab displays &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="m"&gt;4&lt;/span&gt; spaces wide
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;shiftwidth&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="m"&gt;4&lt;/span&gt;    " &lt;span class="nb"&gt;indent&lt;/span&gt; by &lt;span class="m"&gt;4&lt;/span&gt; spaces
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;expandtab&lt;/span&gt;       " &lt;span class="nb"&gt;insert&lt;/span&gt; spaces instead of Tab &lt;span class="p"&gt;(&lt;/span&gt;essential &lt;span class="k"&gt;for&lt;/span&gt; Python&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;autoindent&lt;/span&gt;      " keep indentation &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;lines&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;hlsearch&lt;/span&gt;        " &lt;span class="nb"&gt;highlight&lt;/span&gt; &lt;span class="k"&gt;all&lt;/span&gt; &lt;span class="nb"&gt;search&lt;/span&gt; matches
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;incsearch&lt;/span&gt;       " &lt;span class="nb"&gt;search&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; you &lt;span class="nb"&gt;type&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="nb"&gt;mouse&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="k"&gt;a&lt;/span&gt;         " enable the &lt;span class="nb"&gt;mouse&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Text after &lt;code&gt;"&lt;/code&gt; is a comment and is ignored by Vim.&lt;/p&gt;

&lt;p&gt;To create the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vim ~/.vimrc
&lt;span class="c"&gt;# press i, paste the config, press Esc, then type :wq&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  10. What's Next
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Run &lt;code&gt;vimtutor&lt;/code&gt;&lt;/strong&gt; on your server. It's an interactive tutorial bundled with Vim that takes about 30 minutes, and it's more effective than any article, including this one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;In the first week&lt;/strong&gt;, stick to sections 2 through 5 and try not to use the arrow keys or mouse.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;After that&lt;/strong&gt;, deliberately practice composed commands like &lt;code&gt;ciw&lt;/code&gt;, &lt;code&gt;dt)&lt;/code&gt;, and &lt;code&gt;.&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For heavy development work, consider VS Code with Remote-SSH, and keep Vim for quick edits and log inspection. The two work well together.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>everything about jev</title>
      <dc:creator>SimonLi</dc:creator>
      <pubDate>Mon, 21 Sep 2026 11:08:38 +0000</pubDate>
      <link>https://dev.to/simonli/everything-about-jev-5b0i</link>
      <guid>https://dev.to/simonli/everything-about-jev-5b0i</guid>
      <description>&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/qingshungLI" rel="noopener noreferrer"&gt;
        qingshungLI
      &lt;/a&gt; / &lt;a href="https://github.com/qingshungLI/everything-about-jev" rel="noopener noreferrer"&gt;
        everything-about-jev
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      tell you everything about jev,TypeSafe AI's System One model for typed decisions.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div&gt;
&lt;a rel="noopener noreferrer" href="https://github.com/qingshungLI/everything-about-jev/assets/hero.svg"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2FqingshungLI%2Feverything-about-jev%2FHEAD%2Fassets%2Fhero.svg" alt="Everything about Jev" width="100%"&gt;&lt;/a&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Everything about Jev&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href="https://github.com/qingshungLI/everything-about-jev/actions/workflows/checks.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/qingshungLI/everything-about-jev/actions/workflows/checks.yml/badge.svg" alt="Checks"&gt;&lt;/a&gt;
&lt;a href="https://github.com/qingshungLI/everything-about-jev/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/26ec12acd3d83e355318ac053fb579b635e7437ef9acc0684d400f2b8d2c7fcd/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f71696e677368756e674c492f65766572797468696e672d61626f75742d6a65763f636f6c6f723d313462386136" alt="License"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/qingshungLI/everything-about-jev/README.md" rel="noopener noreferrer"&gt;简体中文&lt;/a&gt; · &lt;a href="https://github.com/qingshungLI/everything-about-jev/README.en.md" rel="noopener noreferrer"&gt;English&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;这里整理了 Jev 的使用方法、示例代码、社区项目和讨论。如果你刚听说这个模型，可以先读下面的介绍，再选一个 demo 跑起来。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/qingshungLI/everything-about-jev#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B" rel="noopener noreferrer"&gt;快速开始&lt;/a&gt; · &lt;a href="https://github.com/qingshungLI/everything-about-jev#%E7%A4%BA%E4%BE%8B" rel="noopener noreferrer"&gt;示例&lt;/a&gt; · &lt;a href="https://github.com/qingshungLI/everything-about-jev#%E7%A4%BE%E5%8C%BA%E8%AE%A8%E8%AE%BA" rel="noopener noreferrer"&gt;社区讨论&lt;/a&gt; · &lt;a href="https://github.com/qingshungLI/everything-about-jev/catalog/projects.md" rel="noopener noreferrer"&gt;项目目录&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Jev 是什么&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Jev 是 TypeSafe AI 的决策模型。你给它一段文本或业务状态，再定义问题和可选答案，它会返回选择、评分和概率。&lt;/p&gt;
&lt;p&gt;比如收到一条“我的订阅扣了两次钱”的消息，你可以让 Jev 判断该交给哪个团队、是否需要人工处理，以及紧急程度。它返回的字段可以直接用于程序里的条件分支。&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;类型&lt;/th&gt;
&lt;th&gt;用法&lt;/th&gt;
&lt;th&gt;返回值&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Choice&lt;/td&gt;
&lt;td&gt;从“账单、技术、其他”中选择&lt;/td&gt;
&lt;td&gt;选项、confidence、各选项概率&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Noul&lt;/td&gt;
&lt;td&gt;判断是否需要人工处理&lt;/td&gt;
&lt;td&gt;“是”的概率&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Score&lt;/td&gt;
&lt;td&gt;按给定量表评估紧急程度&lt;/td&gt;
&lt;td&gt;评分和概率分布，评分可能为小数&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;Jev 适合分类、路由、筛选和有限动作选择。需要写回复时，可以接生成模型；需要查最新信息时，由应用先检索，再把结果传给 Jev。&lt;code&gt;confidence&lt;/code&gt; 和获选项概率是不同字段，接入时要注意区分。&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/qingshungLI/everything-about-jev/docs/system-overview.md" rel="noopener noreferrer"&gt;系统说明&lt;/a&gt;介绍了这三类问题、模型边界，以及如何在应用里处理不确定的结果。&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;快速开始&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;需要 Python 3.10+。下面使用 &lt;a href="https://www.jevai.org/docs" rel="nofollow noopener noreferrer"&gt;jevai.org 社区 API&lt;/a&gt;；使用 TypeSafe 官方密钥的读者请看&lt;a href="https://github.com/qingshungLI/everything-about-jev/docs/official-sdk.md" rel="noopener noreferrer"&gt;官方 SDK 示例&lt;/a&gt;。&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;git clone https://github.com/qingshungLI/everything-about-jev.git
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; everything-about-jev
python -m pip install -r requirements.txt&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;在根目录创建 &lt;code&gt;.env&lt;/code&gt;：&lt;/p&gt;
&lt;div class="highlight highlight-source-dotenv notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-v"&gt;JEVAI_API_KEY&lt;/span&gt;&lt;span class="pl-k"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;你的社区服务密钥&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;运行：&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;python demos/python/quickstart.py&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;默认示例把“把页面变暗一点，晚上看太刺眼了”匹配到 &lt;code&gt;dark_mode&lt;/code&gt;。它只返回动作名称，不操作浏览器。密钥文件已加入 &lt;code&gt;.gitignore&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;也可以用 TypeScript（Node.js 20+）：&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm ci
npm run demo:community&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;遇到限流或密钥问题，参见&lt;a href="https://github.com/qingshungLI/everything-about-jev/docs/getting-started.md" rel="noopener noreferrer"&gt;接入说明&lt;/a&gt;。社区 API 和官方 API 使用各自的密钥，具体区别见&lt;a href="https://github.com/qingshungLI/everything-about-jev/docs/providers.md" rel="noopener noreferrer"&gt;供应方对照&lt;/a&gt;。&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;示例&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;示例&lt;/th&gt;
&lt;th&gt;内容&lt;/th&gt;
&lt;th&gt;Python 参数&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;命令面板&lt;/td&gt;
&lt;td&gt;根据一句话选择深色模式、导出或帮助&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--case palette&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;工单分类&lt;/td&gt;
&lt;td&gt;同时判断队列、人工需求和紧急度&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--case ticket&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;资料核对&lt;/td&gt;
&lt;td&gt;判断提供的资料是否支持一个说法&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--case research&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;模型路由&lt;/td&gt;
&lt;td&gt;从给定候选中选择适合任务的模型&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--case model-route&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;工具检查&lt;/td&gt;
&lt;td&gt;检查工具调用是否符合操作规则&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--case tool-guard&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;完成检查&lt;/td&gt;
&lt;td&gt;根据已完成工作和缺失项判断任务状态&lt;/td&gt;
&lt;td&gt;&lt;code&gt;--case completion&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;python demos/python/quickstart.py --case model-route&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;更多语言和演示入口：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/qingshungLI/everything-about-jev/demos/python/quickstart.py" rel="noopener noreferrer"&gt;Python&lt;/a&gt;、&lt;a href="https://github.com/qingshungLI/everything-about-jev/demos/typescript/community-demo.ts" rel="noopener noreferrer"&gt;TypeScript&lt;/a&gt;、&lt;a href="https://github.com/qingshungLI/everything-about-jev/demos/node/tool-guard.mjs" rel="noopener noreferrer"&gt;Node.js&lt;/a&gt;、&lt;a href="https://github.com/qingshungLI/everything-about-jev/demos/curl/tool-guard.sh" rel="noopener noreferrer"&gt;Bash / curl&lt;/a&gt;。&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/qingshungLI/everything-about-jev/demos/web/index.html" rel="noopener noreferrer"&gt;浏览器演示&lt;/a&gt;：离线模拟，适合讲解交互流程。&lt;/li&gt;
&lt;li&gt;…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/qingshungLI/everything-about-jev" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Recently, many people have been discussing Jev, a product launched by TypeSafe AI. Rather than writing articles or chatting with you, Jev makes decisions, classifications, and evaluations based on the information provided—for example, determining who a ticket should be assigned to or which tool should be called next.&lt;/p&gt;

&lt;p&gt;I’ve put together a bilingual Chinese–English repository covering Jev’s core principles, integration methods, community projects, and the debates surrounding it. It also includes runnable examples in Python, TypeScript, Node.js, and more, so you can try it out directly.&lt;/p&gt;

&lt;p&gt;If you want to understand what Jev can do and where it fits best, this is a good place to start.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>github</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to Fix `already has an active writer` in Codex CLI</title>
      <dc:creator>SimonLi</dc:creator>
      <pubDate>Mon, 21 Sep 2026 07:34:42 +0000</pubDate>
      <link>https://dev.to/simonli/how-to-fix-already-has-an-active-writer-in-codex-cli-3lm</link>
      <guid>https://dev.to/simonli/how-to-fix-already-has-an-active-writer-in-codex-cli-3lm</guid>
      <description>&lt;h1&gt;
  
  
  Fixing &lt;code&gt;already has an active writer&lt;/code&gt; When Resuming a Codex CLI Session
&lt;/h1&gt;

&lt;p&gt;When restoring a historical session in Codex CLI, you may see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;thread/resume failed during TUI bootstrap:
thread &amp;lt;THREAD_ID&amp;gt; already has an active writer (code -32600)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This guide provides a direct troubleshooting flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install &lt;code&gt;strace&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Identify the suspicious process associated with a specific JSONL session.&lt;/li&gt;
&lt;li&gt;If individual diagnosis is unnecessary, clean up all leftover &lt;code&gt;codex resume --all&lt;/code&gt; processes.&lt;/li&gt;
&lt;/ol&gt;

&lt;blockquote&gt;
&lt;p&gt;Important: Do not delete the session &lt;code&gt;.jsonl&lt;/code&gt; file as a first response. The error usually means another process still owns the thread writer, not that the session file itself is corrupted.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  1. Cause: a single-writer lock per thread
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;already has an active writer&lt;/code&gt; error is not necessarily caused directly by a disconnected SSH session or a closed terminal. The underlying issue is that Codex enforces a &lt;strong&gt;single-writer&lt;/strong&gt; constraint for each thread.&lt;/p&gt;

&lt;p&gt;Codex continuously appends events to a session rollout &lt;code&gt;.jsonl&lt;/code&gt; file. To prevent multiple processes from writing to the same thread at the same time—which could cause out-of-order events, duplicated entries, or inconsistent session history—Codex maintains writer ownership or a writer lock for each thread.&lt;/p&gt;

&lt;p&gt;A new &lt;code&gt;thread/resume&lt;/code&gt; request must obtain that writer lock before it can continue. Therefore, the error means:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The current resume request detected that writer ownership for this thread still belongs to another Codex instance or background writer task, so it refused to start a second writer.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  2. Install &lt;code&gt;strace&lt;/code&gt; on Linux
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;strace&lt;/code&gt; can help determine whether a process is accessing the target session file or making file-lock-related system calls.&lt;/p&gt;

&lt;p&gt;First, identify your Linux distribution:&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;cat&lt;/span&gt; /etc/os-release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install &lt;code&gt;strace&lt;/code&gt; based on the distribution:&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="c"&gt;# Debian / Ubuntu&lt;/span&gt;
apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; strace

&lt;span class="c"&gt;# Alpine&lt;/span&gt;
apk add &lt;span class="nt"&gt;--no-cache&lt;/span&gt; strace

&lt;span class="c"&gt;# CentOS / RHEL / Rocky Linux / AlmaLinux&lt;/span&gt;
dnf &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; strace

&lt;span class="c"&gt;# Older RHEL/CentOS systems&lt;/span&gt;
yum &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; strace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;strace &lt;span class="nt"&gt;-V&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Find the process for a specific JSONL session
&lt;/h2&gt;

&lt;p&gt;Assume the error includes this session file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/dfs/data/.codex-data/sessions/2026/09/21/rollout-2026-09-21T10-27-46-01a0c1ca-74cd-7d21-bd7b-1de7e03f7f96.jsonl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The thread ID that can be used for matching is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;01a0c1ca-74cd-7d21-bd7b-1de7e03f7f96
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.1 List all suspicious Codex PIDs
&lt;/h3&gt;

&lt;p&gt;First, list all currently running Codex processes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps auxww | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'[c]odex'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the issue is likely caused by a bulk-resume task, narrow the list to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps auxww | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'[c]odex resume --all'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second column in the output is the PID. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root  100621  ...  codex resume --all --include-non-interactive
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, &lt;code&gt;100621&lt;/code&gt; is the PID.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2 Trace one PID with &lt;code&gt;strace&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Replace &lt;code&gt;&amp;lt;PID&amp;gt;&lt;/code&gt; with the real process ID, for example &lt;code&gt;100621&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;strace &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-tt&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; 256 &lt;span class="nt"&gt;-p&lt;/span&gt; 100621 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;trace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;%file,flock,fcntl,read,write &lt;span class="se"&gt;\&lt;/span&gt;
  2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;tee&lt;/span&gt; /tmp/codex-100621.strace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-p 100621&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Attaches to an existing process&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-f&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Also traces child processes and threads&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-tt&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Prints precise timestamps&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-s 256&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Prints up to 256 characters, avoiding truncated paths&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-e trace=%file,flock,fcntl,read,write&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Limits output to file access, locks, reads, and writes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;tee&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Writes output to both the terminal and a log file&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Keep &lt;code&gt;strace&lt;/code&gt; running. In another terminal, try &lt;code&gt;codex resume&lt;/code&gt; again to trigger activity. Observe the output for a few seconds, then press &lt;code&gt;Ctrl+C&lt;/code&gt; to stop &lt;code&gt;strace&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Pressing &lt;code&gt;Ctrl+C&lt;/code&gt; stops only &lt;code&gt;strace&lt;/code&gt;; it does not terminate the Codex process being traced.&lt;/p&gt;

&lt;p&gt;Search whether the PID accessed the target JSONL file or processed a lock:&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;grep&lt;/span&gt; &lt;span class="nt"&gt;-Ei&lt;/span&gt; &lt;span class="s1"&gt;'01a0c1ca-74cd-7d21-bd7b-1de7e03f7f96|writer|lock|\.jsonl'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /tmp/codex-100621.strace
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the output contains the complete target &lt;code&gt;.jsonl&lt;/code&gt; path, or lock-related calls such as &lt;code&gt;flock&lt;/code&gt;, &lt;code&gt;fcntl&lt;/code&gt;, or &lt;code&gt;F_SETLK&lt;/code&gt;, that PID is actively handling the session and should be treated as a priority investigation target.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.3 Check every &lt;code&gt;resume --all&lt;/code&gt; PID in bulk
&lt;/h3&gt;

&lt;p&gt;If you have several suspicious processes, briefly trace each &lt;code&gt;codex resume --all&lt;/code&gt; process and search for the target thread ID:&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;THREAD_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'01a0c1ca-74cd-7d21-bd7b-1de7e03f7f96'&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;pid &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;ps auxww | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'[c]odex resume --all'&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Checking PID: &lt;/span&gt;&lt;span class="nv"&gt;$pid&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  strace &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-tt&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; 256 &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$pid&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="nv"&gt;trace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;%file,flock,fcntl &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="s2"&gt;"/tmp/codex-&lt;/span&gt;&lt;span class="nv"&gt;$pid&lt;/span&gt;&lt;span class="s2"&gt;.strace"&lt;/span&gt; &amp;amp;

  &lt;span class="nv"&gt;trace_pid&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$!&lt;/span&gt;
  &lt;span class="nb"&gt;sleep &lt;/span&gt;3
  &lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$trace_pid&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;true

  &lt;/span&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-Eqi&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$THREAD_ID&lt;/span&gt;&lt;span class="s2"&gt;|writer|lock|&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;jsonl"&lt;/span&gt; &lt;span class="s2"&gt;"/tmp/codex-&lt;/span&gt;&lt;span class="nv"&gt;$pid&lt;/span&gt;&lt;span class="s2"&gt;.strace"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Possible match: PID &lt;/span&gt;&lt;span class="nv"&gt;$pid&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-Ei&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$THREAD_ID&lt;/span&gt;&lt;span class="s2"&gt;|writer|lock|&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="s2"&gt;jsonl"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
      &lt;span class="s2"&gt;"/tmp/codex-&lt;/span&gt;&lt;span class="nv"&gt;$pid&lt;/span&gt;&lt;span class="s2"&gt;.strace"&lt;/span&gt; | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 20
  &lt;span class="k"&gt;fi
done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A process that does not make a filesystem call during the three-second tracing window is not necessarily unrelated to the target thread. It may simply be idle or waiting. This script is intended to reduce the search space, not replace judgment about the process state and workload.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Terminate the process associated with one JSONL session
&lt;/h2&gt;

&lt;p&gt;After confirming that a PID is not performing valid work and that it accesses or owns the target thread, inspect its full details first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps &lt;span class="nt"&gt;-fp&lt;/span&gt; &amp;lt;PID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try a graceful termination first:&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;kill&lt;/span&gt; &amp;lt;PID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait three seconds and confirm whether it has exited:&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;sleep &lt;/span&gt;3
ps &lt;span class="nt"&gt;-p&lt;/span&gt; &amp;lt;PID&amp;gt; &lt;span class="nt"&gt;-o&lt;/span&gt; pid,stat,etime,cmd
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it still exists, use a forced termination:&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;kill&lt;/span&gt; &lt;span class="nt"&gt;-9&lt;/span&gt; &amp;lt;PID&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A plain &lt;code&gt;kill&lt;/code&gt; sends &lt;code&gt;SIGTERM&lt;/code&gt;, allowing the process an opportunity to release resources and run shutdown cleanup. &lt;code&gt;kill -9&lt;/code&gt; sends &lt;code&gt;SIGKILL&lt;/code&gt;, which cannot be caught or handled; the process stops immediately and cannot perform cleanup. Use &lt;code&gt;kill -9&lt;/code&gt; only for a stuck process after you have confirmed that it is safe to terminate.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Terminate all &lt;code&gt;codex resume --all&lt;/code&gt; processes
&lt;/h2&gt;

&lt;p&gt;If you have confirmed that all &lt;code&gt;codex resume --all --include-non-interactive&lt;/code&gt; processes are stale and no longer have business value, you can clean them up together.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.1 Preview the processes first
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps auxww | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'[c]odex resume --all'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Carefully check the &lt;code&gt;START&lt;/code&gt;, &lt;code&gt;TIME&lt;/code&gt;, &lt;code&gt;TTY&lt;/code&gt;, and &lt;code&gt;COMMAND&lt;/code&gt; columns. Do not terminate a session that was started recently and is still performing real work.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.2 Send &lt;code&gt;SIGTERM&lt;/code&gt; first
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps auxww | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'[c]odex resume --all'&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt; | xargs &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nb"&gt;kill&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait a few seconds and check again:&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;sleep &lt;/span&gt;3
ps auxww | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'[c]odex resume --all'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.3 Use &lt;code&gt;SIGKILL&lt;/code&gt; only for surviving processes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps auxww | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s1"&gt;'[c]odex resume --all'&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt; | xargs &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nt"&gt;-9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The following script can be saved as &lt;code&gt;kill_codex_resume_all.sh&lt;/code&gt;. It displays the target processes and asks for confirmation before sending &lt;code&gt;SIGTERM&lt;/code&gt;. Passing &lt;code&gt;-9&lt;/code&gt; sends &lt;code&gt;SIGKILL&lt;/code&gt; instead.&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="c"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="nv"&gt;PATTERN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'[c]odex resume --all'&lt;/span&gt;
&lt;span class="nv"&gt;SIGNAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'TERM'&lt;/span&gt;

&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="k"&gt;:-}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'-9'&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nv"&gt;SIGNAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'KILL'&lt;/span&gt;

&lt;span class="nv"&gt;PIDS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ps auxww | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PATTERN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $2}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PIDS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'No codex resume --all processes found'&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="k"&gt;fi

&lt;/span&gt;ps auxww | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$PATTERN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'\nSend SIG%s to the PIDs above? [y/N] '&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SIGNAL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; answer

&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$answer&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in
  &lt;/span&gt;y|Y&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
  &lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Cancelled'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;0 &lt;span class="p"&gt;;;&lt;/span&gt;
&lt;span class="k"&gt;esac&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;pid &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;$PIDS&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;kill&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$SIGNAL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$pid&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="s2"&gt;"Sent SIG&lt;/span&gt;&lt;span class="nv"&gt;$SIGNAL&lt;/span&gt;&lt;span class="s2"&gt; to PID: &lt;/span&gt;&lt;span class="nv"&gt;$pid&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make the script executable and run 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;chmod&lt;/span&gt; +x kill_codex_resume_all.sh

&lt;span class="c"&gt;# Default: send SIGTERM&lt;/span&gt;
./kill_codex_resume_all.sh

&lt;span class="c"&gt;# Use SIGKILL only if normal termination did not work&lt;/span&gt;
./kill_codex_resume_all.sh &lt;span class="nt"&gt;-9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  6. Resume the session again
&lt;/h2&gt;

&lt;p&gt;After the stale writer process has been cleaned up, retry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;codex resume
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;already has an active writer&lt;/code&gt; still appears, do &lt;strong&gt;not&lt;/strong&gt; delete the session &lt;code&gt;.jsonl&lt;/code&gt; file. At that point, one of the following is more likely:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The writer is still active on another machine, container, or Codex client.&lt;/li&gt;
&lt;li&gt;Internal writer state on shared storage was not released normally.&lt;/li&gt;
&lt;li&gt;Your current Codex version has a writer-ownership or app-server issue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a temporary workaround, start a new session without &lt;code&gt;resume&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;codex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then investigate Codex instances in other environments, confirm the shared-storage path, and check the installed Codex version.&lt;/p&gt;

</description>
      <category>cli</category>
      <category>debugging</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
