关于 remote-project-control
用于协调本地开发与通过 SSH 运行的服务器项目的技能。它建立项目记忆,并指导安全同步代码、管理作业、监控任务和查找制品。
主要功能
- 01读取并维护项目记忆
- 02检查本地与服务器状态
- 03通过 Git 远程同步代码
- 04协调服务器作业
- 05监控队列与日志
- 06查找远程制品
适用场景
- 01为项目建立服务器工作流
- 02将本地更改同步到执行服务器
- 03检查作业进度并查找输出
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ a-green-hand-jack/ ml-research-skills --skill remote-project-control安装后在 Claude Code 中输入/remote-project-control确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
template_manifest.jsonreferences/memory-model.mdoperations.mdssh-command-wrappers.mdscripts/remote-bashremote-cmdtemplates/agent/local-overrides.yamltemplates/docs/ops/current-status.mddecision-log.mdtemplates/infra/remote-projects.yaml详细介绍
远程项目控制
操作前 — 必须执行
- 检测范围:运行
git rev-parse --git-common-dir和--show-toplevel。在项目控制根目录布局中,<ProjectName>/和<ProjectName>/code/是相互独立的仓库——分别检查。 - 读取项目记忆:如果项目根目录中存在
memory/BRIEFING.md:memory/BRIEFING.md— 精简的项目状态快照memory/project-conventions.md— 当前约定,包括 SSH 包装器、服务器路径和此项目的范围限制
- 如果位于工作树中:先读取
.agent/worktree-status.md;将进行中的服务器状态写入该文件,而不是根目录的memory/。 - 将易变状态(队列、服务器负载、作业状态)视为需要重新核实的内容——不要依据缓存的会话记忆处理这些状态。
跳过此步骤可能导致使用过时的服务器状态、错误的环境路径,或违反项目特定的 SSH 包装器约定。
帮助用户操作一个代码在本地编辑、但实际通过 SSH 在一台或多台服务器上运行的项目。先建立项目记忆,然后协调安全的本地、Git 远程和服务器操作。
此技能中使用的术语:
local:用户的本地开发计算机,通常是运行 Agent 的 Macremote或git remote:Git 托管远程端,例如 GitHub 或 GitLab,如originserver:通过 SSH 连接的执行机器或集群,例如quest、ibex-vscode或epfl-haas
此技能名称沿用历史名称。在项目记忆和面向用户的摘要中,SSH/HPC/RunAI 执行环境优先使用 server,除非引用现有字段名称,否则将 remote 留给 Git 远程端。
当服务器执行状态需要关联到项目级实验、证据、操作或工作树状态时,将此技能与 research-project-memory 配合使用。提交作业后,将其与 run-status-monitor 配合使用,以便在无需将原始日志载入上下文的情况下进行轻量级进度检查或限定于制品的监控。
技能目录布局
<installed-skill-dir>/
├── SKILL.md
├── references/
│ ├── memory-model.md
│ ├── operations.md
│ └── ssh-command-wrappers.md
├── scripts/
│ ├── remote-cmd
│ └── remote-bash
├── template_manifest.json
└── templates/
├── infra/remote-projects.yaml
├── docs/ops/current-status.md
├── docs/ops/decision-log.md
└── agent/local-overrides.yaml
渐进式加载
- 始终阅读
references/memory-model.md - 用户想要检查、同步、运行、监控或获取制品时,阅读
references/operations.md - 在编写包含循环、shell 变量、命令替换、管道、通配符、
find、awk或多行逻辑的 SSH 命令前,阅读references/ssh-command-wrappers.md - 在目标项目中初始化记忆文件时,以
templates/为准 - 如果仓库中有
memory/,将已核实的服务器执行事实概述到research-project-memory看板中,但不要重复服务器清单。
核心原则
- 记忆是引导上下文,不是执行时的事实依据
- 稳定的共享事实应存放在仓库中;与个人机器相关的私有事实应存放在本地覆盖文件中
- 对易变状态采取行动前,先进行验证
- 在本地与服务器之间同步代码时,优先使用 GitHub/GitLab 或已配置的 Git 远程仓库;除非项目明确采用其他方式,否则不要临时自行复制源代码
- 未经用户明确批准,绝不要在服务器端使用破坏性的 git 命令
- 将
gh、git、ssh、curl和调度器/API 命令的网络访问视为一种独立的故障模式;在沙盒化的 Agent 运行时中,如果出现 DNS、超时或连接错误,应先在获得网络权限后重试,再排查凭据或配置 - 将 GitHub/GitLab API 访问与常规
gitSSH 访问分开看待:git push可能成功,但gh repo create、gh repo view或gh repo fork可能因gh未通过身份验证而失败 - 将 GitHub/GitLab API 网络访问与身份验证分开看待:在沙盒化的 Agent 运行时中,除非在获得网络权限后重新运行命令,否则
gh可能无法连接api.github.com - 将 GitHub Projects 视为 GitHub API 操作,而非 Git 远程仓库。
gh project ...需要带有project范围的令牌;如果缺少此范围,在执行项目看板命令前,使用gh auth refresh -s project刷新令牌。 - 在项目控制根目录布局中,分别检查根仓库和组件仓库;
<ProjectName>/和<ProjectName>/code/可能是相互独立的 Git 仓库,且具有不同的远程仓库和权限 - 简单的 argv 风格服务器命令使用
remote-cmd;脚本、循环或任何包含 shell 语法的命令使用remote-bash。请参阅下文的禁止使用的 SSH 模式。
禁止使用的 SSH 模式
绝不要在操作记录或 Agent 命令输出中直接拼接以下命令:
| 反模式 | 改用 |
|---|---|
ssh <alias> "cd <path> && <cmd>" | remote-cmd <alias> <repo> -- <cmd> |
ssh <alias> "<cmd> $VAR"(shell 变量) | remote-cmd <alias> <repo> -- <args> |
ssh <alias> "<cmd> | <cmd>"(管道 / 循环 / find / awk) | remote-bash <alias> <repo> <script> |
ssh <alias> "<cmd1> ; <cmd2>"(链式命令) | remote-bash <alias> <repo> <script> |
ssh A "ssh B '<nested cmd>'"(嵌套单行命令) | 通过 remote-bash 调用项目本地的 scripts/ops/ 包装脚本 |
例外:不含参数且没有 shell 语法的单词命令可以使用(ssh <alias> "pwd"、ssh <alias> "hostname")。
原因:本地 shell 会在发送 SSH 命令前展开 $VAR、~、通配符和引号,从而在无提示的情况下破坏原本要在服务器端执行的命令。包装脚本可以正确处理引号,并让操作记录保持整洁。
记忆文件
此技能管理四个用途不同的项目记忆文件:
infra/remote-projects.yaml:稳定的共享事实,例如本地仓库路径、Git 远程仓库/分支、服务器仓库映射、调度器类型、启动模式、密钥路径和安全策略docs/ops/current-status.md:当前项目阶段的工作记忆,包括活动分支、关注重点、最近已知任务、待解决问题和下一步docs/ops/decision-log.md:对稳定工作流决策原因的持久记录.agent/local-overrides.yaml:可选的私有覆盖配置,存放单个用户的机器、SSH 别名、用户名和私有路径;此文件通常应加入 gitignore
如果缺少一个或多个文件,请先使用随附模板初始化这些文件,再尝试从头推断项目上下文。
步骤 1 — 熟悉项目并加载记忆
- 检测项目根目录:
git rev-parse --show-toplevel 2>/dev/null || pwd
- 如果存在,请读取现有记忆文件:
<project-root>/infra/remote-projects.yaml<project-root>/docs/ops/current-status.md<project-root>/.agent/local-overrides.yaml<project-root>/docs/ops/decision-log.md
- 如果缺少
infra/remote-projects.yaml,请使用此技能中的模板初始化项目记忆。只询问最低限度的关键信息:
- 项目名称
- 本地仓库根目录
- 默认服务器名称
- ssh 别名
- 服务器仓库根目录
- 调度器类型
- 默认启动模式
- 环境激活命令
-
如果缺少
.agent/local-overrides.yaml,但显然需要私有覆盖项,请提出创建该文件,并建议将.agent/添加到.gitignore。 -
如果项目似乎是包含组件仓库的控制根目录,请分别检查每个相关仓库,而不要假设它们共用一个 Git 远程仓库:
git -C <project-root> remote -v
git -C <project-root>/code remote -v
git -C <project-root>/paper remote -v
一个仓库缺少远程仓库,不代表其他仓库也缺少远程仓库。
步骤 2 — 构建会话启动摘要
将已加载的文件合并为简洁的项目上下文摘要。在开展实质性的远程操作前,始终先向用户展示精简的启动摘要。
已知时,请包括:
- 项目名称
- 本地仓库根目录、当前分支、短提交哈希,以及工作树是否有未提交更改
- 默认服务器和服务器仓库根目录
- 用于同步的 Git 远程仓库名称和分支
- 调度器类型和默认启动模式
- 环境激活命令
- 关键数据、检查点、临时文件和日志根目录
- 当前关注点
- 最新已知作业
- 未解决的问题
- 下一步计划
- 任何缺失的必填字段
步骤 3 — 操作前重新验证易变状态
执行任何远程操作前,请验证自上次会话以来可能已发生变化的状态。
至少需要验证:
git rev-parse --short HEAD
git branch --show-current
git status --short
对于选定的服务器,请使用配置的 ssh_alias 和 remote_repo_root 或 server_repo_root,验证服务器端仓库及其 Git 状态:
ssh <ssh-alias> "cd <remote-repo-root> && pwd && git branch --show-current && git rev-parse --short HEAD && git status --short"
重复检查时,优先使用更安全的封装命令:
remote-cmd <ssh-alias> <remote-repo-root> -- git status --short
remote-bash <ssh-alias> <remote-repo-root> scripts/ops/status.sh
如果请求涉及提交作业或监控作业,还要验证服务器上的调度器工具以及相关日志或输出路径。
步骤 4 — 对请求分类并执行
选择以下一种流程,并遵循 references/operations.md 中的详细指南:
bootstrap:根据模板创建或修复记忆文件,并填写最低限度的必填字段inspect:比较本地与服务端的 git 状态,验证路径、环境激活状态和调度器可用性,并总结当前情况git-remote-setup:检查或创建 GitHub/GitLab 仓库、设置远程仓库、派生上游仓库、关联可选的 GitHub Projects,或准备通过 Git 远程仓库进行本地到服务端的同步sync-code:准备本地提交,通过已配置的 Git 远程仓库推送,并仅使用非破坏性的快进拉取更新服务端仓库run-job:使用服务端上下文安全地提交作业;如果需要新的可复现作业脚本,请在此技能建立环境后使用run-experimentinteractive-session:准备正确的salloc、srun或等效命令,并在服务端仓库中使用已配置的环境激活方式运行后续命令monitor:检查队列状态,并查看已配置日志根目录中的日志artifacts:定位远程检查点、输出和日志;除非用户明确要求,否则不要批量传输大型数据closeout:在会话结束时更新项目记忆
如果运行时无法直接执行 SSH 命令,仍应使用此技能:按正确顺序生成准确命令,说明前提,并保持记忆文件为最新状态。
在执行任何使用 GitHub API 的 gh 操作(包括 gh repo ... 和 gh project ...)之前,运行:
gh auth status
谨慎判断失败原因:
- 如果输出显示无法连接到
api.github.com、github.com,或提示检查互联网连接,应先将其视为网络/沙盒访问问题。在要求用户重新登录之前,先在允许网络访问的情况下重新运行同一项gh检查。 - 如果
gh auth status已获得网络访问权限,但仍报告令牌无效、缺少账户或登录失败,请停止 GitHub API 流程,并告知用户使用gh auth login -h github.com重新认证。 - 不要将这两种失败解释为仓库创建失败、Git 远程仓库失败、SSH 密钥失败或服务端问题。
对于 GitHub Projects:
- 在运行
gh project create、gh project view、gh project link、gh project item-*或gh project field-*之前,确认gh auth status显示projectscope。 - 如果缺少此 scope,请运行或让用户运行
gh auth refresh -s project。 - 如果常规沙盒中的
gh auth status失败,但启用网络和钥匙串的检查成功,应将常规检查的失败视为沙盒或 Keychain 访问问题,而非实际退出登录。 - 如果代码仓库属于项目控制根目录布局,请在根目录的
memory/project.yaml中记录 GitHub Project URL/编号。
对其他命令也采用相同的网络优先判断原则:
git fetch、git push、git pull、git ls-remote:DNS 或连接失败应先视为网络/沙盒访问问题,直到在允许网络访问的情况下重新运行后再判断。ssh <server>:主机名解析失败、超时或网络不可达,应先视为网络/VPN/沙盒连通性问题,直到在预期的网络权限和 VPN 状态下重新运行后再判断。curl、包管理器和调度器/API CLI:连接失败不足以证明凭据或服务端配置有误。
步骤 5 — 写回正确的记忆层
当新信息变得可信时,将其持久化到适当的文件中:
- 稳定的映射和策略变更 ->
infra/remote-projects.yaml - 当前分支、已知的最新服务器作业、当前重点、阻碍事项和下一步 ->
docs/ops/current-status.md - 持久的工作流依据 ->
docs/ops/decision-log.md - 用户专属的 ssh 别名、用户名和私有路径 ->
.agent/local-overrides.yaml
如果仓库也使用 research-project-memory,则只写入跨项目指针:
memory/evidence-board.md:关联EXP-###的已验证作业/运行指针memory/action-board.md:监控、获取制品、重新运行或报告等操作memory/current-status.md:最新的已验证服务器执行摘要和下一步验证事项- 工作树
.agent/worktree-status.md:与分支/工作树用途相关联的服务器运行状态
不要将易变的调度器输出或一次性的 shell 命令结果写入稳定清单。
步骤 6 — 每次重要会话结束时都进行收尾
结束前,只要会话实质性地改变了项目状态,就更新 docs/ops/current-status.md。记录:
- 用户应从哪个分支或提交继续
- 本地做了哪些更改
- 哪些内容已推送到 Git 远程仓库并拉取到服务器仓库
- 已知最新的已提交或正在运行的作业
- 值得后续检查的日志或输出路径
- 下一次会话要执行的具体操作
如果确立了新的稳定实践,请在 docs/ops/decision-log.md 中添加简短条目。
如果确立了新的项目专属 SSH/远程约定(例如新的封装别名、服务器路径、RunAI 池或调度器标志),请按 ssh 或 compute 类别将其写入 memory/project-conventions.md。服务器基础设施变更导致某项约定失效时,将其移至“已过期”,并说明原因。
如果项目有 memory/current-status.md,请用简洁的跨组件指针更新该文件,而不是复制完整的远程状态。
引导初始化目标
初始化项目时,从 templates/ 生成以下文件:
templates/infra/remote-projects.yaml-><project-root>/infra/remote-projects.yamltemplates/docs/ops/current-status.md-><project-root>/docs/ops/current-status.mdtemplates/docs/ops/decision-log.md-><project-root>/docs/ops/decision-log.mdtemplates/agent/local-overrides.yaml-><project-root>/.agent/local-overrides.yaml(需要私有覆盖项时)
保留现有文件,除非用户明确要求覆盖。