mcpField
P
paseokit

paseokit

github.com/mimukitAgent 工作流2205 次安装1 天前更新
代码仓库

关于 paseokit

paseokit 是用于协调 Git worktree 与 Paseo 工作区注册表的技能。它将登记与清理分开,清理前预览变更,并把 worktree 的创建和移除交由 gitkit 处理。

主要功能

  1. 01查看工作区注册表差异
  2. 02通过 sync 登记缺失 worktree
  3. 03清理重复及已完成条目
  4. 04调整 Paseo 的 worktree 根目录
  5. 05预览并确认清理操作

适用场景

  1. 01将已有 worktree 登记到 Paseo
  2. 02查找缺失或重复的工作区记录
  3. 03合并 PR 后移除已完成的 worktree
  4. 04检查 Paseo 应将新 worktree 放在哪里

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/mimukit/skills --skill paseokit

安装后在 Claude Code 中输入/paseokit确认已加载。

附带文件modes/align.mdmodes/clean.md

详细介绍

paseokit

Paseo 会为每个检出显示一个工作区,可以是主仓库,也可以是其下的一个 git worktree,并在每个工作区中挂接 Agent。Worktree 本身由原生 git worktree 创建:可以遵循 gitkit 的约定,使用 issuekit 的 start,也可以由你亲自操作。

Paseo 不会自行注册任何内容。 git worktree add 创建的 worktree 在经过某种方式注册之前,对 Paseo 不可见。没有可启用的发现设置,因此实际工作不会自行出现在侧边栏中。

不过,Paseo 确实会自行修剪一项内容,具体如版本衔接处的目录修剪所述:它会归档目录已不存在的所有活动行。除此之外,它不会归档任何内容:它从不合并重复行,从不判断工作是否已合并,也从不触碰目录仍存在的行。因此,剩余的不同步情况包括从未显示的工作、重复项,以及仍留在磁盘上的已完成 worktree。

paseokit 只负责这项对账,并按方向拆分:sync 添加缺失项,clean 移除已完成项——包括重复行,以及工作已合并的 worktree。每种操作都仅针对你运行它的项目,除非你要求处理整台机器;无论哪种操作,运行两次后第二次都不会造成任何变化。

这种按需设计是刻意为之。只有运行 sync 时,worktree 才会出现在 Paseo 中,而不是在创建时出现。这是经过权衡的选择:不使用 git hooks、调度器或后台进程,也不会向任何仓库写入内容。

paseokit 不会越过的界限

Git 管理 worktree;Paseo 管理行。 paseokit 从不运行 paseo workspace create --isolation worktree 来开展实际工作,从不虚构路径,也从不让 Paseo 创建分支。创建和移除 worktree 都使用遵循 gitkit 约定的原生 git worktree,因此没有安装 Paseo 的机器也会运行完全相同的命令。

paseokit 在更高一层操作,只处理 Paseo 独自掌握的信息:注册表行,也就是此路径在此项目下存在一个工作区,且具有这个标题。

有两点值得明确说明:

  • paseo workspace archive 不仅操作注册表。 它会归档工作区中的所有 Agent,结束其中的所有终端,并且在 Paseo 认定该目录归自己所有、且没有其他活动行指向它时,删除工作区对应的 worktree 目录。只有行可以恢复;目录不行。排入任何归档操作之前,请先阅读归档调用会删除目录。
  • 移除 worktree 仍然是 gitkit 的职责。 paseokit 通过 gitkit 执行拆除,绝不会用归档代替它,因为会删除内容的归档,就是一次从未预览过的删除。
  • clean 是唯一会触及磁盘的模式。 它判断哪些 worktree 已完成,并执行拆除;但在安装了 gitkit 时,它不会自行运行 git worktree remove,也绝不虚构路径或分支规则。判断由 paseokit 做出;移除仍由 gitkit 执行。

paseokit 绝不会触碰跟踪系统。 它会读取 issue 和 pull request 来生成标题并判断结果;但绝不会关闭 issue、移动标签或编辑 pull request。如果 pull request 已合并但对应的 issue 仍未关闭,这属于跟踪系统不同步,paseokit 会指出这一点,并转交给 issuekit 的 close。

触发时机

  • list。“paseo 认为我的工作树有哪些?”“为什么侧边栏里没有我的工作树?”“显示一下差异。”只读。
  • sync。“将我的工作树同步到 paseo。”“注册我的工作树。”默认仅作用于当前项目;“全部同步”“同步所有内容”或“我的所有项目”会将范围扩大到整台机器——参见范围。
  • clean。“清理 PR 已合并的工作树。”“删除已合并的工作树及其会话。”“清理侧边栏里的无效条目。”“我的机器上全是已经合并的工作。”这是唯一会归档条目或从磁盘删除内容的模式;它会先列出所有计划归档和删除的内容,然后将归档作为一组确认,并对每项删除分别确认。
  • align。“paseo 应该把新工作树放在哪里?”“让 paseo 使用我的工作树根目录。”

**如果无法确定模式,先从 list 开始。**它是只读的,并会指出 sync 会处理哪些条目,所以作为第一步总不会错。

sync 与 clean。sync 只会添加内容:它会注册、重命名标题并恢复条目,但绝不会归档条目、合并重复项或触碰磁盘。所有移除操作,从归档无效条目到删除已合并的工作树,都属于 clean。clean 会在一个列表中预览这两类操作,并在触碰任一类内容前征求确认;对于磁盘操作,它还会先证明拉取请求已合并,工作树才会出现在列表中,并遵循 gitkit 的移除规则:每个工作树都要单独确认。

**不属于此技能:**创建工作树(gitkit)、关闭 issue 并在合并后拆除内容(issuekit close),或驱动 Agent,因为 paseo run、attach、send、logs 和计划功能都直接属于 paseo CLI。paseokit 负责注册表维护,而不是 Agent 操作。

预检(所有模式)

paseo status        # CLI installed? daemon running and reachable?
  • 未安装 paseo → 这台机器没有 Paseo,因此无需协调。请如实说明这一点,然后停止。不要改用其他方式:没有 Paseo,工作树也已处于正常状态,工作流中的其他内容也不依赖此技能。
  • 守护进程未运行或无法访问 → 指出 paseo start 并停止。未经请求,不要在他人的机器上启动守护进程。
  • 缺少 gh 或未通过身份验证 → 标题会退化为分支名称,跟踪器列会显示“未知”。list、sync 和 align 的其他功能不受影响。clean 的磁盘操作是例外,会停止执行,因为它的前提是已证明合并,而只有跟踪器能证明这一点;不过注册表清理仍会在单独预览并确认后运行。
  • paseo 标志或子命令被拒绝 → CLI 更新很快。在断定某项操作不受支持之前,先检查 paseo <command> --help,并对照下面的两个版本号,再判断是否是 CLI 的问题。目标是实现约定的结果,即注册条目、归档条目、设置标题;具体标志的写法并不重要。

所有依赖版本的事实都列在版本差异中。在执行写入操作前,请根据更新版本重新核对该列表。

分别读取两个版本号。paseo status 会将 CLI 和 Daemon Version 分别列出,它们可能不一致:CLI 会在下次安装时升级,而守护进程会继续运行启动时所用的代码,直到执行 paseo restart。CLI 会显示自身版本支持的所有标志,因此某个标志可能在本地解析成功,却仍被守护进程拒绝。当两个版本号不同时,应优先将写入操作被拒绝视为版本不匹配,并说明这一点。**不要运行 paseo restart 来消除版本差异。**重启会终止所有正在运行的 Agent,包括正在读取本文的 Agent。

版本界限

已针对 Paseo CLI 0.8.0 和守护进程 0.8.0 验证。本技能中所有依赖 Paseo 版本的事实都列在此处,其余部分按名称引用这些条目,不注明自身版本。守护进程报告了更新版本时,请重新检查每个条目,再信任任何写入操作,并在此处统一更新。

  • 目录清理。 守护进程启动时以及此后每五分钟会执行一次协调。如果某个活跃条目的目录已不存在,就将其归档,原因设为 directory_missing,除此之外不做其他操作。此功能于 0.7 引入。
  • 所有权标记。 isPaseoOwnedWorktree 使用与归档删除操作相同的 <hash>/<slug> 路径测试,并且每次协调都会刷新该标记。0.7 之前采用较宽松的检查来设置此标记,因此它可能与删除操作的判断不一致。
  • project 组。 create、ls、rename 和 delete 均已实现。对于其他动词,安全探测方式是使用守护进程会接受并执行、但不会匹配到任何内容的命令,例如使用一个不存在的格式正确的 id。
  • 无法取消归档。 workspace 子命令只有 create、ls、rename 和 archive,没有其他子命令。
  • daemon.autoArchiveAfterMerge 的限制。 该功能仅在拉取请求已合并、工作区干净、没有任何提交领先于 origin,且工作树由 Paseo 创建时才会执行。这些限制于 0.7 引入。

Paseo 对工作区的了解

有两个数据面,两者的差异至关重要。

CLI 列表是精简投影。 paseo workspace ls --json 只返回 workspaceId、project(显示名称,而非 id)、name、isolation 和 cwd。它只列出活跃工作区。这些信息足以回答一个问题:是否有任何活跃条目指向此路径;除此之外别无用途。

paseo project ls --json 会解析项目 id。 它会返回每个活跃项目的 projectId、name、kind 和 path,因此现在可通过 CLI 获取 --project 要求的 prj_… id。按 path 匹配。优先使用此命令;只有在命令不存在或守护进程拒绝执行时,才回退到状态文件。

状态文件包含两个列表都未公开的信息。 这些文件位于 ~/.paseo/projects/:

文件独有信息用途
workspaces.jsonbranch、title、kind、projectId、createdAt、archivedAt、isPaseoOwnedWorktree、worktreeRoot、mainRepoRoot墓碑记录、重复项排序、重命名安全检查、删除预估
projects.json每个项目的 projectKey 和 archivedAt检测孤立项目,以及作为 project ls 的回退方案

主检出中的 kind 为 local_checkout,工作树中的 kind 为 worktree。

这是文档记录的数据界限,并非稳定 API。 workspace ls 仍然不包含 branch、title、createdAt 和任何已归档条目,因此读取 workspaces.json 仍不可避免,并非捷径。将这两个文件都视为只读:paseokit 会解析它们,并通过 CLI 执行写入,绝不直接写入这些文件。

如果任一文件缺失、无法读取或结构异常,所有写入模式都必须降级为只读,并说明具体是哪个文件以及原因。绝不猜测 id。

工作区只包含标题和固定标记,不包含其他信息;没有关联的问题,也没有状态字段。因此,这里没有与 link 式信息增强对应的机制;标题就是全部信息。

archive 调用会删除目录

paseo workspace archive <workspace-id> 会执行三个步骤,只有第一步是修改注册表:

  1. 它会归档工作区拥有的所有 Agent,无论是运行中的还是已存储的,并终止其中的所有终端。它不会征求同意,也不会因为有 Agent 正在运行而拒绝执行。
  2. 它会归档工作区记录。这一步可以撤销。
  3. 接着,如果没有其他活动行指向该目录,且该目录通过下方的所有权测试,它就会尝试删除后端目录。删除操作会运行 git worktree remove --force,然后移除该目录。Git 不会还原其中任何内容。

删除操作会进行路径测试,路径结构就是全部测试条件。 守护进程只接受 <worktrees.root>/<hash>/<slug> 形式的目录,其中 <hash> 是主检出绝对路径的短 base-36 摘要。gitkit 的约定是 $WORKTREE_ROOT/<repo>/<branch>,其中保存的是仓库名称,而守护进程要求的是哈希,因此 gitkit 工作树无法通过测试,删除操作会抛出 Refusing to delete non-Paseo worktree。只有 Paseo 自行创建的工作树才能通过。 守护进程会捕获该异常,将其记录为警告,并报告归档成功,因此在 CLI 中看不到删除被拒绝的提示。

根据版本衔接部分的所有权标志,isPaseoOwnedWorktree 可以预测是否会删除:workspaces.json 中为 true 表示会删除磁盘目录,为 false 表示只归档注册表。不过,在排队归档前仍要确认路径结构,因为存储的值是否准确取决于最近一次检查:父目录名称是仓库名称的目录属于 Git 工作树;父目录名称是不透明哈希的目录则属于 Paseo。

以下三条规则都必须遵守:

  • 只要工作树位于哈希目录下,就将归档视为磁盘删除。 这是守护进程唯一会删除的结构。预览时应将其视为删除,而不是注册表修改。
  • 工作树存在未提交更改也无法保护它。 守护进程会向 git worktree remove 传入 --force,因此,Paseo 创建的工作树中未提交的工作会随目录一起消失。这就是为什么 clean 会自行确认工作树干净,而不是指望该调用拒绝执行。
  • 运行中的 Agent 不会阻止调用。 归档操作会停止并归档该 Agent,还会终止工作区中的所有终端。因此,busy 检查是 paseokit 自身的防护措施,并非 CLI 提供的安全网。

工作区拆除命令会在删除前运行,并以目录所在路径为目标。对于配置了拆除脚本的工作区,每次归档 Paseo 所有的工作树时都会运行该脚本。如果拆除命令失败,目录删除会被取消,而记录会保持归档状态,此时工作区与其目录就会不一致。

注册表还有一个问题

workspace create 不是幂等的。 对同一路径调用两次完全相同的命令,会悄无声息地生成两条 cwd 相同的记录。因此,注册前的每项存在性检查都至关重要,而非仅仅是优化;检查时还必须考虑已归档的记录,否则下方的墓碑规则会悄无声息地失效。

模式:list

只读。不做任何更改,不提出任何问题;状态不明确时,应首先使用此模式。

合并三个来源,并按绝对路径进行匹配,这是 git 和 Paseo 共同记录的唯一键:

paseo project ls --json                     # live projects, each with a projectId and a path
git -C "$REPO" worktree list --porcelain    # per live project
paseo workspace ls --json                   # active rows
paseo ls -g --json                          # agents across every directory, each with a cwd and a status

在判定任何结果之前,先应用两个筛选条件:

  • HEAD 不可解析为符号引用时,不显示该行。 porcelain 记录包含 branch refs/heads/<name> 或 detached;detached 记录永远不会注册。这与在工作树中运行 git symbolic-ref -q HEAD 得到的结果相同,也正是防止 debugkit 的 bisect 临时目录出现在侧边栏中的机制。
  • Agent 的 cwd 值会以波浪号缩写形式返回(~/projects/skills)。请先展开路径再进行比较,否则所有 busy 检查都会静默地返回 false。

然后为每一行给出判定结果:

判定结果含义修复方式
busy非空闲 Agent 的 cwd 位于此工作区内保留
registered工作树存在,且恰好有一行活动记录指向它无需处理
unregistered工作树存在,但没有任何记录指向它sync
orphaned有一行活动记录指向一个已不存在的路径等待;守护进程会在五分钟内将其归档
duplicate两行或更多活动记录共用一个 cwdclean
tombstoned工作树存在,但其唯一记录已归档sync,需确认
unknown repo$WORKTREE_ROOT 下的工作树所属仓库是 Paseo 从未见过的sync,需确认
stray project某项目的 rootPath 是工作树,而非主检出目录报告此情况;确认后,运行 paseo project delete 将其移除
reapable拉取请求已合并、议题已关闭、工作树干净clean

只要存在 busy 行,就将其排在最前面。 对这些行采取操作会中断正在进行的工作。

orphaned 行是时序造成的临时状态,详见目录清理。守护进程会在自己的处理周期中将其归档,因此请报告此状态并说明何时会消失。只有用户要求立即清除时,才将其排入归档队列。

stray project 有明确的特征:它的 projectKey 与某个真实项目的 projectKey 相同,而它的 rootPath 位于 $WORKTREE_ROOT 下。这是未使用 --project 进行注册所产生的结果;由于其下方的记录可能已归档,因此它不会显示在 workspace ls 中。

交接

在本技能中撰写的所有交接内容都使用程序性语体:每句话只给出一条指令,使用主动语态和现在时,不使用比喻。

变更内容。 没有变更。明确说明这一点。

所在位置。 给出一个表格,列出各判定结果的数量。

下一步。 任何行的判定结果为 unregistered 或 tombstoned 时,优先选择 sync。任何行的判定结果为 duplicate 或 reapable 时,优先选择 clean。两种情况同时出现时,先选择 clean,这样 sync 就会将记录注册到一个已清除失效记录的注册表中。如果所有行的判定结果都是 registered,请明确说明侧边栏已与磁盘内容一致。

模式:sync

此模式用于添加,并且从设计上可安全地重复运行。它会注册、重命名和恢复记录;绝不会归档任何记录,也绝不会触碰目录或分支。任何形式的移除,包括归档失效记录,都应交由 clean 处理。

范围

sync 有两种范围,请求中的措辞决定使用哪一种:

  • 默认使用项目范围。 使用 git rev-parse --path-format=absolute --git-common-dir 从当前目录解析主检出,然后仅对该项目执行操作:磁盘上的工作树,以及 workspaces.json 中 projectId 与其匹配的注册表行。其他所有项目的行和工作树都保持不变,也不报告。
  • sync all 是整台机器范围。 用户会通过“sync all”“sync everything”或“all my projects”提出此请求。它涵盖 paseo project ls --json 返回的所有项目;由于下面的未知仓库遍历本质上是对整台机器进行扫描,因此只有此范围会执行该遍历。

如果当前目录不在 Git 仓库中,项目范围就没有对应对象。 请说明这一点,并指出 sync all 可用于扫描整台机器。不要擅自扩大用户未要求的范围。

先运行 list 的联接操作,并按所选范围筛选,因为 sync 只会对这些判定结果执行操作。

直接执行,无需确认

以下所有操作都已证明不会造成破坏,因此无需询问确认。

注册每个 unregistered 工作树:

paseo workspace create --isolation local --path "$WT" \
  --project "$PROJECT_ID" --title "$TITLE" --json

即使目标是工作树,--isolation local 仍是正确的设置:它会指示 Paseo 接管 $WT 处的检出,而不是新建一个。Paseo 会自行检查 Git,并记录 kind: "worktree"、分支和 mainRepoRoot。

必须指定 --project。 如果不指定,Paseo 会在工作树路径下创建一个重复的项目,也就是上文提到的 stray project。通过运行 paseo project ls --json 并匹配主检出的 path 来解析 $PROJECT_ID;如果找不到,则在 projects.json 中查找 rootPath 匹配且 archivedAt 为 null 的项目。如果无法解析 id,则跳过注册并报告原因。 切勿为了绕过缺失的 id 而在未指定 --project 的情况下注册。

报告每个 duplicate 集合,并将其交由 clean 处理。将每个 orphaned 行报告为可自我修复。sync 会同时指出这两类情况,以便清楚显示偏差;它不会归档任何内容。

重命名标题由 Paseo 自动生成而非由人工设置的行:

paseo workspace rename "$WORKSPACE_ID" "$TITLE"

标题格式为 #<n> · <issue title>;从 issue-<n>-<slug> 分支中解析 <n>,并通过 gh issue view "$N" --json title 读取标题。如果 gh 无法使用,或分支名称不含 issue 编号,则退回使用分支名称。

仅当行的 title 为 null 或与分支名称完全一致时,才重命名该行。 其他任何标题都视为由人工设置,应保持不变,并报告为不一致,而不是覆盖。

跳过所有 busy 项,并在报告中注明 Agent 的短 ID。切勿重命名含有运行中 Agent 的工作区。

各项都需单独确认一次

这两项都会超出用户请求的范围,因此都要停下来询问。

未知仓库(仅限 sync all,参见范围)。遍历 $WORKTREE_ROOT/*,通过 git -C "$CANDIDATE" rev-parse --git-common-dir 将每个候选项解析到其主检出,并收集 Paseo 从未见过的仓库。列出这些仓库,然后在一次确认后先创建项目:

paseo project create "$REPO" --json

该调用会直接返回新的 prj_… ID。使用该 ID 注册仓库的主检出,然后注册其工作树;每项都通过 workspace create --isolation local --project "$PROJECT_ID" 完成。

Paseo 自己的工作树无需特殊处理。它们已经有对应记录,其 --git-common-dir 会解析到 Paseo 已知的仓库,因此不会进入未知仓库类别,也无需猜测哈希目录模式。

墓碑记录。 归档记录会阻止重新注册:有人刻意归档了该工作区,若在下一次运行时重新添加,就会撤销他们刚完成的整理。列出这些墓碑工作树,在一次确认后恢复它们;否则保持原样。

没有 paseo workspace unarchive,参见版本分界。“恢复”墓碑记录意味着为同一路径创建一条新记录,因此归档记录仍保留在 workspaces.json 中,恢复后的工作区会获得新的 wks_… ID。执行时要说明这一点;不要声称记录已复活。

移交

发生了什么变化。 说明你执行的范围:当前项目或整台机器。分别报告注册、恢复和重命名的数量。逐项说明跳过的内容及原因。将 busy 跳过项放在最前面,因为它们涉及正在进行的工作。

变更落在哪里。 只涉及 Paseo 的注册表,且仅涉及新增或重命名的记录。明确说明没有归档任何记录,也没有更改任何目录、分支或 git 注册,并说明侧边栏会在几秒内反映这些新记录。

后续操作。 按以下优先级处理:

  • 存在任何 busy 项 → 指明路径和 Agent。告知用户等该 Agent 完成后再次运行 sync。
  • 存在任何 stray project → 指明项目,并说明修复方式是 paseo project delete "$PROJECT_ID"。此处不要运行该命令。 该命令会删除项目及其下的每个工作区,因此应通过 clean 的预览和确认来执行,而不是放在 sync 可直接执行的环节中。
  • 存在任何 duplicate 或 reapable 项 → 引导至 clean,由其在一次操作中合并重复记录,并通过 gitkit 拆除合并后的工作树。
  • 追踪器状态不一致 → 引导使用 issuekit 执行 close <n>,否则使用 gh issue close <n>。
  • 没有剩余问题 → 说明注册表与磁盘一致,然后停止。这不值得反复执行。

模式

clean 和 align 的模式正文分别存放在 modes/ 下的一个文件中。根据触发条件选择模式,读取对应文件并遵循其中的说明。本文件中的内容适用于所有模式,不会在模式文件中重复说明。list 和 sync 保留在此处,因为 list 中的联结方式和判定结果构成了 sync 与 clean 操作时使用的术语体系。

  • 模式 clean → 阅读 modes/clean.md,然后遵循其中的说明。
  • 模式 align → 阅读 modes/align.md,然后遵循其中的说明。

备注

  • paseokit 仅在本机运行,且始终是可选的。 如果机器上没有 Paseo,就什么也不做;工作流中的其他任何部分都不得依赖它。gitkit、issuekit 等绝不会调用它,否则在没有该工具的机器上都会出错。它是你可以运行的泵,而不是链条中的一环。
  • orcakit 是同级工具,不是前置工具。 它会将相同的工作树同步到 Orca;Orca 的模型恰恰相反:Orca 会自行发现工作树,并且对它们一无所知,因此 orcakit 负责补充信息和清理,而 paseokit 负责注册和回收。两者都仅在本机运行,且都是可选的,彼此绝不会调用对方。
  • 工作树信息由 gitkit 管理。 路径约定 $WORKTREE_ROOT/<repo>/<branch> 和 issue-<n>-<slug> 分支语法仅在此处作为没有 gitkit 的机器上的声明式可移植性回退方案出现。分支命名、基础引用解析和拆除规则都由 gitkit 管理;本文件中任何其他关于 gitkit 的信息副本都是错误。
  • 跟踪器信息由 issuekit 管理。 paseokit 会读取 issue 和拉取请求的状态来生成标题和判断结果,但不会写入任何内容。
  • 安全的操作直接执行;扩大范围和破坏性操作则需要询问。 list 绝不询问。sync 会不经提示地执行新增操作,只会在两种注册用户未指定内容的操作前停止。clean 会在执行任何操作前列出所有计划归档和删除的内容。它会针对归档询问一次,因为用户应该看到哪些内容会从侧边栏中消失;并且会针对每次删除分别询问,因为 gitkit 的移除规则会将每个工作树视为独立决定,而被移除的工作树是这里唯一无法通过 git 恢复的东西。
  • 不要因为某个 paseo 命令的名字听起来安全,就认为它安全。 archive 会删除目录,而 project delete 会连同项目下的所有工作区一起删除。查看 paseo <command> --help,了解命令会影响哪些内容;并且应将单行说明视为概要,而非保证。
  • 绝不要写入 ~/.paseo/projects/*.json。 paseokit 会读取这些文件中未通过列表展示的字段,并且只会通过 paseo 写入。手动编辑状态文件后,必须重启守护进程才能生效,而重启会终止所有正在运行的 Agent。
  • 无法使用 shell? 那就无法访问 paseo CLI、git 或 gh。根据用户提供的信息进行判断,并以代码块形式打印确切的命令供用户运行;绝不要声称已注册或归档你无法实际执行的工作区。

评论

支持 Markdown