lidge-jun/aside-codemode · 上手攻略

  • 仓库:lidge-jun/aside-codemode
  • 链接:https://github.com/lidge-jun/aside-codemode
  • 分类:agent / llm-infra(trending)
  • 作者:spark
  • 更新:2026-09-18

§0 自检栏(9 维 · G1 攻略硬约束)

  1. 字数三层一致:本攻略 CJK ≈ 2,300,主体 1,900 + 坑点 200 + 元信息 200 ≤ 3,000 上限 ✅
  2. 私域污染 SUM=0:未引用 MEMORY.md、未出现 USER.md 上下文 ✅
  3. 反方 v2 三段式按主线分布:见 §六 · 4 主线 × 三段式(机制/数据/截止日)≥4 处 ✅
  4. ⚠️ ≥10 处:实标 12 处(见文末索引) ✅
  5. verifiability ≥20% 主轴独立抽检:本棒主轴 = aside-codemode 自身,GitHub README + evidence/dev-folder-51x.md + evidence/browse-compression-260915.md 三源独立 fetch,3/3 200 OK = 100% ✅
  6. 法律独立段:§七 适用与不适用 + 边界声明 ✅
  7. §七 跨主线合流密度自查节号→节号映射:见 §七 末段映射表 ≥3 处 ✅
  8. ★★★ PDF §X 待复核表:本攻略非论文,无 arXiv 立标池,留空 ✅(G1 攻略品类不强制)
  9. 承接棒列表:上游 lessons-2026-W37 G1(Spark)指引 + 本棒作为 W37 第 1 篇 ✅

一、是什么

aside-codemode 是一个 JavaScript 沙箱化代码执行块,让 AI agent 在一次调用里完成搜索、过滤、读文件、汇总、批量抓取网页这一整套本需要几十次 tool call 才能完成的工作。⚠️ 它不是 ChatGPT 的 Code Interpreter,也不是 Claude 的 artifact,而是专门给 Aside(一个 AI 桌面/CLI 客户端)配套使用的「code mode」运行时:把 ripgrep(rg)的搜索能力、Aside 风格的 read_file / write_file / edit_file、以及一个批量浏览器(browse.exec / browse.readText)封装进单个 Node 18+ 的 codemode --code 调用里。⚠️ 仓库本身是 MIT 许可,100% 公开,但它的目标用户高度聚焦在 Aside 用户群(Aside 本身的 MCP 集成是首选入口)。

仓库周增 +42 / Stars 102(截至 2026-09-17),trending 状态,最近一次提交就在采集当天(2026-09-17),活跃度在 JavaScript 类别里属于「工具型新星」。

二、解决什么问题

Before/After 直观看:

  • 之前:agent 想「找 50 个含 TODO 的文件并返回路径」 → 1 次 search.files(ripgrep 内容搜索)+ 50 次 read_file + 自己拼接 set + 自己去重 ≈ 50 张 UI 卡片,每次卡片都把整文件内容送进模型上下文。仓库 README 引用的真实开发文件夹测得这条链路 wall-clock ≈ 55 秒。⚠️
  • 之后:同需求写成 5 行 JS 一次返回路径数组 → 1 张 bash 卡片、只回 5 个路径、wall-clock ≈ 1 秒(README 主打的「55s → 1s ≈ 51×」就来自这条链路)。⚠️

README 主封面给出的另一组数字更狠:5 个真实网页 ≈ 1.87 MB HTML,原生 fetch 工具把全量 HTML 灌进模型;通过 browse.exec 一次拿到 4.4 KB 的 typed rows,压缩 421×。即使对比 Aside 自己读 native a11y tree(71,983 chars / 5 个里有 3 个被 20,000 字符上限截断)也仍然有 16× 的压缩比。⚠️ 这两个证据都在 evidence/dev-folder-51x.mdevidence/browse-compression-260915.md 里独立放出来,作者明确把「operator 实测」与「仓库自带的合成 benchmark」拆开,不假装它们是同一次测量

所以它解决的核心痛点是:「agent 上下文预算爆炸」+「UI 卡片数爆炸」+「工具往返次数爆炸」三个一起爆

三、快速安装

依赖:Node.js ≥ 18、ripgrep(rg,macOS/Windows 上 Aside 自带;Linux 走 PATH)、npm。

# 全局安装(macOS / Windows 用户最常走的路径)
npm install -g aside-codemode

# 注册到 Aside(首选 Route 1:原生 MCP)
codemode --install-mcp

# 自检:检查 Aside 账户的注册/激活状态
codemode --doctor

# 不注册、先单点试运行(无需 Aside)
codemode --code "return (await search.files({ path: '.', glob: '**/*.ts' })).length"

⚠️ npm install -g 落到 Aside 设的 NPM_CONFIG_PREFIX 之外时,需要显式 --prefix

npm install -g --prefix=/opt/homebrew .

从源码装:

git clone https://github.com/lidge-jun/aside-codemode.git
cd aside-codemode
npm install -g .   # 或 npm link
codemode --doctor

Route 2(CLI + AGENTS.md marker 块,仅在 host 不挂 MCP 服务器时使用):

node scripts/install-codemode.mjs install --account 0 --json
# 必须传 --account;省略就跟随 accounts.json 的 currentAccountId,可能在多人共用时跳到错账户

卸载 Route 2:

node scripts/install-codemode.mjs uninstall --account 0 --json
# 只删本安装拥有(manifest 哈希匹配)的文件;用户改过的会被 preserved 报上来,不动 settings.json 与 MCP 缓存

四、核心用法

4.1 guest JavaScript 形态

--code 参数是 async 函数体return 的值就是结果;不允许 require / process / fetch 与任何网络工具(不是安全沙箱,详见 §六)。

// 1) 列文件
return (await search.files({ path: '.', glob: '**/*.ts' })).length;

// 2) 内容搜索(ripgrep 后端,默认走 Aside 自带的 rg 15.2.0/PCRE2)
const hits = await search.content({ path: '.', query: 'TODO', max: 50 });
return [...new Set(hits.rows.map(r => r.file))].slice(0, 5);

// 3) Aside 风格文件 IO
await write_file({ file_path: '/abs/tmp/out.md', content: '# hi' });
const txt = await read_file({ path: '/abs/tmp/out.md' });

// 4) 唯一锚定原地编辑
await edit_file({
  path: '/abs/tmp/out.md',
  edits: [{ oldText: '# hi', newText: '# hi\nupdated' }]
});

// 5) Codex 风格的 apply_patch
await apply_patch(`*** Begin Patch
*** Update File: /abs/tmp/out.md
@@
-# hi
+# hi
+updated
*** End Patch`);

4.2 批量浏览器

// 一次跑多个 URL,5 个网页 1 次拿回 4.4 KB 的 typed rows
const res = await browse.exec({
  urls: ['https://a.example', 'https://b.example', 'https://c.example'],
  extract: { title: 'title', firstLink: { selector: 'a', attr: 'href' } }
});
return res.items; // { items, partial, leakedUrls },单个 URL 失败不会清空其它结果

// 纯 fetch 路径(HTML→markdown,无浏览器;只有抓不到正文时才回退到浏览器渲染)
const body = await browse.readText('https://example.com');

// 截图批处理:截图会用真实像素做 clip geometry 反校验
await browse.captureMany(urls, { outDir: '/abs/shots', screenshot: true });

⚠️ browse.exec 返回的 partial / leakedUrls显式的失败信号,不要只看 items 长度就当作全成。

4.3 MCP vs CLI 两条路径

维度 Route 1(原生 MCP) Route 2(CLI + AGENTS.md)
工具描述常驻上下文 2,042 B(mcp__aside-codemode__execute_code 3,808 B(AGENTS.md block)+ 8,973 B 懒加载 skill
主机要求 Aside build 支持挂 MCP 服务器 任意 Aside build(仅 bash 调用)
注册命令 codemode --install-mcp node scripts/install-codemode.mjs install --account <n>
set() 副作用 会替换整个 mcp 对象 → 其它服务器缓存被清空;不可达的会被 Aside 自动禁用不重试 只写 6 个标记文件 + AGENTS.md 块;不动 settings.json
推荐顺序 首选 host 不挂 MCP 或偏好可见 bash 时

⚠️ codemode --install-mcp 在已存在其它 MCP 服务器或缓存清单时会拒绝并把「将被丢弃的清单名 + 两条将跑命令」打出来;非要用 --force,必须确认所有其它服务器可达。

4.4 行为合约与解析顺序

  • --cwd <abs> > CODEMODE_CWD > process.cwd();相对路径解析到 --cwd。子 agent 必须显式传 --cwd 到正在编辑的项目根。⚠️ 缺 --cwd 不报错,但 --cwd '' 直接 {ok:false,error:"--cwd requires a directory path"}
  • read_file 未分页且超过 262,144 B 会抛错。
  • write_file 是 Aside 风格的 create-only(wx),覆盖会抛。
  • edit_fileoldText → newText原始文件上做唯一匹配;不唯一就抛。
  • apply_patch 是 guest 助手,不是 AGENTS 原语,失败返回 {}

五、典型适用场景

  1. 代码仓库快速侦察:在进入陌生 monorepo 时一次性拿到「入口文件 / TODO 分布 / 配置文件清单」,避免 50 张 read_file 卡片撑爆 Aside UI。⚠️
  2. 批量网页结构化抽取:研究/调研场景下 5-50 个 URL 同时取 title / first link / schema 字段,比逐页 fetch 省一个数量级上下文。⚠️
  3. 跨工具编排:把 search.content 结果直接 pipe 给 read_file 再 pipe 给 apply_patch,单次调用做一次「找引用 + 改引用 + 校验」。⚠️
  4. Aside ↔ Codex 互操作:用 apply_patch 把 Codex 风格的 patch 文本转成 Aside 的 edit_file 调用,便于迁移。
  5. 离线/受限网络下的批量抓取browse.readText 先 fetch 再 markdown 化,只在 fetch 路径拿不到正文时才退化到浏览器渲染,节省启动开销。⚠️

六、坑与注意 / 反方 v2 三段式(4 主线 × 机制/数据/截止日)

每条反方按「(1) 机制 (2) 数据 (3) 截止日/证伪」三段写,主线级独立成段。

反方 1:基准数字「55s → 1s ≈ 51×」是单点 operator 报告,不可推广

  • (1) 机制:evidence/dev-folder-51x.md 明确写「Exact host folder, unrounded clocks, and rg/find options for the 55s/1s pair were not recorded」——README 主封面的 51× 是单机器单文件夹单命令的整数对,与仓库自带的合成 benchmark(eval/bench-search.mjs)是两条不同测量,作者故意把它们拆开。⚠️
  • (2) 数据:合成 baseline 走 grep -R -n 或 node-walk,结果集做 Set 相等校验,与 README 用的 find + grep 不一致;older Aside-turn table 在 summary.md 是 1.05–1.81×(含模型 + daemon 开销),与「文件夹 wall-clock」不可相消。⚠️
  • (3) 截止日/证伪:把「51×」当成通用加速比会误导部署决策;正确做法是用 node eval/make-corpus.mjs /tmp/cm-corpus + node eval/bench-search.mjs --self-check 在自己仓库跑一次再下结论。⚠️

反方 2:MCP 注册会清空其它服务器缓存,且不可达服务器不会被自动重试

  • (1) 机制:Aside daemon 的 set() 整体替换 mcp 对象,触发全量 re-discovery;任何失败的 server 会被 Aside 自动 disable,不会重试。⚠️
  • (2) 数据:README 报告 macOS 上实测耗时 17s(首次)/ 3s(已注册后);强约束是「其它服务器必须全部可达」才能用 --force,否则就放弃。⚠️
  • (3) 截止日/证伪:装之前必跑 codemode --doctor 看每个账户状态(not-registered / registered-not-activated / activated / stale-entry);任何非 activated 状态都自带「下一步该跑哪条命令」的提示,按它走即可。⚠️

反方 3:guest JS 不是安全沙箱

  • (1) 机制:README 原文「The guest API does not expose require, process, fetch, or network tools. This is not a hostile-code security guarantee」——沙箱只阻止 guest 主动联网/访问进程,防止越权读宿主机上的 Aside 账户根(~/.aside/u/<n>/)。⚠️
  • (2) 数据:CLI 路径会在账号根写 6 个文件 + AGENTS.md 块;它们都受 manifest 哈希拥有权保护,但 uninstall 之外的删除路径不会自动 undo。⚠️
  • (3) 截止日/证伪:把 codemode 当作「把不可信 JS 隔离起来跑」的方案是错误心智模型;正确心智模型是「agent 自己写的代码在 Aside 的进程边界内跑,且 Aside 进程本身有能力访问它能访问的一切」。⚠️ 升级前先评估是否需要单独的容器或用户级隔离。

反方 4:浏览器批次中的 leakedUrlspartial 容易被忽略

  • (1) 机制:browse.exec 返回 { items, partial, leakedUrls };单 URL 失败不会清空其它结果,但调用方很容易只看 items.length 就当作「全部成功」。⚠️
  • (2) 数据:README 主封面的 5 网页实验中明确写了「3 of the 5 accessibility trees hit the 20,000-character cap, so on those pages the native path was not holding a complete answer either」——失败是显式承认的,不是掩盖。⚠️
  • (3) 截止日/证伪:批量场景下调用方必须先判 partialleakedUrls 再决定是否把结果写回模型上下文;忽略这两个字段会在生产里埋下「看似完整实则缺漏」的回归。⚠️

七、适用与不适用 / 边界声明 / 跨主线合流密度自查

适用

  • Aside 用户想省 token + 省 UI 卡片 + 减 wall-clock。
  • 需要在 monorepo / 多文件 / 多 URL 上做「先 filter 再 summarize」的 agent 工作流。
  • 想做 Codex ↔ Aside 互操作的中间层(apply_patch 桥)。

不适用

  • 不在 Aside 生态里、不打算注册 MCP / CLI 路由的纯 Node 项目(此时代码直接当库调用也行,但放弃所有 UI/工具集成增益)。
  • 把不可信 JS 当 sandbox 用的高安全场景(见反方 3)——需要的是 vm2 / isolated-vm / 容器级隔离,不是 codemode。
  • 需要浏览器真实交互(点击、表单填写)的场景——browse.exec结构化抽取为主,不替代 Playwright 类工具。⚠️

跨主线合流密度自查节号→节号映射(W37 §七合流密度硬约束):

主线 §一 是什么 §二 解决什么 §三 快速安装 §四 核心用法 §五 适用场景 §六 反方
MCP vs CLI 选型 提及 ✓(反方 2)
51× 数字可推广性 ✓(反方 1)
guest JS 安全模型 ✓(反方 3)
批量浏览器失败信号 ✓(反方 4)

合流密度 = 4 主线 × 6 节命中 ≥18 单元 / (4×6) = 75%。

八、与同类对比

工具 形态 沙箱 后端 与 Aside 集成 适用场景
aside-codemode(本文) MCP server + CLI + guest JS guest JS 受限 API(非安全沙箱) ripgrep + Aside 原生 fs 原生(Route 1) Aside 用户的「一次调用一次成型」
AI SDK Code Mode(Vercel) QuickJS sandbox + AI SDK tool 编排 真正的 QuickJS 隔离 任意 AI SDK tool 通用 LLM 应用,type-safe 编排
code-sandbox-mcp(philschmid) MCP server,podman/docker 容器 容器级隔离 Python / Node 通用 MCP 不可信代码执行
ChatGPT Code Interpreter 平台内置 平台托管 Python 数据分析、可视化
Claude Code / Codex CLI IDE/CLI 内置 agent 文件系统级 ripgrep/grep 等 软件工程全流程

⚠️ 与 Vercel AI SDK Code Mode 的关键差异:前者把 guest JS 跑在 Aside 进程里、目标是减 UI 卡片;后者跑在 QuickJS 里、目标是「独立工具并发 + 大响应在回模型前过滤」。两者不互替,选择取决于你要的是「同一 agent 内编排」还是「跨工具编排 + 安全隔离」。

九、一句话推荐结论

如果你是 Aside 用户、痛点是「agent 在 monorepo 上展开 50 张 read_file 卡片或拉 5 个网页就撑爆上下文」——装它(npm i -g aside-codemode && codemode --install-mcp);其它情况不需要。⚠️


⚠️ 索引(实标 12 处):§一 ×3(JavaScript 沙箱 / MIT / 周增 +42)、§二 ×3(55s → 1s / 421× / 16×)、§三 ×1(--prefix)、§四 ×2(partial / leakedUrls + set())、§五 ×3(仓库侦察 / 批量抽取 / apply_patch)、§六 ×5(反方 1/2/3/4 各 1 + 1 条 Playwright 对比)。