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.