Files
rrweb-skill/docs/superpowers/plans/2026-06-12-sgrobot-adapter.md

6.7 KiB

SGrobot Adapter Implementation Plan

For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (- [ ]) syntax for tracking.

Goal: Build a reusable generator that turns one rrweb semantic trace into SGrobot-compatible PlanTemplate.toml and runtime SKILL.toml artifacts without changing SGrobot core.

Architecture: Keep this repository as a Codex skill plus deterministic generator. The generator writes one business-specific plan and one business-specific sgBrowser runtime skill per recording, with the semantic trace baked into the generated page script and saved beside it as evidence.

Tech Stack: Node.js ESM, node:test, SGrobot PlanTemplate.toml, SGrobot runtime SKILL.toml, sgBrowser sgBrowserExcuteJsCodeByDomain.


Task 1: Generator Contract

Files:

  • Create: tests/generate_sgrobot_flow.test.mjs

  • Create: scripts/generate_sgrobot_flow.mjs

  • Create: package.json

  • Step 1: Write the failing tests

import { test } from "node:test";
import assert from "node:assert/strict";
import { mkdtemp, readFile, rm } from "node:fs/promises";
import { tmpdir } from "node:os";
import path from "node:path";
import { generateSgRobotArtifacts, writeArtifacts } from "../scripts/generate_sgrobot_flow.mjs";

const trace = {
  id: "expense-approval",
  name: "费用审批",
  description: "打开审批页,填写意见并点击同意。",
  startUrl: "https://oa.example.test/expense/123",
  steps: [
    { type: "assertText", text: "费用审批", label: "确认在审批页" },
    { type: "fill", selector: "textarea[name='comment']", value: "同意", label: "填写审批意见" },
    { type: "click", selector: "button[data-action='approve']", label: "点击同意", risk: "write" }
  ]
};

test("generates SGrobot plan and runtime skill artifacts", () => {
  const result = generateSgRobotArtifacts(trace, { defaultMode: "execute" });
  assert.equal(result.summary.planId, "rrweb-expense-approval");
  assert.equal(result.summary.skillName, "rrweb-expense-approval-execute");
  assert.equal(result.summary.requiresApproval, true);
  assert.equal(result.files.get("plan_templates/rrweb-expense-approval/PlanTemplate.toml").includes('skills = ["rrweb-expense-approval-execute"]'), true);
  assert.equal(result.files.get(".sgclaw-workspace/skills/rrweb-expense-approval-execute/SKILL.toml").includes('command = "sgBrowserExcuteJsCodeByDomain"'), true);
  assert.equal(result.files.get(".sgclaw-workspace/skills/rrweb-expense-approval-execute/SKILL.toml").includes('expected_domain = "oa.example.test"'), true);
  assert.equal(result.files.get(".sgclaw-workspace/skills/rrweb-expense-approval-execute/scripts/execute_trace.js").includes('"default_mode": "execute"'), true);
});

test("writes generated artifacts under a SGrobot repository root", async () => {
  const root = await mkdtemp(path.join(tmpdir(), "rrweb-sgrobot-"));
  try {
    const result = generateSgRobotArtifacts(trace);
    await writeArtifacts(root, result.files);
    const plan = await readFile(path.join(root, "plan_templates/rrweb-expense-approval/PlanTemplate.toml"), "utf8");
    const skill = await readFile(path.join(root, ".sgclaw-workspace/skills/rrweb-expense-approval-execute/SKILL.toml"), "utf8");
    const evidence = await readFile(path.join(root, ".sgclaw-workspace/skills/rrweb-expense-approval-execute/trace.semantic.json"), "utf8");
    assert.match(plan, /skills = \["browser\.open_url"\]/);
    assert.match(skill, /script_path = "scripts\/execute_trace.js"/);
    assert.equal(JSON.parse(evidence).id, "expense-approval");
  } finally {
    await rm(root, { recursive: true, force: true });
  }
});
  • Step 2: Run test to verify it fails

Run: node --test tests/generate_sgrobot_flow.test.mjs

Expected: FAIL with Cannot find module '../scripts/generate_sgrobot_flow.mjs'.

  • Step 3: Implement the generator

Create scripts/generate_sgrobot_flow.mjs exporting generateSgRobotArtifacts(trace, options) and writeArtifacts(root, files). The generator must validate id, name, startUrl, and steps, derive expected_domain from startUrl, emit SGrobot paths, and support defaultMode of dry-run or execute.

  • Step 4: Add package metadata

Create package.json with:

{
  "name": "rrweb-sgrobot-skill",
  "version": "0.1.0",
  "type": "module",
  "private": true,
  "scripts": {
    "test": "node --test tests/*.test.mjs",
    "generate:sgrobot": "node scripts/generate_sgrobot_flow.mjs"
  }
}
  • Step 5: Run test to verify it passes

Run: npm test

Expected: PASS with both generator tests green.

Task 2: Codex Skill Wrapper

Files:

  • Create: SKILL.md

  • Create: references/sgrobot-adapter.md

  • Create: examples/basic-trace.json

  • Step 1: Write the skill instructions

Create a concise SKILL.md that tells Codex to use scripts/generate_sgrobot_flow.mjs when adapting rrweb semantic traces for SGrobot. It must state that .agents/skills/**/SKILL.md is only an agent helper, while SGrobot runtime artifacts are PlanTemplate.toml and .sgclaw-workspace/skills/**/SKILL.toml.

  • Step 2: Add focused SGrobot mapping reference

Create references/sgrobot-adapter.md with the SGrobot-specific mapping rules: one generated plan per recording, one generated runtime skill per recording, browser.open_url first, generated sgBrowser execution skill second, optional json.save_result third, and step-level approval when execute mode includes mutating actions.

  • Step 3: Add a realistic example trace

Create examples/basic-trace.json using the same schema covered by the test: id, name, description, startUrl, and steps.

  • Step 4: Validate the skill folder

Run: python3 /Users/zhaoyilun/.codex/skills/.system/skill-creator/scripts/quick_validate.py /Users/zhaoyilun/Documents/rrweb-skill

Expected: PASS.

Task 3: Verification Against SGrobot Shape

Files:

  • Read-only check: /Users/zhaoyilun/projects/sgrobot-architecture-design/docs/concepts/skill-and-plan-template.md

  • Read-only check: /Users/zhaoyilun/projects/sgrobot-architecture-design/docs/how-to/add-skill.md

  • Step 1: Generate sample output to a temp directory

Run: node scripts/generate_sgrobot_flow.mjs --trace examples/basic-trace.json --out /tmp/rrweb-sgrobot-sample --default-mode dry-run --force

Expected: the command prints paths for the plan, skill, runtime script, and trace evidence.

  • Step 2: Inspect generated files

Run: find /tmp/rrweb-sgrobot-sample -type f | sort

Expected: files exist under plan_templates/rrweb-expense-approval/ and .sgclaw-workspace/skills/rrweb-expense-approval-execute/.

  • Step 3: Re-run tests

Run: npm test

Expected: PASS.