<?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: Guo Mengyue</title>
    <description>The latest articles on DEV Community by Guo Mengyue (@gemron).</description>
    <link>https://dev.to/gemron</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%2F4108297%2F65b5eca4-9d73-4d30-813a-e4c4d37052cf.jpg</url>
      <title>DEV Community: Guo Mengyue</title>
      <link>https://dev.to/gemron</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gemron"/>
    <language>en</language>
    <item>
      <title>Keeping AI coding work resumable: projects, sessions and handoffs in Termexo</title>
      <dc:creator>Guo Mengyue</dc:creator>
      <pubDate>Sun, 13 Sep 2026 12:38:29 +0000</pubDate>
      <link>https://dev.to/gemron/keeping-ai-coding-work-resumable-projects-sessions-and-handoffs-in-termexo-jah</link>
      <guid>https://dev.to/gemron/keeping-ai-coding-work-resumable-projects-sessions-and-handoffs-in-termexo-jah</guid>
      <description>&lt;p&gt;An AI coding task can stop for several reasons: a test fails, the agent needs approval, or you have to switch projects. Starting another terminal is easy. Remembering what each terminal was doing is the harder part.&lt;/p&gt;

&lt;p&gt;I maintain Termexo, an MIT-licensed Windows workbench for organizing AI coding terminals. Its direction is to keep projects, agents, model settings and session context together, with browser access to the same running desktop when needed. This post describes a workflow to try, including the parts that still need a person.&lt;/p&gt;

&lt;h2&gt;
  
  
  Give every terminal a project and a job
&lt;/h2&gt;

&lt;p&gt;Start with one repository and two tasks: implementing a change and checking it. Write an acceptance condition before starting either task. For a login form, that could be: an invalid credential response shows a useful message, and the corresponding test passes.&lt;/p&gt;

&lt;p&gt;Termexo groups project directories, terminal layouts and related settings into workspaces. It supports Claude Code, Codex CLI, OpenCode and Antigravity, presenting their real terminals. The task board helps connect the work to goals and acceptance.&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%2Fhvpnuie0bfawwrw7bexs.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%2Fhvpnuie0bfawwrw7bexs.png" alt="Termexo task board with demonstration tasks" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Repository screenshot with demonstration data. A task reaching a completed state still needs review.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When two agents work concurrently, define which files each may change and which task depends on the other. A shared workbench does not automatically resolve conflicting edits. Separate branches or worktrees can help when appropriate; the developer remains responsible for integration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat waiting as something you need to see
&lt;/h2&gt;

&lt;p&gt;A running process is not necessarily making progress. It may be waiting for input or approval. Status indicators and notifications help expose those moments so you can return to the relevant terminal and make the decision.&lt;/p&gt;

&lt;p&gt;For a small trial, notice whether you can identify the waiting task without opening every terminal. That is a more useful evaluation than counting how many agents are open.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leave a handoff that another session can use
&lt;/h2&gt;

&lt;p&gt;Native session search and recovery help reopen supported agent sessions. When changing tools or handing work to another person, use a reviewed handoff with four parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Goal:&lt;/strong&gt; what behavior should change, and how will it be accepted?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progress:&lt;/strong&gt; what changed, and where is the code?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verification:&lt;/strong&gt; which checks ran, what passed, and what remains unverified?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Next step:&lt;/strong&gt; one concrete action, including unresolved constraints.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example: “The login error message is implemented. The unit test passes. Browser behavior has not been checked. Next, verify keyboard submission and add the missing test if it fails.”&lt;/p&gt;

&lt;p&gt;Termexo's handoff packages help carry this background. They are not a complete transfer of an agent's private context, and the receiving environment still needs the code, CLI and relevant configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reach the running desktop from another device
&lt;/h2&gt;

&lt;p&gt;Browser access can be useful when a long task needs a short response while you are away from your desk. Trusted local networks or controlled VPNs can use direct access; cross-network access can use a reachable self-hosted HTTPS relay.&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%2Fodio5uzezpfrq26yrka7.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%2Fodio5uzezpfrq26yrka7.png" alt="Termexo desktop and phone access illustration" width="800" height="500"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Project interface imagery illustrating access to the desktop from a phone.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The Windows host must stay on, with Termexo running and connected. The terminal processes execute there. Plan for sleep settings, connectivity and access credentials before relying on the remote workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this fits today
&lt;/h2&gt;

&lt;p&gt;For an individual developer, the use case is maintaining several projects without repeatedly reconstructing their state. Within an engineering team, the current fit is each member organizing their own workbench and producing clearer handoffs.&lt;/p&gt;

&lt;p&gt;Shared workspaces, fine-grained permissions, centralized audit and fuller automatic orchestration remain longer-term plans. Local-first describes where the workbench and its state run; sending code to an external model still depends on the agent, endpoint and model configuration.&lt;/p&gt;

&lt;p&gt;Try a complete cycle: define a task, implement it, check it, resume a session and review a handoff. Add remote access only if it solves a real interruption in your day.&lt;/p&gt;

&lt;p&gt;Source and releases: &lt;a href="https://github.com/gemron/Termexo" rel="noopener noreferrer"&gt;gemron/Termexo&lt;/a&gt;. Setup and remote access: &lt;a href="https://www.termexo.com/guide.html" rel="noopener noreferrer"&gt;project guide&lt;/a&gt;. Agent CLIs, accounts and model services require their own setup.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Written by the project maintainer with AI assistance. Images come from the project and include demonstration content.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
    </item>
    <item>
      <title>I Have Five Claude Accounts and No Idea Which One This Terminal Is Spending</title>
      <dc:creator>Guo Mengyue</dc:creator>
      <pubDate>Thu, 03 Sep 2026 15:25:37 +0000</pubDate>
      <link>https://dev.to/gemron/i-have-five-claude-accounts-and-no-idea-which-one-this-terminal-is-spending-3oj5</link>
      <guid>https://dev.to/gemron/i-have-five-claude-accounts-and-no-idea-which-one-this-terminal-is-spending-3oj5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Disclosure:&lt;/strong&gt; I maintain Termexo, the project this post is about. It is free and MIT licensed — there is nothing to buy. This write-up was drafted with AI assistance from my own notes and the project's source, and I have checked every technical claim in it against the code that ships in V0.7.0.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you run more than one Claude Code or Codex terminal, you have probably hit this moment:&lt;/p&gt;

&lt;p&gt;Your usage is nearly gone, so you open a new terminal on a different account and type &lt;code&gt;claude&lt;/code&gt;. It starts. But which account is it actually signed in as? Nothing in the interface tells you. You are left reasoning from "did I remember to set that environment variable?" — and when you guess wrong, you quietly burn the wrong subscription.&lt;/p&gt;

&lt;p&gt;Termexo V0.7 is mostly about that: &lt;strong&gt;making the account a visible, changeable property of a terminal instead of invisible state hidden in an environment variable.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I maintain Termexo. It is a Windows-only, local-first workspace for coding agents, MIT licensed. It does not replace Claude Code, Codex, or OpenCode and does not re-skin their chat interfaces — all three keep running in real PTY terminals. Termexo owns the layer above: workspaces, layout, state, sessions, tasks, and accounts.&lt;/p&gt;

&lt;h3&gt;
  
  
  The account lives in a directory, not in a key
&lt;/h3&gt;

&lt;p&gt;The constraint that shapes everything else: for Claude Code and Codex, identity is not a swappable token. It is an entire &lt;strong&gt;configuration directory&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Claude Code reads &lt;code&gt;CLAUDE_CONFIG_DIR&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Codex reads &lt;code&gt;CODEX_HOME&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Credentials, identity (&lt;code&gt;userID&lt;/code&gt;, &lt;code&gt;oauthAccount&lt;/code&gt;, &lt;code&gt;machineID&lt;/code&gt;), session transcripts, and caches all live under that directory. Whichever directory you point at, that is who the CLI is.&lt;/p&gt;

&lt;p&gt;Termexo gives every managed account its own directory. "Switching accounts" therefore means changing an environment variable — and &lt;strong&gt;a running process cannot be told to change its own environment.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That single fact is what makes this a lifecycle problem.&lt;/p&gt;

&lt;h3&gt;
  
  
  Two-phase launch, so the frontend never touches secrets
&lt;/h3&gt;

&lt;p&gt;Termexo already launched agents in two phases, so the switch reuses it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. prepare_claude_launch(terminalId, accountProfileId, profileId, …)
   → resolve the account, model, and network profiles
   → read API keys from Windows Credential Manager
   → write this terminal's hook configuration
   → stash the full environment map in LaunchEnvironmentStore, keyed by terminalId
   → return only an AgentLaunchSpec (a command string and an executable path)

2. create_terminal(terminalId, …)
   → PtyManager::start takes (not reads) that environment out of the store
   → injects it into the PTY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The frontend never receives a key and never builds a command line. It generates &lt;code&gt;terminalId&lt;/code&gt; with &lt;code&gt;crypto.randomUUID()&lt;/code&gt; before step 1 and reuses it.&lt;/p&gt;

&lt;p&gt;So switching an account becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// 1. Build the new launch command first.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;launch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;prepareLaunch&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;terminalId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;accountProfileId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;          &lt;span class="c1"&gt;// ← the only thing that changes&lt;/span&gt;
  &lt;span class="na"&gt;profileId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profileId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;mcpProfileId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mcpProfileId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;autoConfirm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;autoConfirm&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// 2. Only now touch the running PTY.&lt;/span&gt;
&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;terminalGateway&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;close&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// 3. Restart on the new command.&lt;/span&gt;
&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;restartTerminalWithProfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;launch&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;profileId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;profileId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;mcpProfileId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;original&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mcpProfileId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;accountProfileId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The order matters. If preparation fails — the account directory cannot be created, a credential is gone — the error is thrown &lt;em&gt;before&lt;/em&gt; &lt;code&gt;close()&lt;/code&gt;, and the running session is untouched. Build the replacement, then dismantle the original; never the other way round.&lt;/p&gt;

&lt;h3&gt;
  
  
  The restart always starts a new session, and that is honest
&lt;/h3&gt;

&lt;p&gt;The dialog says "new session" in plain words. Not because resuming is hard, but because it is &lt;strong&gt;semantically wrong&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;A transcript physically lives in the previous account's configuration directory (&lt;code&gt;~/.claude/projects/**/*.jsonl&lt;/code&gt;). Under the new account's directory that session id does not exist, and &lt;code&gt;claude --resume &amp;lt;id&amp;gt;&lt;/code&gt; simply fails.&lt;/p&gt;

&lt;p&gt;So the restart clears &lt;code&gt;nativeSessionId&lt;/code&gt;, and the UI says so up front rather than letting you discover it when your first message kills the terminal.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reconnection has to rebuild the environment
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;LaunchEnvironmentStore&lt;/code&gt; is a take-once, in-memory store. After the app restarts, terminals reconnect — and that environment is long gone. Left alone, the CLI falls back to its default home and silently becomes a different account.&lt;/p&gt;

&lt;p&gt;The fix is to let a terminal remember its own identity and rebuild from that record:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;&lt;span class="k"&gt;pub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;crate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="nf"&gt;relaunch_environment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;database&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;WorkspaceDatabase&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;CredentialStore&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;agent_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;account_profile_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;model_profile_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;workspace_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Option&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;amp;&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;create_terminal&lt;/code&gt; takes this path whenever the stash is empty, rebuilding the account directory, proxy settings, and provider key. A terminal you switched stays switched across restarts, because the new &lt;code&gt;accountProfileId&lt;/code&gt; was written back to its record.&lt;/p&gt;

&lt;h3&gt;
  
  
  One more thing: signed in, and asked to sign in again
&lt;/h3&gt;

&lt;p&gt;While building this I tracked down an old annoyance: an account that had already completed &lt;code&gt;claude auth login&lt;/code&gt; was asked to log in again the first time a terminal opened on it.&lt;/p&gt;

&lt;p&gt;Claude Code decides whether to run its first-run wizard from a single flag in the configuration directory — &lt;code&gt;hasCompletedOnboarding&lt;/code&gt; — and that wizard &lt;strong&gt;always includes a login step&lt;/strong&gt;, regardless of whether valid credentials are sitting right there. Earlier &lt;code&gt;claude auth login&lt;/code&gt; builds never set the flag after a successful sign-in, so every account signed in by one of them met the wizard's login screen every time.&lt;/p&gt;

&lt;p&gt;Termexo now writes the flag when the account directory already holds credentials. Writes go through a sibling temp file and a rename, so a CLI reading concurrently never sees half a file; a damaged config is skipped and logged rather than overwritten, because Claude repairs it from its own backups and rewriting would destroy what it repairs from.&lt;/p&gt;

&lt;p&gt;An account that has &lt;em&gt;not&lt;/em&gt; signed in still gets the wizard — that one needs it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What else landed in V0.7
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The window draws its own chrome.&lt;/strong&gt; No system title bar: the top bar spans the whole window with the window controls at its right edge, and both side panels start beneath it, the way an editor lays out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terminals render on the GPU.&lt;/strong&gt; Long scrollback scrolls without the DOM renderer's stutter; machines without a usable GPU fall back automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drag-to-reorder works again&lt;/strong&gt; for terminal tabs in the desktop build, where the webview's own drag handling had been eating the events.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration copies between accounts&lt;/strong&gt; — settings, instructions, plugins, and skills. Credentials, identity, and session history never travel, so both accounts stay signed in as themselves.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A finished sign-in is detected on its own&lt;/strong&gt;, rather than waiting on a login CLI that keeps running after the browser flow has already returned.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Boundaries, kept on purpose
&lt;/h3&gt;

&lt;p&gt;There is no Termexo account and no cloud relay. Workspaces, terminal configuration, the session index, and events live in local SQLite. API keys live in Windows Credential Manager. Native session files stay read-only — Termexo parses them and never rewrites a JSONL to make its own UI tidier.&lt;/p&gt;

&lt;p&gt;Local-first does not mean the model requests are offline: Claude Code, Codex, and OpenCode still reach whichever provider you configured, under that provider's own terms and privacy policy. Termexo orchestrates locally; it does not proxy your requests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try it
&lt;/h3&gt;

&lt;p&gt;Windows 10/11 x64, WebView2, Node.js 18.18+:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;npx&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;termexo&lt;/span&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="nx"&gt;latest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Known limits: Windows only for now, and third-party endpoints for Codex need the provider to be compatible with the Responses API — being OpenAI-compatible is not always enough.&lt;/p&gt;

&lt;p&gt;The source and the V0.7.0 release notes are on &lt;a href="https://github.com/gemron/Termexo" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, and there is a project site at &lt;a href="https://www.termexo.com" rel="noopener noreferrer"&gt;termexo.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I maintain this project, so take the framing above for what it is — the account problem is the one I hit myself. The feedback I want most: &lt;strong&gt;when you run several coding agents at once, where does your workflow lose the most context&lt;/strong&gt; — planning, approval, recovery, or accounts and quota?&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
