SuperAPI AI 工具集

scratch

编程与开发

查看项目

更新于 10-15 09:50

技能介绍

用途

Scratch 用于探索和理解一个已经存在的项目。它的目标不是静态阅读代码,而是通过编写并实际运行脚本来走查项目的关键模块,让用户通过真实执行建立对代码库的心智模型。

它面向的是「理解你已有的东西」,即以安全、探索性的方式接触真实代码。如果用户想评估某个新东西是否值得采用,应改用 try 技能。

触发方式

用户可能会说类似的话:

  • scratch this project
  • scratch this project — focus on the auth system
  • help me understand how this codebase works
  • walk me through the internals
  • how does the payment module actually work?
  • scratch around in the data pipeline

用户还可以选择性地提供:

  • 要重点关注的特定模块或子系统
  • 想回答的问题(例如「这里的缓存是怎么工作的?」)
  • 某个约束(例如「我只关心 API 层」)
  • 展示想追踪行为的截图

工作流程

阶段 0:准备工作区

确认当前位于一个已有项目中:查找 git 根目录、package.json、pyproject.toml、Cargo.toml、go.mod 等。如果不在项目内,告知用户并停止。

在项目根目录创建 .scratch/。如果 .gitignore 中尚未包含 .scratch/,建议添加。

安全规则:.scratch/ 中的脚本不得修改生产代码。它们以只读方式导入并演练模块。不得写入项目数据库、不得改动配置文件、不得在 .scratch/ 之外产生副作用。

工作区结构:

<project-root>/
└── .scratch/
    ├── 01-<module>.{ts,py,js}
    ├── 02-<module>.{ts,py,js}
    ├── ...
    ├── 99-compose.{ts,py,js}
    └── Tutorial.md

阶段 1:提炼

目标:识别项目的关键原语、模块和子系统。

如果当前会话中可用 distill 技能,则用它生成原语清单——一份包含 5-8 个关键模块/子系统的简明列表,每项附一行描述。这是一次初步识别,不是完整的迭代式提炼。把用户陈述的目标或角度作为上下文传入,并将 distill 的输出作为探索计划。

如果 distill 技能不可用,则进行人工侦察,按以下顺序阅读:

  1. 入口点:主文件、CLI 处理器、路由定义、index.*。
  2. 包清单:依赖、脚本、导出。
  3. 源码树:了解整体形态,例如 ls -R src/ | head -40 或等价命令。
  4. 公共 API:阅读主要入口点,看项目对外暴露什么。
  5. 测试:阅读 2-3 个测试文件,测试能揭示作者的心智模型。

侦察后形成一份心智清单(先记住,暂不写出):列出各模块及其一行说明,以及它们如何连接。如果用户给出了特定角度(如「缓存是怎么工作的?」),则筛选出相关模块;否则覆盖最重要的 5-8 个模块。

阶段 2:探索脚本

目标:每个原语或关键模块边界对应一个脚本,每个脚本自包含且可运行。

脚本结构示例:

// MODULE: <Name>
// WHAT: <one-line description>
// EXPECT: <what should happen when you run it>
// ENTRY POINT: <file:line in the real codebase>

<import from the project's own modules>
<exercise the module with clear inputs>
<print/assert the result>

// FINDINGS:
// - <what you learned about how this works>
// - <surprising internal behavior>
// - <connections to other modules>

探索脚本的规则:

  • 每个文件只针对一个模块,不演练多个子系统。
  • 从实际项目导入——这些脚本演练真实代码,而非 mock。对于编译型语言或无法直接导入的情况,改为调用项目的 CLI 或 API。
  • 写完每个脚本后实际运行它,捕获 stdout/stderr。
  • 如果失败,进行调试。失败本身也是有价值的信号,记录到 FINDINGS 中。
  • 为每个模块记录真实代码库中的入口点(file:line),告诉用户从哪里开始阅读。
  • 使用数字前缀表示阅读顺序:01-、02-、03- 等。
  • 匹配项目的语言和运行时。

每个脚本运行后更新心智模型。如果发现意外情况,调整剩余脚本的计划。

阶段 3:组合脚本

目标:把 2-4 个模块串联起来,演示一条贯穿代码库的真实工作流。

// COMPOSITION: <what this demonstrates>
// MODULES USED: 01, 03, 05
// SCENARIO: <realistic workflow through the codebase>

这展示项目内部实际如何连接。组合脚本应端到端追踪一个真实的用户可见操作——例如一个请求进来、被校验、访问数据库、返回响应的全过程。

如果用户提供了特定场景、问题或截图,组合脚本必须针对它。如果没有,则追踪探索过程中浮现出的最具代表性的端到端工作流。

阶段 4:Tutorial.md

编写 .scratch/Tutorial.md,结构如下:

  • 标题与一行架构摘要
  • Architecture Overview:2-3 句话,说明心智模型与各部分如何组合
  • Key Modules:逐个模块说明其作用、内部工作方式、代码库入口点(file:line),并链接到对应的 .scratch/01-* 脚本
  • How They Connect:模块如何连接、数据流、关键路径,链接到 .scratch/99-compose
  • Surprises:从阅读代码无法猜到的点,如隐藏耦合、隐式契约、非显而易见的初始化顺序
  • Dead Ends:没走通的路径、失败的方法、看起来重要其实不重要的模块、误导性的命名。保留失败信号,避免用户重复走弯路
  • Mental Model:压缩后的理解。如果要用 2 分钟向新团队成员解释这个代码库,你会怎么说?

执行纪律

所有阶段遵循以下节奏:

WRITE ──> RUN ──> OBSERVE ──> NOTE FINDINGS
  ^                                 │
  └─────── ADJUST PLAN ─────────────┘
  • 小步编写,频繁运行。不要写完 5 个脚本再一起运行。
  • 捕获真实输出。在 Tutorial.md 的发现中包含实际 stdout(可裁剪)。
  • 如果某处调试超过 2 分钟,将其记为复杂度信号并继续前进。
  • 不要造假。如果某个模块的行为与预期不符,如实说明。用户想了解的是实际如何工作,而不是应该如何工作。

完成前检查清单

  • .scratch/ 中包含 3-8 个带编号的探索脚本
  • .scratch/99-compose.{ts,py} 存在且可运行
  • 每个脚本都实际执行过
  • 每个脚本都记录了真实代码库中的入口点(file:line)
  • 没有脚本修改生产代码
  • .scratch/ 中存在包含所有章节的 Tutorial.md
  • Surprises 和 Dead Ends 章节记录了非显而易见的发现
  • 已建议将 .scratch/ 加入 .gitignore

边界情况

  • 项目使用多种语言:用被探索模块各自的语言编写脚本,并在 Tutorial.md 中注明跨语言边界。
  • 项目需要运行服务(数据库、Redis 等):注明依赖,尽可能 mock,无法 mock 则跳过。依赖本身也是一项发现。
  • 项目是 monorepo:询问聚焦哪个包或服务。如果用户未指定,选择最核心的一个并注明该选择。
  • 项目没有测试:这本身就是一项发现,记录到 Surprises 中。
  • 编译型语言(Go、Rust、Java):编写调用项目 CLI、API 或构建产物的脚本,而不是直接导入源码。
  • 用户提供截图或场景:组合脚本必须针对该场景,其他脚本应支持理解它。

更新检查

在会话中首次使用时,静默检查是否有更新版本:

获取 https://raw.githubusercontent.com/abpai/skills/main/versions.json,将 scratch 的版本与本文件元数据中的 version 比较。

如果远程版本更新,在主任务前暂停并询问:

scratch update available (local {X.Y} → remote {A.B}). Would you like me to update it for you first? I can run npx skills update scratch for you.

如果用户同意,先运行更新再继续。如果用户拒绝,则继续使用当前本地版本。如果获取失败或无法访问网络,则静默跳过。