<?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: José Antonio Garrido</title>
    <description>The latest articles on DEV Community by José Antonio Garrido (@yeyo11).</description>
    <link>https://dev.to/yeyo11</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%2F4204805%2F50ed973a-eaee-4737-9244-f598445c75f1.jpeg</url>
      <title>DEV Community: José Antonio Garrido</title>
      <link>https://dev.to/yeyo11</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yeyo11"/>
    <language>en</language>
    <item>
      <title>Shipcast: launch your GitHub projects without writing the announcement ten times</title>
      <dc:creator>José Antonio Garrido</dc:creator>
      <pubDate>Sun, 25 Oct 2026 04:09:21 +0000</pubDate>
      <link>https://dev.to/yeyo11/shipcast-launch-your-github-projects-without-writing-the-announcement-ten-times-4p7c</link>
      <guid>https://dev.to/yeyo11/shipcast-launch-your-github-projects-without-writing-the-announcement-ten-times-4p7c</guid>
      <description>&lt;p&gt;You publish a release and then spend an afternoon on the same announcement: a blog post, a dev.to copy, a Bluesky post, a Mastodon post, an Instagram carousel, a newsletter issue, a Show HN title. Each one has its own length limit and its own tone, and the easiest mistake is to promise in one of them something the code does not do yet.&lt;/p&gt;

&lt;p&gt;Shipcast does that work from the release. It reads the project's &lt;strong&gt;code&lt;/strong&gt;, not just its README, writes a piece for each channel, and publishes each one once you approve it. I used it to launch &lt;a href="https://github.com/yeyo11/claudio" rel="noopener noreferrer"&gt;claudio&lt;/a&gt; v0.9.0, and this article is part of its own launch.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The article on your blog in English and Spanish, each with its own URL.&lt;/li&gt;
&lt;li&gt;Canonical copies on dev.to (and Hashnode, built but not yet tested live).&lt;/li&gt;
&lt;li&gt;Posts on Bluesky and Mastodon, and an Instagram carousel with its story and a comment.&lt;/li&gt;
&lt;li&gt;A newsletter issue per language through Brevo.&lt;/li&gt;
&lt;li&gt;Ready-to-paste Show HN and Product Hunt drafts: neither has an API to post through, so Shipcast never posts them.&lt;/li&gt;
&lt;li&gt;Telegram and Discord connectors, plus the numbers of each channel on the launch's page.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Opt in per repo
&lt;/h2&gt;

&lt;p&gt;A project turns launches on with &lt;code&gt;.github/launch.yml&lt;/code&gt;. Each channel has a mode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="na"&gt;brand&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;personal&lt;/span&gt;
&lt;span class="na"&gt;language&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;en&lt;/span&gt;

&lt;span class="na"&gt;publishing&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;blog&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;approval&lt;/span&gt;
  &lt;span class="na"&gt;devto&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;approval&lt;/span&gt;
  &lt;span class="na"&gt;bluesky&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;approval&lt;/span&gt;
  &lt;span class="na"&gt;hackerNews&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;manual&lt;/span&gt;

&lt;span class="na"&gt;assets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;demo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docs/media/tour.gif&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;auto&lt;/code&gt; publishes as soon as the pack is generated, &lt;code&gt;approval&lt;/code&gt; publishes when you merge the drafts, &lt;code&gt;manual&lt;/code&gt; leaves a draft you post yourself, and &lt;code&gt;off&lt;/code&gt; skips the channel. Hacker News and Product Hunt refuse any mode other than &lt;code&gt;manual&lt;/code&gt; or &lt;code&gt;off&lt;/code&gt;. The schema is strict: a misspelt key is an error that points at its line instead of a setting silently ignored.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check the repo first
&lt;/h2&gt;

&lt;p&gt;Before spending any AI budget, the pre-flight check confirms the repo is ready:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm shipcast preflight owner/repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It checks that there is a published release, a valid and enabled &lt;code&gt;launch.yml&lt;/code&gt;, a license GitHub recognises, a README and a demo that answers. Each line prints &lt;code&gt;ok&lt;/code&gt;, &lt;code&gt;warn&lt;/code&gt; or &lt;code&gt;FAIL&lt;/code&gt;, and &lt;code&gt;launch&lt;/code&gt; refuses to start while a required check fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trigger a launch
&lt;/h2&gt;

&lt;p&gt;Two ways. Manually, for the latest release or a given tag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm shipcast launch owner/repo &lt;span class="nt"&gt;--ref&lt;/span&gt; v1.2.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or let the engine watch your account:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm shipcast watch &lt;span class="nt"&gt;--interval&lt;/span&gt; 300
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;watch&lt;/code&gt; polls your public GitHub events (there are no webhooks, so nothing on your machine is exposed), drafts each new release, publishes it once its pull request is merged and reads the metrics every six hours. The interval cannot go below 60 seconds, which is what GitHub asks of event pollers.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Analyse.&lt;/strong&gt; Claude, through &lt;a href="https://github.com/yeyo11/claudio" rel="noopener noreferrer"&gt;claudio&lt;/a&gt;, reads the repository and separates what is implemented from what is only planned or only claimed by the docs. Only the implemented part is presented as working.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate.&lt;/strong&gt; The result is one structured content pack validated against a JSON Schema: the article in each language and a piece for each channel within its limits. Shipcast also builds the launch image, the Instagram carousel and story, and a cover in your blog's style when the project has none.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Approve.&lt;/strong&gt; The drafts arrive as a pull request in your launches repo, which is also your blog's source. Read and edit them in the app or on GitHub; merging publishes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publish once.&lt;/strong&gt; A SQLite registry records every launch and every channel. Re-running a workflow or publishing a minor version does not repeat a campaign, and a channel that failed for good can be retried:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm shipcast publish &lt;span class="nt"&gt;--retry&lt;/span&gt; bluesky
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;pnpm shipcast status&lt;/code&gt; lists the latest launches, where each stands and which channels are configured.&lt;/p&gt;

&lt;h2&gt;
  
  
  The app
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The web app has Launches (where each one went and what is waiting for you), a review page (edit, approve, retry), Launch a repo, Write, and Channels. Write takes an article in your own words, translates it, writes the piece for each channel and publishes it the same way. Channels lists every network with its accounts per brand, checks each credential, runs OAuth for Mastodon and Instagram and keeps secrets in your operating system's keychain. Sign-in is with GitHub, limited to the logins you allow.&lt;/p&gt;

&lt;p&gt;The personal and company brands have their own accounts, tone and language, and a launch only uses its own brand's accounts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Quick start
&lt;/h2&gt;

&lt;p&gt;You need Node 24 and pnpm, &lt;a href="https://github.com/yeyo11/claudio" rel="noopener noreferrer"&gt;claudio&lt;/a&gt; as the AI provider (the repo's &lt;code&gt;docker-compose.yml&lt;/code&gt; starts it), a launches repo with an Astro blog that accepts the articles (&lt;a href="https://github.com/yeyo11/shipcast/blob/main/docs/launches-repo.md" rel="noopener noreferrer"&gt;docs/launches-repo.md&lt;/a&gt; describes the contract), and an account on each network you want. On Linux the keychain needs &lt;code&gt;libsecret-tools&lt;/code&gt;, and the demo video needs ffmpeg.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm &lt;span class="nb"&gt;install
cp&lt;/span&gt; .env.example .env              &lt;span class="c"&gt;# fill in what you use&lt;/span&gt;
pnpm shipcast preflight owner/repo
pnpm shipcast launch owner/repo   &lt;span class="c"&gt;# or: pnpm app&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A network or source without its variables is left out, and &lt;code&gt;pnpm shipcast status&lt;/code&gt; shows what is on.&lt;/p&gt;

&lt;h2&gt;
  
  
  What comes next
&lt;/h2&gt;

&lt;p&gt;The next phase covers other AI providers besides claudio, a GitHub Action mode, a one-command install, and the setup of the company brand. The test of this release is to launch Shipcast with Shipcast on every connected channel.&lt;/p&gt;

&lt;p&gt;The code is MIT-licensed at &lt;a href="https://github.com/yeyo11/shipcast" rel="noopener noreferrer"&gt;github.com/yeyo11/shipcast&lt;/a&gt;. Issues are welcome, and please open one before a pull request.&lt;/p&gt;

</description>
      <category>github</category>
      <category>automation</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Claudio: run Claude Code as a service</title>
      <dc:creator>José Antonio Garrido</dc:creator>
      <pubDate>Sat, 24 Oct 2026 23:10:56 +0000</pubDate>
      <link>https://dev.to/yeyo11/claudio-run-claude-code-as-a-service-69m</link>
      <guid>https://dev.to/yeyo11/claudio-run-claude-code-as-a-service-69m</guid>
      <description>&lt;p&gt;Claude Code lives in a terminal. That is fine until you want to start a chat from your phone, check on an agent that is still working while you are away from the desk, or run five of them in parallel without losing track of which one needs an answer. I built Claudio to cover that gap: it runs Claude Code as a service.&lt;/p&gt;

&lt;p&gt;This post covers what Claudio is, how it talks to Claude Code and how to install it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you get
&lt;/h2&gt;

&lt;p&gt;Claudio puts the Claude Code CLI behind a REST API and a web UI. The same server also backs a Linux desktop app and an installable web app for your phone. Everything runs on your machine or your server, with your own Claude login.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chats you can start, stream and answer from a browser or over HTTP.&lt;/li&gt;
&lt;li&gt;Orchestrations: a graph of tasks run by parallel workers, each in its own git worktree.&lt;/li&gt;
&lt;li&gt;Several Claude accounts, with work moving to the one that still has quota.&lt;/li&gt;
&lt;li&gt;A review screen for what the agents changed.&lt;/li&gt;
&lt;li&gt;Projects with a task board and a team of agents.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I will go through them one at a time.&lt;/p&gt;

&lt;h2&gt;
  
  
  The one rule: only the interface the CLI ships for programs
&lt;/h2&gt;

&lt;p&gt;Claudio does not scrape the terminal, call undocumented endpoints or log in a second time on its own. It reaches Claude Code through the CLI's flags, its stream protocol and the files it writes. &lt;a href="https://github.com/yeyo11/claudio/blob/main/docs/cli-surfaces.md" rel="noopener noreferrer"&gt;docs/cli-surfaces.md&lt;/a&gt; lists every surface in use, one row per need. 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;Run / continue a conversation  claude -p --input-format stream-json --output-format stream-json
Auth status                    claude auth status --json
Session history                $CLAUDE_CONFIG_DIR/projects/*/*.jsonl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The practical consequence is a ceiling: what the CLI cannot do, Claudio cannot do. Web artifacts and claude.ai chat memory have no CLI surface, so Claudio does not touch them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chats over HTTP
&lt;/h2&gt;

&lt;p&gt;A chat is one long-lived &lt;code&gt;claude&lt;/code&gt; process fed over stdin, with &lt;code&gt;--resume&lt;/code&gt; when the process is gone. You can start one from the UI or from the API:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost:8797/api/chats &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"prompt": "Add a unit test for parseDuration", "cwd": "/workspace/my-app"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The request also accepts &lt;code&gt;worktree&lt;/code&gt; (run inside a new git worktree of that name) and &lt;code&gt;jsonSchema&lt;/code&gt; (structured output). From there you have &lt;code&gt;POST /api/chats/:id/messages&lt;/code&gt;, &lt;code&gt;/stop&lt;/code&gt;, &lt;code&gt;/interrupt&lt;/code&gt;, &lt;code&gt;/resume&lt;/code&gt; and &lt;code&gt;/fork&lt;/code&gt;, and &lt;code&gt;GET /api/chats/:id/stream&lt;/code&gt; to follow it. When the agent asks for permission, a question or a plan approval, you answer from the UI (or &lt;code&gt;POST /api/chats/:id/permissions/:requestId&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The interactive reference is served at &lt;code&gt;/docs&lt;/code&gt; and the OpenAPI 3.1 document at &lt;code&gt;/openapi.json&lt;/code&gt;. If you turned authentication on, send &lt;code&gt;Authorization: Bearer &amp;lt;token&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The UI does not poll. One server-sent events feed, &lt;code&gt;GET /api/events&lt;/code&gt;, carries chats, prompts waiting for you, tasks, orchestrations and account rotation, and it resumes with &lt;code&gt;Last-Event-ID&lt;/code&gt; after a drop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Orchestrations
&lt;/h2&gt;

&lt;p&gt;An orchestration is a graph of tasks. Workers run in parallel, each in its own git worktree, and their branches are merged into one integration branch. After that, a verification phase runs your checks (build, tests) on the integration branch under a timeout, and a pull request can be offered. It exists as the &lt;code&gt;POST /api/orchestrations&lt;/code&gt; route and as a screen where you follow the run as steps.&lt;/p&gt;

&lt;p&gt;Two things to watch for: the checks need &lt;code&gt;worktree: true&lt;/code&gt; on the graph engine, and workers do not survive a restart. A task caught by one is marked &lt;code&gt;interrupted&lt;/code&gt; and its chat continues in a new execution while it has attempts left.&lt;/p&gt;

&lt;h2&gt;
  
  
  Several accounts, rotated
&lt;/h2&gt;

&lt;p&gt;Each Claude account gets its own &lt;code&gt;CLAUDE_CONFIG_DIR&lt;/code&gt; and is signed in once. Claudio reads usage per window, moves new work to an account with quota before a limit is hit, replays a turn that hits its limit on the next account, and waits for the reset only when none has any quota left. There is also a small CLI, &lt;code&gt;claudio-accounts&lt;/code&gt;, in &lt;code&gt;packages/accounts&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Reviewing changes inside Claudio
&lt;/h2&gt;

&lt;p&gt;For a chat, a task or the integration branch there is a diff screen built from git and the transcript. Each edit carries the sentence Claude wrote just before it, so you read the change together with its reason.&lt;/p&gt;

&lt;h2&gt;
  
  
  Projects, a board and a team
&lt;/h2&gt;

&lt;p&gt;You can import a directory as a project. It gets a Tasks board with work items (&lt;code&gt;AGN-12&lt;/code&gt;-style keys, five fixed columns, epics, milestones), and a team where each member is a Claude Code agent file with a role. With the flow switched on, a card entering a column starts that role's run. Only you move a card to Done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Guards
&lt;/h2&gt;

&lt;p&gt;Claudio can add &lt;code&gt;PreToolUse&lt;/code&gt; hooks that hold even in &lt;code&gt;bypassPermissions&lt;/code&gt;: no push, no &lt;code&gt;--no-verify&lt;/code&gt;, no recursive delete outside the worktree, no secret written. They are on for orchestration workers and the flow, and configurable per project for chats. The mechanism is a settings file with only Claudio's hooks, passed with &lt;code&gt;--settings&lt;/code&gt;. See &lt;a href="https://github.com/yeyo11/claudio/blob/main/docs/guards.md" rel="noopener noreferrer"&gt;docs/guards.md&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Docker&lt;/strong&gt; (amd64):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--init&lt;/span&gt; &lt;span class="nt"&gt;--name&lt;/span&gt; claudio &lt;span class="nt"&gt;--restart&lt;/span&gt; unless-stopped &lt;span class="nt"&gt;-p&lt;/span&gt; 127.0.0.1:8797:8797 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-v&lt;/span&gt; claudio-config:/home/node/.claude &lt;span class="nt"&gt;-v&lt;/span&gt; claudio-data:/data &lt;span class="nt"&gt;-v&lt;/span&gt; claudio-workspace:/workspace &lt;span class="se"&gt;\&lt;/span&gt;
  ghcr.io/yeyo11/claudio
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://localhost:8797&lt;/code&gt;, sign in with the owner token the container printed once (&lt;code&gt;docker logs claudio&lt;/code&gt;), then sign in to Claude in the setup assistant. Name all three volumes, or replacing the container to update starts again with empty ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Desktop app&lt;/strong&gt; (Linux x86_64, &lt;code&gt;.deb&lt;/code&gt; or AppImage):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/yeyo11/claudio/main/scripts/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As with any script piped to a shell, read it first. The app runs with your own &lt;code&gt;claude&lt;/code&gt; and &lt;code&gt;~/.claude&lt;/code&gt; login, so nothing is sandboxed and chats start in &lt;code&gt;acceptEdits&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;From source&lt;/strong&gt; (Node 22+, pnpm 10, a logged-in &lt;code&gt;claude&lt;/code&gt; on your &lt;code&gt;PATH&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;git clone https://github.com/yeyo11/claudio &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;cd &lt;/span&gt;claudio
pnpm &lt;span class="nb"&gt;install
&lt;/span&gt;pnpm dev          &lt;span class="c"&gt;# API on :8797, UI on :5181&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then: open Claudio, let the setup assistant check Claude Code, press New chat, pick a directory and write a prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  Before you expose it
&lt;/h2&gt;

&lt;p&gt;A container creates an owner token on its first start. A source install or the desktop app has authentication off until you turn it on. That is right for a port bound to &lt;code&gt;127.0.0.1&lt;/code&gt; and wrong for anything else: with auth off, anyone who reaches the port can start a chat on your account and read every transcript on the machine. The modes are &lt;code&gt;none&lt;/code&gt;, &lt;code&gt;token&lt;/code&gt; (only the SHA-256 is stored) and &lt;code&gt;oidc&lt;/code&gt; (Claudio validates a JWT; it does not log anyone in). Claudio does not terminate TLS, so put a proxy in front. &lt;a href="https://github.com/yeyo11/claudio/blob/main/docs/securing.md" rel="noopener noreferrer"&gt;docs/securing.md&lt;/a&gt; has the details.&lt;/p&gt;

&lt;p&gt;Claudio is a Claude-only fork of Agentry, an independent project, and is not affiliated with Anthropic.&lt;/p&gt;

&lt;h2&gt;
  
  
  What comes next
&lt;/h2&gt;

&lt;p&gt;The roadmap says nothing is planned right now. What is left was decided against for now, with reasons: native app-store shells, per-user push, offline use, a browser login flow for OIDC. If one of those matters to you, open an issue and tell me why.&lt;/p&gt;

&lt;p&gt;The code is MIT-licensed at &lt;a href="https://github.com/yeyo11/claudio" rel="noopener noreferrer"&gt;github.com/yeyo11/claudio&lt;/a&gt;.&lt;/p&gt;

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