agentleFS
MarioJamesMarioJames/skill-foundry/skills/persistent-ssh-ops/SKILL.md

persistent-ssh-ops

Skill1 starsChanged 4 days agoApache-2.0View on GitHub

通过可复用的 TTY SSH 会话操作远程服务器;用于远程维护、部署、排障和多步验证,按请求初始化本地命名主机配置。

The file

Show its rules and text

We split this skill into the rules it gives an agent

15 rules. About 0 are common, 9 are distinctive, and 6 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈9

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    When the user requests initialization or an update of the local server profiles, use profile-setup.md.

    line 14
  2. Distinctive:

    Before selecting or resolving a target, run the bundled scanner:

    line 20
  3. Very specific:

    Do not reconstruct ssh from server_profiles[].uri.

    line 39
  4. Very specific:

    If the requested target is neither a registered profile nor a scanned shell alias, try it as an OpenSSH Host alias.

    line 41
  5. Very specific:

    Use only a scanner-returned alias matching ^[A-Za-z_][A-Za-z0-9_.-]*$.

    line 55
  6. Distinctive:

    Start the registered profile runtime, resolved OpenSSH alias, or legacy login-shell command above in a TTY-capable execution tool:

    line 59
  7. Distinctive:

    Before edits or service changes:

    line 80
  8. Very specific:

    Check whether docker compose or docker-compose is installed before choosing one.

    line 86
  9. Very specific:

    Run native config validation such as nginx -t, xray run -test, or docker compose config.

    line 90
  10. Distinctive:

    Verify service status, listeners, bounded recent logs, and an end-to-end smoke test.

    line 91
  11. Distinctive:

    Keep secrets out of commands likely to be echoed, shell history, transcripts, and reports.

    line 96
  12. Distinctive:

    Do not expose private keys, tokens, seeds, passwords, connection strings, or unredacted service configuration.

    line 99
  13. Distinctive:

    Treat host-key changes as a security event.

    line 100
  14. Very specific:

    After final verification, send exit and confirm the execution session ended.

    line 104
  15. Distinctive:

    Never turn off host-key checking to recover from an unexpected fingerprint change.

    line 118

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Persistent SSH Ops

Core rule

Open one TTY-backed SSH session per target host and reuse it for the complete remote workflow. Use local commands only for discovery and preparation; send remote commands through the persistent session.

Local profile setup

When the user requests initialization or an update of the local server profiles, use profile-setup.md. Ordinary remote work uses existing profiles or OpenSSH aliases without changing local shell configuration.

Named server profiles use zsh on Debian/Linux as well as macOS. The bundled runtime requires zsh and jq 1.7+; profile discovery loads the configured login shell, which must be zsh with the initializer's .zshrc source block for these profiles. Inspect command -v zsh, command -v jq and the configured shell first; changing the login shell or installing zsh requires authorization.

Discover and resolve the target

Before selecting or resolving a target, run the bundled scanner:

bun <skill-directory>/scripts/scan-hosts.ts

Resolve the script path relative to this SKILL.md, not the current project directory. The scanner starts the user's configured login shell in login and interactive mode and returns two separately filtered sources:

  • server_profiles: names and password-free ssh:// URIs loaded from ~/.config/zsh/servers.json;
  • host_aliases: legacy direct ssh, mosh, and autossh aliases.

Treat both fields as runtime-only local context. Never copy scanner output into the skill, repository, memory, or final report. Prefer an exact server_profiles[].name match over a legacy alias with the same name. Never inspect or report stored passwords. runtime_status is ok, missing (confirmed absent JSON), or not_applicable (bash alias discovery). Invalid configuration, an unloaded runtime, a malformed discovery stream, or a failing login shell causes a nonzero exit; do not treat these as an empty host list.

For a registered profile, use only a scanner-returned name matching ^[a-z][a-z0-9_]*$ and start the installed runtime directly:

"$HOME/.config/zsh/server-runtime.zsh" <exact-profile-name>

Do not reconstruct ssh from server_profiles[].uri; doing so would bypass the profile's password/key behavior. The runtime command must be started with a TTY for a reusable interactive session.

If the requested target is neither a registered profile nor a scanned shell alias, try it as an OpenSSH Host alias. Inspect its resolved, non-secret connection shape without connecting:

ssh -G <host-alias> | sed -n '/^hostname /p; /^user /p; /^port /p; /^proxyjump /p; /^identityfile /p'

Report identity-file paths only; never print private-key contents. When the target remains ambiguous after scanning, ask for the host alias. Do not guess from previously used machine names.

For a scanned legacy shell alias, start the exact safe alias name through the same login shell used by the scanner:

"$SHELL" -lic '<exact-scanned-alias>'

Use only a scanner-returned alias matching ^[A-Za-z_][A-Za-z0-9_.-]*$. Do not use eval, do not execute host_aliases[].command directly, and do not accept arbitrary shell text as an alias.

Open and reuse a session

Start the registered profile runtime, resolved OpenSSH alias, or legacy login-shell command above in a TTY-capable execution tool:

{
  "cmd": "ssh <host-alias>",
  "tty": true,
  "yield_time_ms": 1000,
  "max_output_tokens": 12000
}

Record session_id -> host -> current remote directory, then send every remote command through that session's stdin. Use one persistent session per host when several hosts are in scope.

Establish context immediately:

printf 'host=%s user=%s cwd=%s\n' "$(hostname)" "$(whoami)" "$PWD"

Remote workflow

Before edits or service changes:

  • Inspect current state with project-appropriate commands such as git status, docker ps, docker compose ps, systemctl status, ss -lntp, and service config tests.
  • Resolve the actual config, unit, compose, and deployment paths instead of assuming conventional locations.
  • Back up risky configuration before modifying it.
  • Preserve unrelated dirty files and live changes.
  • Check whether docker compose or docker-compose is installed before choosing one.

After a change:

  • Run native config validation such as nginx -t, xray run -test, or docker compose config.
  • Verify service status, listeners, bounded recent logs, and an end-to-end smoke test.
  • Reconnect and verify final state if a restart interrupts SSH.

Command hygiene

  • Keep secrets out of commands likely to be echoed, shell history, transcripts, and reports. Prefer protected environment injection or root-owned files with minimum permissions.
  • Bound logs and avoid leaving foreground tails or monitors attached.
  • Quote heredocs carefully when transferring multi-line configuration.
  • Do not expose private keys, tokens, seeds, passwords, connection strings, or unredacted service configuration.
  • Treat host-key changes as a security event. Stop and report the mismatch; do not bypass verification with permissive SSH options.

Close the session

After final verification, send exit and confirm the execution session ended. If necessary, send EOF; if a foreground process blocks logout, interrupt only that process, then exit. Leave a session open only when the user explicitly requests it, and report why it remains.

Reporting

Report the resolved host identity, important files changed, validation commands, concrete outcomes, and whether every SSH session was released. Redact authentication material and secret-bearing values.

Gotchas

  • systemctl show -p LoadCredential 的复杂属性即使以 root 执行或通过管道读取,也可能显示 [unprintable];这不能证明配置缺失或权限不足,不可解析为空值。核验此类 a(ss) 凭据属性时,使用 busctl --json=short get-property org.freedesktop.systemd1 <unit-object-path> org.freedesktop.systemd1.Service LoadCredential,按预期来源核对 JSON 的 type 与 data 元组。对象路径从 systemd 单元路径编码规则或 manager 的 GetUnit 获取,不盲目拼接。真实只读验证先执行 busctl --json=short call org.freedesktop.systemd1 /org/freedesktop/systemd1 org.freedesktop.systemd1.Manager GetUnit s <unit-name>,再查询返回的对象路径;此结构化查询路线已在本机非 root 条件下验证。不要将凭据内容写入日志。
  • A local listener or green service status does not prove the service is reachable externally.
  • Automatic JSON password authentication disables keyboard-interactive and refuses effective ProxyJump/ProxyCommand connections. Key authentication retains proxy support. See profile-setup.md for supported prompts and identity paths.
  • A registered profile must be executed through server-runtime.zsh; its URI is discovery metadata, not an executable command.
  • A host alias may use ProxyJump, a non-default port, or several identity files; inspect ssh -G before reproducing the connection manually.
  • Repeated one-shot SSH commands lose shell state, current directory, and interactive diagnostics; reuse the TTY for multi-step work.
  • Never turn off host-key checking to recover from an unexpected fingerprint change.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.