本文へ移動
cccskills
無料GitHub で公開

mock_websites

How to set up and manipulate mock web application state via HTTP APIs for CUA-Gym tasks. For setup-gen and reward-gen agents.

日本語の概要は準備中です。原文の説明を表示しています。

xlang-ai/CUA-Gymスター 224(GitHub 224 + cccskills 0)
連携ツールSlackX (Twitter)

実行スコア 未検証

インストール方法を見る

含まれるファイル(67)

  • SKILL.md13.2 KB
  • REWARD_SKILL.md11.2 KB
  • schemas/airtable_mock.md20.6 KB
  • schemas/amazon_mock.md14.4 KB
  • schemas/asana_mock.md5.1 KB
  • schemas/aws_console_mock.md4.9 KB
  • schemas/azure_mock.md29.9 KB
  • schemas/booking_com_mock.md14.7 KB
  • schemas/california_tax_mock.md19.7 KB
  • schemas/Canvas-LMS_mock.md15.0 KB
  • schemas/coinbase_mock.md15.4 KB
  • schemas/discord_mock.md7.1 KB
  • schemas/docusign_mock.md5.5 KB
  • schemas/ebay_mock.md12.9 KB
  • schemas/epic-health_mock.md28.8 KB
  • schemas/Expensify_mock.md29.5 KB
  • schemas/facebook_mock.md24.1 KB
  • schemas/github_mock.md4.9 KB
  • schemas/gitlab_mock.md4.5 KB
  • schemas/gmail_mock.md4.1 KB
  • schemas/google_calendar_mock.md10.2 KB
  • schemas/google_docs_mock.md9.1 KB
  • schemas/google_drive_mock.md6.4 KB
  • schemas/google_flights_mock.md15.4 KB
  • schemas/google_sheets_mock.md9.9 KB
  • schemas/hubspot_mock.md22.5 KB
  • schemas/instacart_mock.md21.7 KB
  • schemas/instagram_mock.md6.1 KB
  • schemas/jira_mock.md4.7 KB
  • schemas/linkedin_mock.md4.1 KB
  • schemas/lucidchart_mock.md17.8 KB
  • schemas/microsoft_teams_mock.md25.8 KB
  • schemas/miro_mock.md18.8 KB
  • schemas/monday_mock.md24.8 KB
  • schemas/multi_procedure_application_mock.md13.6 KB
  • schemas/notion_mock.md4.7 KB
  • schemas/outlook_web_mock.md22.6 KB
  • schemas/PACS-viewer_mock.md19.3 KB
  • schemas/paypal_mock.md14.8 KB
  • schemas/pinterest_mock.md17.3 KB
  • schemas/postman_mock.md16.1 KB
  • schemas/premiere_pro_mock.md19.2 KB
  • schemas/quickbooks_mock.md21.0 KB
  • schemas/reddit_mock.md4.3 KB
  • schemas/robinhood_mock.md13.7 KB
  • schemas/salesforce_mock.md6.3 KB
  • schemas/SAP_mock.md10.0 KB
  • schemas/ServiceNow_mock.md19.7 KB
  • schemas/shopify_admin_mock.md11.6 KB
  • schemas/slack_mock.md5.4 KB
  • schemas/stripe_dashboard_mock.md16.1 KB
  • schemas/TradingView_mock.md24.1 KB
  • schemas/trello_mock.md4.8 KB
  • schemas/TurboTax_mock.md31.6 KB
  • schemas/twitter_mock.md4.7 KB
  • schemas/uber_eats_mock.md23.5 KB
  • schemas/usa-gov_mock.md25.1 KB
  • schemas/visa_portal_ds160_mock.md15.5 KB
  • schemas/visa_portal_mock.md23.7 KB
  • schemas/wandb_mock.md23.6 KB
  • schemas/wechat_mock.md16.0 KB
  • schemas/workday_mock.md18.7 KB
  • schemas/youtube_mock.md6.2 KB
  • schemas/Zendesk_mock.md19.6 KB
  • schemas/zhihu_mock.md14.2 KB
  • schemas/zillow_mock.md16.4 KB
  • schemas/zoom_web_mock.md15.9 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Mock Websites — Setup & State Injection Guide

This skill teaches setup-gen how to create initial web app state and golden patches for mock website tasks. Unlike file-based domains, mock website tasks involve HTTP state injection — there are no local files on the VM.

  • Libraries: requests, json, uuid
  • All 16 mocks are deployed at https://cua-gym-<name>.xlang.ai

0. Mock Website Registry

All mocks are publicly deployed. The URL pattern is https://cua-gym-<name>.xlang.ai where <name> is the directory name without _mock, with underscores replaced by hyphens.

MockPublic URLSCHEMA.md
asana_mockhttps://cua-gym-asana.xlang.aiopenrlvr-mock/asana_mock/SCHEMA.md
aws_console_mockhttps://cua-gym-aws-console.xlang.aiopenrlvr-mock/aws_console_mock/SCHEMA.md
discord_mockhttps://cua-gym-discord.xlang.aiopenrlvr-mock/discord_mock/SCHEMA.md
docusign_mockhttps://cua-gym-docusign.xlang.aiopenrlvr-mock/docusign_mock/SCHEMA.md
github_mockhttps://cua-gym-github.xlang.aiopenrlvr-mock/github_mock/SCHEMA.md
gitlab_mockhttps://cua-gym-gitlab.xlang.aiopenrlvr-mock/gitlab_mock/SCHEMA.md
gmail_mockhttps://cua-gym-gmail.xlang.aiopenrlvr-mock/gmail_mock/SCHEMA.md
jira_mockhttps://cua-gym-jira.xlang.aiopenrlvr-mock/jira_mock/SCHEMA.md
linkedin_mockhttps://cua-gym-linkedin.xlang.aiopenrlvr-mock/linkedin_mock/SCHEMA.md
notion_mockhttps://cua-gym-notion.xlang.aiopenrlvr-mock/notion_mock/SCHEMA.md
reddit_mockhttps://cua-gym-reddit.xlang.aiopenrlvr-mock/reddit_mock/SCHEMA.md
salesforce_mockhttps://cua-gym-salesforce.xlang.aiopenrlvr-mock/salesforce_mock/SCHEMA.md
slack_mockhttps://cua-gym-slack.xlang.aiopenrlvr-mock/slack_mock/SCHEMA.md
trello_mockhttps://cua-gym-trello.xlang.aiopenrlvr-mock/trello_mock/SCHEMA.md
twitter_mockhttps://cua-gym-twitter.xlang.aiopenrlvr-mock/twitter_mock/SCHEMA.md
youtube_mockhttps://cua-gym-youtube.xlang.aiopenrlvr-mock/youtube_mock/SCHEMA.md

1. State API

Every mock exposes identical HTTP endpoints:

POST /post?sid=<sid> — State Injection

ActionBodyEffect
set{"action":"set", "state":{...}}Writes current_state AND creates initial_state (if first write). Used by initial_setup.py.
set_current{"action":"set_current", "state":{...}}Writes ONLY current_state. Never touches initial_state. Used by golden_patch.py.
reset{"action":"reset"}Deletes both current and initial state files.

All actions support "merge": true to deep-merge into existing state instead of replacing.

GET /go?sid=<sid> — State Inspection

Returns:

{
  "initial_state": { ... },
  "current_state": { ... },
  "state_diff": { ... }
}
  • initial_state = snapshot from first action:"set" call
  • current_state = latest state (updated by UI interactions or set_current)
  • state_diff = keys that changed between initial and current

GET /state?sid=<sid> — Raw State Read

Returns {stored_state, has_custom_state, sid}.

POST /upload?sid=<sid> — File Upload

Upload files (attachments, images, documents) to the mock server. Files are stored per-session and served via /files/.

Request: multipart/form-data with one or more file fields.

Response:

{
  "success": true,
  "files": [
    {
      "original_name": "report.pdf",
      "stored_name": "a1b2c3d4_report.pdf",
      "size": 12345,
      "content_type": "application/pdf",
      "url": "/files/<sid>/a1b2c3d4_report.pdf"
    }
  ]
}

Usage in initial_setup.py — upload a file and reference its URL in state:

import requests

# Upload a file
with open('/path/to/attachment.pdf', 'rb') as f:
    resp = requests.post(
        f'{BASE_URL}/upload?sid={sid}',
        files={'file': ('attachment.pdf', f, 'application/pdf')},
        timeout=30
    )
uploaded = resp.json()['files'][0]
file_url = uploaded['url']  # e.g., /files/<sid>/a1b2c3d4_attachment.pdf

# Reference it in state injection
state['messages']['general'].append({
    'messageId': 'msg_1',
    'content': 'Here is the report',
    'attachments': [{'name': 'attachment.pdf', 'url': file_url, 'size': uploaded['size']}],
    # ... other fields
})

GET /files/<sid>/<filename> — Serve Uploaded Files

Returns the uploaded file with appropriate Content-Type header. Files are served with Content-Disposition: attachment.


2. Session ID (sid) Pattern

The sid links initial_setup.py, golden_patch.py, and reward.py to the same state.

Flow:

  1. initial_setup.py generates a UUID sid → writes to /tmp/task_web_sid on the VM
  2. initial_setup.py POSTs action:"set" with the sid → creates both initial and current state
  3. golden_patch.py reads sid from /tmp/task_web_sid → POSTs action:"set_current" → updates ONLY current state
  4. reward.py reads sid from /tmp/task_web_sid → GETs /go?sid=<sid> → compares initial vs current
# Generate and persist sid (initial_setup.py)
import uuid
sid = str(uuid.uuid4())
with open('/tmp/task_web_sid', 'w') as f:
    f.write(sid)

# Read sid (golden_patch.py and reward.py)
with open('/tmp/task_web_sid') as f:
    sid = f.read().strip()

3. State Schemas

Each mock has a schema file documenting the full state shape, default IDs, and observable state changes. Schemas are stored locally in this skill directory.

MANDATORY: Always read the schema before writing state injection code. The schema tells you:

  • Required top-level keys (e.g., currentUser, channels, messages for slack)
  • Object shapes for each entity type
  • Default IDs for users, channels, projects, etc.
  • Which state fields change when the user performs specific actions

To load the schema for a mock (do this in Step 0, immediately after reading this SKILL.md):

Read: .claude/skills/mock_websites/schemas/<mock_name>.md

Example — for a Slack task:

Read: .claude/skills/mock_websites/schemas/slack_mock.md

For multi-mock tasks, read ALL schemas for every mock listed in task_config.json's domains array.

Available schemas: asana_mock, aws_console_mock, discord_mock, docusign_mock, github_mock, gitlab_mock, gmail_mock, jira_mock, linkedin_mock, notion_mock, reddit_mock, salesforce_mock, slack_mock, trello_mock, twitter_mock, youtube_mock.

If no schema file exists for a mock, inspect the mock's default state via GET /go?sid=nonexistent to discover the state shape (it returns default data when no custom state is set).


4. initial_setup.py Template

"""
Initial Setup: <task_description>
Task ID: <task_id>
Domain: mock_websites
Mock: <mock_name>
"""
import json
import os
import shlex
import subprocess
import time
import uuid

import requests

# --- Config ---
BASE_URL = 'https://cua-gym-<name>.xlang.ai'  # e.g., cua-gym-slack.xlang.ai
sid = str(uuid.uuid4())

# Persist sid for golden_patch.py and reward.py
with open('/tmp/task_web_sid', 'w') as f:
    f.write(sid)

# --- Build initial state ---
# Consult SCHEMA.md for the full state shape.
# Include ALL required top-level keys. Missing keys → blank UI or crash.
state = {
    # ... full state matching SCHEMA.md ...
}

# --- Inject state ---
resp = requests.post(
    f'{BASE_URL}/post?sid={sid}',
    json={'action': 'set', 'state': state},
    timeout=30
)
assert resp.status_code == 200, f'State injection failed: {resp.text}'
print(f'State injected: sid={sid}')

# --- Verify ---
go = requests.get(f'{BASE_URL}/go?sid={sid}', timeout=10).json()
assert go['initial_state'] is not None, 'initial_state is None after injection'
print('Verified: initial_state and current_state are set')

# --- Launch browser ---
def launch_gui(command, delay_sec=1.0):
    env = os.environ.copy()
    env['DISPLAY'] = ':0'
    subprocess.Popen(
        shlex.split(command),
        stdout=subprocess.DEVNULL,
        stderr=subprocess.DEVNULL,
        env=env,
    )
    time.sleep(delay_sec)

launch_gui(f'google-chrome "{BASE_URL}/?sid={sid}"', delay_sec=2.0)
print(f'GUI_READY: launched browser at {BASE_URL}/?sid={sid}')

5. golden_patch.py Template

CRITICAL: Always use action:"set_current". NEVER use action:"set" in golden_patch.py.

Using action:"set" would overwrite initial_state, making state_diff empty and breaking reward evaluation entirely.

"""
Golden Patch: <task_description>
Task ID: <task_id>
Domain: mock_websites
Mock: <mock_name>
Changes: <brief list of what this patch does>
"""
import copy
import json

import requests

# --- Config ---
BASE_URL = 'https://cua-gym-<name>.xlang.ai'

# Read sid from initial_setup.py
with open('/tmp/task_web_sid') as f:
    sid = f.read().strip()

# --- Fetch current initial state ---
go = requests.get(f'{BASE_URL}/go?sid={sid}', timeout=10).json()
state = copy.deepcopy(go['initial_state'])

# --- Apply ONLY the minimal changes the task requires ---
# Example: send a message in #general
# state['messages']['general'].append({
#     'messageId': 'msg_new_1',
#     'senderId': 'user_1',
#     'content': 'Hello world!',
#     'timestamp': '2024-06-15T14:30:00Z',
#     'threadId': None,
#     'reactions': [],
#     'attachments': [],
#     'isEdited': False
# })

# --- Write ONLY current_state (preserve initial_state) ---
resp = requests.post(
    f'{BASE_URL}/post?sid={sid}',
    json={'action': 'set_current', 'state': state},
    timeout=30
)
assert resp.status_code == 200, f'set_current failed: {resp.text}'
print(f'Golden state applied via set_current: sid={sid}')

# --- Verify diff exists ---
go2 = requests.get(f'{BASE_URL}/go?sid={sid}', timeout=10).json()
assert go2['state_diff'], 'state_diff is empty — golden state matches initial (no changes applied)'
print(f'Verified: state_diff is non-empty')

6. Multi-Mock Tasks

When task_config.json contains a domains list with multiple mocks:

{
  "domains": ["slack_mock", "notion_mock"],
  "task_instruction": "Copy the meeting notes from Slack #general to a new Notion page"
}

Use the same sid across all mocks:

# initial_setup.py — inject into ALL listed mocks
sid = str(uuid.uuid4())
with open('/tmp/task_web_sid', 'w') as f:
    f.write(sid)

mocks = {
    'slack_mock': 'https://cua-gym-slack.xlang.ai',
    'notion_mock': 'https://cua-gym-notion.xlang.ai',
}

for name, url in mocks.items():
    state = build_state_for(name)  # mock-specific state
    resp = requests.post(f'{url}/post?sid={sid}', json={'action': 'set', 'state': state}, timeout=30)
    assert resp.status_code == 200

# Launch browser with primary mock
launch_gui(f'google-chrome "{mocks["slack_mock"]}/?sid={sid}"', delay_sec=2.0)

Golden patch similarly uses set_current on each mock that should change.


7. Sanity Check (for setup-gen Step 7)

Instead of ls /home/user/, use curl to verify state:

python3 scripts/env_cli.py -c "<workdir>/env_config_initial.json" execute \
  "sid=\$(cat /tmp/task_web_sid); curl -s 'https://cua-gym-slack.xlang.ai/go?sid='\$sid | python3 -m json.tool | head -60"

8. Bitter Lessons

  1. action:"set" in golden_patch.py is the #1 bug. It overwrites initial_state, making state_diff empty. Reward scripts that compare initial vs current will always see 0 diff → reward = 0. ALWAYS use action:"set_current".

  2. Missing state keys cause blank pages. If you inject {"channels": [...]} without currentUser, users, messages, etc., the UI renders empty or crashes. Always provide ALL required top-level keys from SCHEMA.md.

  3. Array keys are replaced, not merged. deepMerge treats arrays as atomic values. If you POST {"messages": {"general": [msg1]}} with merge: true, it replaces the entire general array. To add a message, fetch current state first, append, then write back.

  4. sid must be alphanumeric + hyphens + underscores. The server sanitizes sid with [^a-zA-Z0-9_-]. UUIDs work perfectly. Do not use special characters.

  5. State is NOT persisted in the browser. The browser fetches state from the server on page load via ?sid=xxx. If you inject state after the browser loads, the user must refresh. Always inject state BEFORE launching the browser.

  6. /go without sid returns default state. Always include ?sid=<sid> in all API calls. Missing sid returns the app's built-in default data, not your injected state.

  7. Timestamps should be ISO 8601. Most mocks expect "2024-06-15T14:30:00Z" format. Using Unix timestamps or other formats may cause rendering issues.

  8. IDs must be unique within their collection. When adding new messages, channels, etc., generate unique IDs (e.g., msg_new_1, ch_custom_1). Duplicate IDs cause silent data corruption.

  9. golden_patch should copy initial_state and apply minimal changes. Don't build golden state from scratch — start from go['initial_state'], deep-copy it, and modify only what the task requires. This ensures the state_diff accurately reflects task completion.

  10. HTTPS is required. All mocks are served over HTTPS at cua-gym-*.xlang.ai. HTTP will not work.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

コメント

ログインなしで書き込めます。使ってみた感想、質問、動かなかった環境などを気軽にどうぞ。

まだコメントはありません。最初のコメントを書いてみませんか。

送信するとすぐに公開されます。メールアドレスや電話番号などの個人情報は書かないでください。URL は 2 つまでです。

0 / 1000 文字

このフォームは reCAPTCHA で保護されており、Google のプライバシーポリシーと利用規約が適用されます。

同じリポジトリのスキル

blender

無料

How to programmatically create, modify, and verify Blender 3D scenes using Python bpy (headless background mode, .blend files, render output). For setup-gen and reward-gen agents.

日本語の概要は準備中です。原文の説明を表示しています。

xlang-ai/CUA-Gym2242026年8月13日 更新

chrome

無料

How to programmatically set up, control, and verify Google Chrome browser state using Python (Playwright CDP, SQLite, JSON configs). For setup-gen and reward-gen agents.

日本語の概要は準備中です。原文の説明を表示しています。

xlang-ai/CUA-Gym2242026年8月13日 更新

drawio

無料

How to programmatically set up, manipulate, and verify draw.io diagram state using Python (Playwright CDP, XML injection via Edit Diagram menu, DOM verification). For setup-gen and reward-gen agents.

日本語の概要は準備中です。原文の説明を表示しています。

xlang-ai/CUA-Gym2242026年8月13日 更新

How to programmatically set up, manipulate, and verify Excalidraw whiteboard state using Python (Playwright CDP, localStorage JSON, scene elements). For setup-gen and reward-gen agents.

日本語の概要は準備中です。原文の説明を表示しています。

xlang-ai/CUA-Gym2242026年8月13日 更新

gimp

無料

How to programmatically create, modify, and verify images using Python Pillow, NumPy, OpenCV, and scikit-image. For setup-gen and reward-gen agents.

日本語の概要は準備中です。原文の説明を表示しています。

xlang-ai/CUA-Gym2242026年8月13日 更新

grafana

無料

How to set up and manipulate Grafana dashboard, alerting, and admin state via HTTP APIs for CUA-Gym tasks. For setup-gen and reward-gen agents.

日本語の概要は準備中です。原文の説明を表示しています。

xlang-ai/CUA-Gym2242026年8月13日 更新

xlang-ai のスキルをすべて見る

このスキルの問題を報告する