
Terminal
Run named bidirectional serial, SSH, or local shell sessions from your coding agent while flashing firmware, driving AT commands, or debugging embedded boards.
Overview
terminal is an agent skill most often used in Build integrations (also Ship testing, Operate infra) that opens and drives named bidirectional serial, SSH, or local shell sessions for embedded debugging and device CLIs.
Install
npx skills add https://github.com/zhinkgit/embeddedskills --skill terminalWhat is this skill?
- Starts background interactive sessions with stable names and read/write buffers
- Three backends: serial (pyserial), SSH (OpenSSH), and local shell (PowerShell or $SHELL)
- Send plain text or hex, drain output, attach foreground line mode, then stop and clean state
- Persists sessions in `.embeddedskills/state.json` with per-session logs under `.embeddedskills/logs/terminal/`
- CLI flags override saved session state; empty `config.json` keeps credentials and ports explicit per `start`
- 3 session backends: serial, SSH, and local shell
- Session metadata stored under `.embeddedskills/state.json` in `terminal_sessions`
Adoption & trust: 1 installs on skills.sh; 340 GitHub stars; trending (+100% hot-view momentum).
What problem does it solve?
You need a stable serial, SSH, or shell session that survives across agent turns instead of losing context every time you run a one-off command.
Who is it for?
Solo builders doing firmware bring-up, UART/AT debugging, or repeated SSH into boards and servers from Claude Code or Cursor.
Skip if: Pure browser or API-only apps with no serial/SSH/local-shell needs, or anyone who only needs a single non-interactive command without session state.
When should I use this skill?
Use $terminal to open and drive a bidirectional serial, SSH, or local terminal session (default prompt from skill interface).
What do I get? / Deliverables
You get a named background terminal with buffered I/O, session logs, and cleanup hooks so the agent can interact with boards and shells predictably until you stop the session.
- Named background terminal session with buffered send/read
- Per-session log file under `.embeddedskills/logs/terminal/`
- Updated `.embeddedskills/state.json` `terminal_sessions` entries until stopped
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Embedded work first needs live device I/O during implementation—serial consoles, SSH on boards, and local shells are integration steps in Build, not a marketing or launch task. The skill wires agents to hardware and remote shells (pyserial, OpenSSH, local PowerShell/bash), which is classic build-time systems integration rather than frontend UI or docs.
Where it fits
After flashing firmware, open a named 115200 baud serial session to read boot logs and send AT commands without re-specifying COM port each turn.
SSH into a build server or edge board using a Host from `~/.ssh/config` and drive an interactive menu-based provisioning CLI from the agent.
Attach foreground line mode to an existing session while stepping through manual test prompts on a device console during pre-release checks.
Resume a background SSH session to a field gateway, drain buffered logs, and send recovery commands during an incident.
Tail `.embeddedskills/logs/terminal/` output alongside live reads when diagnosing intermittent UART failures.
How it compares
Use this for persistent agent-driven terminal sessions—not for replacing your IDE’s built-in one-shot terminal or a dedicated GUI serial monitor.
Common Questions / FAQ
Who is terminal for?
It is for solo and indie developers—and small embedded teams—who want their AI coding agent to hold interactive serial, SSH, or local shell sessions while debugging hardware and device CLIs.
When should I use terminal?
Use it during Build when integrating UART, SSH, or shell access to boards; during Ship when exercising interactive test menus or consoles; and during Operate when you need repeatable SSH or serial access to deployed devices.
Is terminal safe to install?
It runs local Python helpers, may spawn shells and SSH, and writes session state and logs under `.embeddedskills/`—review the Security Audits panel on this Prism page and pass explicit host/port/credentials on each start rather than relying on shared config.
SKILL.md
READMESKILL.md - Terminal
interface: display_name: "Interactive Terminal" short_description: "管理串口、SSH、本地 Shell 的双向交互终端会话" default_prompt: "Use $terminal to open and drive a bidirectional serial, SSH, or local terminal session." {} # terminal Claude Code skill,用于嵌入式调试中的双向交互终端会话:串口终端、SSH 交互 Shell、本地 Shell、设备 CLI、AT 命令和菜单式控制台。 ## 功能 - 启动后台交互会话,并通过会话名持续读写 - 支持串口、SSH、本地 Shell 三种后端 - 向会话发送文本或 Hex 数据 - 读取并清空会话输出缓冲 - 前台行模式接入会话 - 停止会话并清理 `.embeddedskills/state.json` 状态 ## 环境要求 - Python 3.x - 串口后端:`pyserial`,可用 `pip install pyserial` 安装 - SSH 后端:OpenSSH 客户端 `ssh` - 本地后端:Windows 默认使用 PowerShell,Linux/macOS 默认使用 `$SHELL` 或 `/bin/sh` ## 配置 ### 环境级配置 (`config.json`) terminal skill 的环境级配置目前为空对象: ```json {} ``` 交互终端的关键参数通常和具体会话绑定,应在 `start` 命令中显式传入,避免误连设备或误用凭据。 ### 会话状态 (`.embeddedskills/state.json`) 工作区下的 `.embeddedskills/state.json` 保存当前后台会话: ```json { "terminal_sessions": { "board": { "session_id": "board", "backend": "serial", "tcp_port": 23145, "pid": 1234, "log_file": ".embeddedskills/logs/terminal/board.log" } } } ``` ### 日志目录 后台进程日志保存到: ```text .embeddedskills/logs/terminal/ ``` ### 参数优先级 1. **CLI 参数** (`--port`, `--baudrate`, `--host`, `--name` 等) - 最高优先级 2. **会话状态** (`.embeddedskills/state.json` 中已启动的 `terminal_sessions`) 3. **默认值** - 最低优先级 ## 常用命令 命令示例均以当前 skill 目录为基准。 ### 启动串口终端 ```bash python scripts/terminal_session.py start serial --port COM11 --baudrate 115200 --name board ``` ### 启动 SSH 终端 `--host` 使用 `~/.ssh/config` 中的 Host 别名: ```bash python scripts/terminal_session.py start ssh --host 1380-P904 --name devboard ``` 首次连接可信设备时可追加: ```bash --accept-new-host-key --known-hosts-file <临时known_hosts路径> ``` ### 启动本地 Shell ```bash python scripts/terminal_session.py start local --name local-shell ``` ### 发送命令 ```bash python scripts/terminal_session.py send board "help" --crlf ``` 发送 Hex: ```bash python scripts/terminal_session.py send board "01 03 00 00 00 02" --hex ``` ### 读取输出 ```bash python scripts/terminal_session.py read board --timeout 1 ``` ### 前台行模式接入 ```bash python scripts/terminal_session.py attach board ``` ### 查询与停止 ```bash python scripts/terminal_session.py list python scripts/terminal_session.py status board python scripts/terminal_session.py stop board ``` ## 操作边界 - 只在需要保持交互状态时使用 terminal。 - 一次性远程命令、文件传输、端口转发仍优先使用 `ssh` skill。 - 串口扫描、日志记录、Hex 监控仍优先使用 `serial` skill。 - 未明确用途时,不主动发送会改变设备状态的命令。 - `attach` 是行模式,不等同于完整 TTY/raw 模式;全屏程序、vim、top、交互式密码输入应使用真实终端工具。 - 完成调试后执行 `stop`,避免后台会话占用串口、SSH 连接或本地 Shell。 ## 故障排查 优先检查: 1. `python scripts/terminal_session.py list` 2. `python scripts/terminal_session.py status <会话名>` 3. `.embeddedskills/logs/terminal/<会话名>.log` 4. 串口是否被占用,波特率是否正确 5. SSH Host 别名是否能被 `ssh -G <别名>` 解析 6. 是否缺少 `pyserial` 或 OpenSSH 客户端 #!/usr/bin/env python3 from __future__ import annotations import argparse import base64 import json import os import re import shutil import socket import subprocess import sys import threading import time from datetime import datetime from pathlib import Path from typing import Any STATE_DIR_NAME = ".embeddedskills" STATE_FILE_NAME = "state.json" SKILL_NAME = "terminal" def now_iso() -> str: return datetime.now().astimezone().isoformat(timespec="seconds") def workspace_root(workspace: str | None = None) -> Path: if workspace: return Path(workspace).expanduser().resolve() return Path.cwd().resolve() def state_path(workspace: str | None = None) -> Path: return workspace_root(workspace) / STATE_DIR_NAME / STATE_FILE_NAME def logs_dir(workspace: str | None = None) -> Path: return workspace_root(workspace) / STATE_DIR_NAME / "logs" / SKILL_NAME def workspace_relative(path: Path, workspace: str | None = None) -> str: ws = workspace_root(workspace) try: return Path(os.path.relpath(path.resolve(), ws)).as_posix() except ValueError: return str(path) def load_json_file(path: Path) -> dict[str, Any]: if not path.exists(): return {} try: