Community코딩 & 개발github.com

Sim Env Builder

설명을 바탕으로 MuJoCo 또는 NVIDIA Isaac Sim에서 3D 시뮬레이션 환경(로봇, 강화학습, 자율주행 등)을 구축합니다. 백엔드를 선택하고, 사용자와 사양을 확인한 후, Poly Pizza MCP에서 3D 모델을 가져오거나 절차적 생성으로 대체하여 테스트된 Gym 스타일 환경을 제공합니다.

Sim Env Builder란 무엇인가요?

이 스킬은 사용자의 자연어 설명을 기반으로 물리적으로 정확하고 시각적으로 우수한 3D 시뮬레이션 환경을 자동으로 구축합니다. MuJoCo와 NVIDIA Isaac Sim 중 최적의 백엔드를 선택하며, 사용자와의 확인 절차를 통해 사양을 명확히 하고, 3D 에셋은 Poly Pizza MCP에서 검색하거나 절차적 생성을 통해 확보합니다. 최종적으로 Gymnasium 스타일의 강화학습 환경, 스크립트 기반 데모 컨트롤러, 그리고 물리 및 렌더링 검증을 위한 일련의 스모크 테스트를 제공합니다. 로봇공학 연구자, 강화학습 엔지니어, 자율주행 개발자에게 적합하며, 빠른 프로토타이핑과 재현 가능한 실험 설정에 특히 유용합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/YangLiu68/sim-env-builder/tree/HEAD/plugin/skills/sim-env-builder

Installed? Explore more 코딩 & 개발 skills: steipete/bluebubbles, steipete/eightctl, steipete/blucli · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Sim Env Builder은(는) 무엇을 하나요?

목표: 하나의 설명으로부터, 가능한 적은 사용자 턴(이상적으로: 요청 -> 한 번의 확인 -> 완료)으로 작동하고, 물리적으로 타당하며, 보기 좋은 시뮬레이션 환경을 제공합니다. 품질 기준: 모든 스모크 테스트를 통과해야 하며, 렌더링 결과를 직접 확인하여 요청 사항과 일치하는지 확인해야 합니다.

SKILL_DIR 아래 = 이 파일의 디렉토리. Python 헬퍼는 SKILL_DIR/scripts/simkit에 있습니다.

Phase 0 - 설정 (1분)

PY=$(bash SKILL_DIR/scripts/setup_env.sh)       # python with mujoco, trimesh, usd-core, gymnasium
$PY SKILL_DIR/scripts/check_platform.py           # OS, GPU, Isaac 가용성 확인

환경 폴더 선택: 사용자가 지정하지 않은 경우 현재 디렉토리에 ./<짧은_뱀_이름>/을 생성합니다.

Phase 1 - 백엔드 선택 (reference/backend_choice.md 참조)

Isaac Sim은 NVIDIA RTX GPU가 장착된 Linux/Windows가 필요합니다. MuJoCo는 어디서나 실행됩니다.

  • MuJoCo: 기본값. 접촉이 많은 조작 및 보행, 빠른 반복, CPU/노트북/macOS, 소형-중형 장면, 모델 기반 제어, 재현 가능한 연구, MJX/Warp를 통한 GPU RL에 적합합니다.
  • Isaac Sim: 사실적인 RTX 렌더링 또는 합성 데이터(Replicator), RTX 라이다/카메라 센서 현실감, Isaac Lab에서 수천 개의 병렬 환경, 대규모 USD/Omniverse 장면, 사용자가 이미 Isaac을 사용 중인 경우에 적합합니다.
  • Isaac이 더 적합하지만 isaac_runnable_here가 false인 경우, 확인 메시지에 그 사실을 명시하고 다음을 제안합니다: 여기 MuJoCo에서 빌드 + 완전히 테스트하고, USD 스테이지와 Isaac 스모크 스크립트를 GPU 머신용으로 내보내기(reference/isaac.md 참조). 실제로 실행하지 않은 Isaac 결과를 주장하지 마십시오.

Phase 2 - 빌드 전 사용자 확인 (reference/confirmation.md 참조)

  1. 먼저 빠른 에셋 스캔을 수행하여 브리프를 구체화합니다: find_assets 호출 한 번(Poly Pizza MCP)으로 각 객체 역할에 대해 1-3개의 쿼리를 실행합니다.
  2. 하나의 짧은 브리프(reference/confirmation.md 템플릿)를 보냅니다: 백엔드 및 이유, 장면에 포함될 내용, 로봇/에이전트 및 제어 인터페이스, Poly Pizza vs 절차적 생성에서 가져올 에셋, 주요 물리 속성(중력, 마찰, 시간 간격), 결과물, 그리고 각각 권장 기본값이 포함된 2-4개의 질문.
  3. AskUserQuestion 도구가 있으면 사용하여 질문합니다. 그렇지 않으면 브리프를 메시지로 전달하고 사용자 응답을 기다립니다. 사용자가 응답하기 전에 빌드하지 마십시오. 예외: 사용자가 묻지 말라고 하거나 "그냥 빌드해"라고 한 경우 -> 가정을 SPEC.md에 기록하고 진행합니다.
  4. 확인된 결정을 <env>/SPEC.md에 기록합니다(reference/confirmation.md 템플릿).

Phase 3 - 에셋: Poly Pizza 우선, 절차적 생성 대체 (reference/assets.md 참조)

각 객체 역할에 대해:

  1. find_assets / search_models -> 결과 확인(발견됨 / 부족함 / 없음).
  2. 발견됨 또는 부족함 -> preview_models([...ids]) 직접 확인: 올바른 객체인가? 스타일 일관성? 사실적인 장면에서 장난감, 만화 스타일, 다중 객체 번들, 잘못된 크기 등급은 거부합니다.
  3. 수락됨 -> download_model(id, "<abs env path>/assets/polypizza", "<role>") (크레딧은 assets/polypizza/CREDITS.md에 자동 기록됨).
  4. 없음, 거부됨 또는 다운로드 오류 -> 절차적 생성: simkit.procedural 레시피(나무, 건물, 가구, 거리 소품, 문, 식기류, 지형...)를 사용하거나 기본 요소 / lathe / extrude / rock으로 직접 구성합니다. 요청된 객체를 절대 빠뜨리지 마십시오.
  5. <env>/assets/ASSETS.md 작성: 역할 | 출처(Poly Pizza ID + 제목 + 라이선스, 또는 절차적 생성 레시피) | 실제 크기 | 이유. 모델 제목이 역할과 다른 경우("Park Bench"를 피크닉 테이블로 사용한 경우), 그 이유와 여전히 적합한 이유를 명시하거나 다시 검색/절차적 생성합니다. 또한 거부된 후보(ID + 이유: "만화 스타일", "12개 객체 번들")를 나열하여 모든 것이 절차적 생성으로 처리되더라도 검색 내역을 추적 가능하게 합니다. Poly Pizza 모델은 정적 메시입니다: 관절 로봇과 차량은 simkit.robots에서 가져옵니다(Poly Pizza 메시를 시각적 기하 형상으로 스킨할 수 있음).

Phase 4 - 빌드 (reference/robots.md, templates/ 참조)

mkdir -p <env> && cp -r SKILL_DIR/scripts/simkit <env>/simkit       # vendored: env is self-contained
cp SKILL_DIR/templates/build_env.py SKILL_DIR/templates/env.py SKILL_DIR/templates/view.py <env>/   # 처음 두 개는 편집
  • build_env.py: 모든 것을 결정론적으로(시드 고정) 재생성 -> scene.xml. simkit.scene.Scene (하늘, 바닥, 조명, 시점 카메라, raw MJCF 섹션), simkit.assets.glb_to_mujoco(glb, env, name, target={"height": m}, yaw_deg=..) (Poly Pizza 모델 처리: 실제 크기, Z-up, 색상별 파트, box/hull/parts 충돌), simkit.procedural (대체 및 지형), simkit.robots (테스트된 로봇: 쿼드로터, 자동차, 차동 구동, 암 + 그리퍼, 사족 보행) 및 해당 컨트롤러를 사용합니다.
  • 실제 세계 스케일은 필수입니다(reference/assets.md 크기 표 참조). 객체는 지지면 위에 놓입니다.
  • 사용자가 지정한 모든 객체 클래스는 개요에서 읽을 수 있는 크기로 명확하게 보여야 합니다("바위 투성이 길"에는 눈에 띄는 바위가 있어야 하며 7cm 알갱이가 아니어야 함; "험준한 지형"에는 로봇 스케일에서 보이는 요철이 있어야 함). 스모크 테스트는 hints 아래에 작은 객체를 나열합니다.
  • 최소 2개의 명명된 카메라: 개요 카메라와 대상(로봇/작업 객체가 프레임의 약 30-50%를 채움)에 초점을 맞춘 카메라; 로봇 장착 카메라(있는 경우). 고정 센서 카메라는 로봇의 초기 자세에 의해 가려지면 안 됩니다(스모크가 15% 이상 가려짐 플래그).
  • world.py (장면에 자체 동역학이 있는 경우): make_world(model) -> world(model, data), 스모크, 검사자, 쇼케이스, env.py, view.py 및 대시보드에서 모든 물리 단계 전에 호출됩니다. 부력/항력, 바람, 컨베이어, 신호등 주기, 스크립트된 보행자 및 NPC 차량은 여기에 위치하며, controller.py 내부에는 절대 위치하지 않습니다(수동 테스트나 RL 정책은 보트가 가라앉고 조명이 절대 변하지 않는 세계를 실행하게 됩니다). 작업 검사도 이 함수를 호출해야 합니다.
  • controller.py: 스크립트된 데모 정책(make_controller(model) -> ctrl(model, data))으로 환경이 제 역할을 수행하는 것을 보여줍니다(드론이 게이트를 통과, 자동차가 경로를 주행, 암이 객체에 도달...). 모듈 수준에서 DEMO_SECONDS = <전체 데모 길이>를 설정합니다: 스모크 테스트는 전체 데모(집기, 들어올리기, 놓기 / 모든 게이트)를 촬영하고 확인하며, 처음 4초만 확인하지 않습니다.
  • task_checks.py: 함수 check_<name>(model, data) -> {"status", "value", "expect", "details"} 형태로 작업 수준의 물리 검사를 정의합니다. 사용자가 명시했거나 확인한 각 성공 기준에 대해 하나의 검사(이름은 사용자의 말을 따름: "feet in contact" -> check_feet_in_contact), 그리고 생성 상태 검사(로봇이 지지면 위에서 시작)를 포함합니다. 최소 2개. 첫 번째 실행 전에 임계값과 각 지표의 정확한 정의(기준점, 단위: "로버 베이스 중심에서 착륙선 중심까지, 미터")를 SPEC.md에 기록하고 유지합니다: 근소한 차이는 컨트롤러/장면을 수정하는 의미이므로 검사를 완화하지 마십시오(임계값 변경은 "확인된 계획의 변경 사항" 아래에 표시되어야 함). 제한의 15% 이내로 통과하는 검사는 여유를 보고합니다("기울기 25.8도 vs 30도 제한"). 주장하는 모든 동작(장애물 감속, 신호등 주기, 부력, 그리퍼 유지)은 이를 실행하는 검사가 필요합니다(예: 경로에 장애물을 배치하고 로봇이 정지하는지 확인). 장면의 모든 주요 물리 속성은 물리적 목표가 있는 측정 검사를 받습니다: 공의 구름 감속, 보트의 흘수선, 로버의 경사 오르기, 저중력 낙하 시간, 그리퍼 유지력. 필수 센서도 검사합니다: 데모 중 로봇 카메라를 렌더링하고 작업을 보여주는(예: 앞쪽 나무 줄) 비어 있지 않은 이미지를 확인합니다. 라이다의 경우, 합리적인 범위를 확인합니다. 각 작업 검사를 스크립트된 롤아웃과 2-3개의 변형된(다른 시드, 시작 자세, 초기 속도, 조명 위상) 경우에 대해 실행합니다 - 단 하나의 정확한 롤아웃에만 유효한 검사는 증명력이 거의 없습니다. 파지 검사는 들어올리기 및 운반 중에 두 핑거 패드와 객체 사이의 접촉을 요구하며(data.contact 확인), 단순히 "객체가 올라갔다"가 아닙니다.
  • 충돌체: 단순하고 정직합니다. 나무: 줄기 충돌체, 캐노피는 시각적 전용(사용자가 캐노피 충돌을 원하는 경우 제외). 멀티로터: 팔 캡슐 또는 단일 덩어리, 프로펠러를 삼키는 하나의 박스가 아닙니다. 볼록하지 않은 소품(현미경, 의자, 아치, 선반)은 collision="parts" 또는 몇 개의 기본 요소를 사용합니다. 하나의 볼록 껍질은 시각적으로 비어 있는 공간을 차단합니다(collision_sheet.png 확인).
  • env.py: Gymnasium 스타일의 reset/step/render 인터페이스로 작업 관찰, 보상 스텁, 종료 조건을 포함합니다. __main__ 자체 테스트는 데모 컨트롤러(또는 참조 정책)를 사용하여 env API를 통해 환경을 구동하고 작업 목표에 도달했는지 출력합니다 - 목표에 도달 가능함을 증명합니다.
  • 디버그/카메라 리그 본체 및 마커: geom 그룹 4-5(절대 렌더링되지 않음), 데이터 카메라에 포함되지 않음.
  • 매달린 물체(천장 조명, 걸린 표지판, 벽 선반): mounted_* 또는 hanging_*으로 명명하여 부유 객체 검사에서 건너뛰도록 합니다.
  • 조명: 중성 흰색(색조가 없는 조명); 최대 2-3개의 추가 조명; 흰색 벽이 렌더링에서 흰색-회색으로 유지되는지 확인합니다.
  • 장면을 올바르게 읽는 데 필요한 것 이상의 요청되지 않은 장식은 추가하지 않습니다. 선택적 추가 사항은 브리프에 나열하여 사용자가 선택할 수 있게 합니다.
  • 시간 제한: 빌드를 시작할 때 시간을 기록합니다(date). 추가/확장 항목("접기는 추가 항목")은 필수 항목이 모두 통과한 후에만 시도하며, 가장 먼저 제외됩니다. 빌드 시작 후 약 60분이 지나면 남은 항목 튜닝을 중단하고 REPORT.md와 README 결과를 최종 확정하고 보고합니다(제외된 항목 나열). 결과를 보고하지 않는 빌드는 알려진 격차가 있는 빌드보다 나쁩니다.
  • 예산: 모든 필수 항목이 존재하고 모든 검사가 통과되면 추가 항목을 중단하고 - 시각적 검사, README 및 보고서를 마무리합니다. 추가 아이디어는 README에 기재합니다.
  • 모든 변경 후 $PY build_env.py를 실행합니다. 컴파일 오류는 줄 번호를 포함합니다.

Phase 5 - 스모크 테스트 (reference/smoke_tests.md 참조). 세 가지 모두 필요합니다.

cd <env> && $PY -m simkit.smoke scene.xml --out smoke --controller controller.py --task-checks task_checks.py
  1. 렌더 테스트 - 모든 명명된 카메라 + 자동 뷰가 비어 있지 않고, 조명이 잘 들어오며, 상세한 프레임을 렌더링합니다. 세분화는 어떤 객체가 보이는지 보여줍니다(보이지 않는 객체는 플래그 지정됨).
  2. 물리 검사자 - 장면 자체 설정을 사용한 솔버/접촉/마찰/중력 프로브, 롤아웃 안정성, 관통, 낙하, 안정화, 액추에이터 단계 응답, 결정론, 시간 간격 민감도, 실시간 계수, 레이아웃(부유/침강/상호 관통 소품) 및 작업 검사.
  3. 시각적 검사 - 직접 smoke/contact_sheet.png, smoke/filmstrip.png, smoke/collision_sheet.png 및 smoke/renders/의 클로즈업을 열어보고(읽기 도구 사용), 그런 다음 smoke/visual_check.md에 구체적인 관찰 결과를 채워 넣습니다. 모든 FAIL을 수정합니다. 모든 WARN을 조사합니다(수정하거나, README에서 예상된 이유 설명). 결과가 PASS / PASS_WITH_WARNINGS(설명됨)이고 시각적 검사가 정직하게 모두 "예"가 될 때까지 다시 빌드하고 다시 실행합니다. 2-3회 반복을 예상하십시오. 첫 번째 렌더링은 거의 정확하지 않습니다. 또한 $PY env.py를 실행합니다(무작위 행동, 유한 관찰).

Phase 6 - Isaac Sim 결과물 (Isaac이 선택된 경우에만; reference/isaac.md 참조)

$PY -m simkit.usd_export scene.xml isaac/scene.usda (내보내기 + 로컬 검증), SKILL_DIR/templates/isaac_smoke.py를 isaac/로 복사하고, GPU 머신에서 실행하는 방법을 문서화합니다. 실행된 것과 실행되지 않은 것을 명확히 명시합니다.

Phase 7 - 전달

<env>/README.md: 장면에 포함된 내용, 실행 방법(빌드, 스모크, env, 뷰어: $PY view.py는 데모 컨트롤러를 실시간으로 실행합니다; 일반 mujoco.viewer는 수동 물리만 표시함), 카메라, 액추에이터, 컨트롤러, 작업 검사, 에셋 크레딧, 알려진 제한 사항. 사용자에게 보내는 최종 메시지: 결과 한 줄, 빌드된 내용, Poly Pizza vs 절차적 생성에서 가져온 에셋, 스모크 결과, smoke/showcase.mp4 (사람들이 시청하는 비디오), contact_sheet 및 filmstrip 경로, 완료되지 않았거나 확인되지 않은 모든 것, 그리고 "확인된 계획의 변경 사항" 목록(에셋 또는 라이선스 교체, 크기/개수 변경, 추가 항목 제외) - 변경 사항이 없으면 비어 있지만 항상 포함됩니다. smoke/smoke_report.json 및 physics_report.json에서 모든 숫자(통과한 검사, 점수, 오류)를 복사하고, summary_line을 있는 그대로 붙여넣습니다("Smoke PASS: examiner 19 pass / 0 warn / 0 fail; task checks 9/9 pass; render ok"). 절대 기억에서 개수를 작성하지 마십시오. 첫 번째 스모크 실행이 완료되는 즉시 <env>/REPORT.md를 시작하고 각 수정 후 업데이트하여 중단된 세션에도 보고서가 남도록 합니다. 최종 메시지는 마지막 버전입니다.

결과물 레이아웃 (정확히 유지; 도구와 대시보드가 이에 의존함)

<env>/
  SPEC.md  README.md  REPORT.md  build_env.py  scene.xml  env.py  view.py  controller.py  task_checks.py
  world.py                      (장면에 자체 동역학이 있는 경우에만)
  simkit/                       vendored helpers
  assets/polypizza/*.glb  assets/polypizza/CREDITS.md  assets/polypizza/polypizza_assets.json
  assets/meshes/  assets/procedural/  assets/ASSETS.md
  smoke/  (showcase.mp4 contact_sheet.png filmstrip.png collision_sheet.png renders/ rollout.mp4
           physics_report.json render_report.json smoke_report.json env_manifest.json
           SMOKE.md visual_check.md)
  isaac/  (Isaac인 경우에만: scene.usda, isaac_smoke.py, README section)

경험상의 규칙 (각각은 실제 빌드를 망가뜨린 적이 있습니다)

  • 확인된 범위 내에 머무릅니다. 데모는 사용자가 동의한 내용을 보여줍니다(예: "서 있는 것으로 충분하다"는 안정적인 서기이지, 새로운 보행 컨트롤러가 아님). 장면, 에셋, 검사 및 시각적 검토에 시간을 사용하고, 확장 아이디어는 README에 나열합니다.
  • <visual> 설정: sc.set_visual("map", znear=.., zfar=..) 등. 각 요소는 한 번만 나타날 수 있습니다.
  • camera xyaxes를 수동으로 계산하지 마십시오: Scene.camera(name, pos, target) / simkit.scene.lookat을 사용합니다.
  • 키프레임 qpos 목록을 수동으로 작성하지 마십시오: scene.home[joint] = value를 설정합니다(로봇이 자동으로 수행). Scene.write는 조인트 이름으로 home 키프레임을 작성하고 일치하도록 position-actuator ctrl을 설정합니다.
  • 평평한/얇은 메시는 inertia="shell"이 필요합니다(glb_to_mujoco가 처리). 시각적 기하 형상: contype=0 conaffinity=0 group=2 mass=0; 충돌 프록시는 group 3.
  • 세계에 용접된 로봇은 자체 베이스와 충돌합니다: 베이스/첫 번째 링크에 <exclude>를 추가합니다.
  • Position-actuator @forcelimited/@forcerange 및 @ctrlrange를 설정합니다(기본값은 무제한, 드론이 달아날 수 있음).
  • assetdir: dir=의 절대 경로가 필요합니다(편집기 재시작/다른 CWD 후 깨짐 방지). simkit.scene.Scene이 이를 처리합니다.
  • 점-질량 기하 형상은 충돌에 참여하지 않습니다: 실제 객체에는 pos="0 0 0" mass="..." 점-질량 대신 simkit.assets.box 또는 sphere를 사용합니다.
  • Python 스크립트에서 cd <env>를 상대 경로 앞에 사용하거나, 절대 경로를 사용합니다.
  • 검사자가 렌더링하기 전에 controller.py와 world.py가 make_controller(model), make_world(model)을 내보내는지 확인합니다(모듈 최상위 수준에서 조건부 임포트 허용).
  • 큰 고도 변화가 있는 지형을 위한 바닥: size="100 100 0.1" pos="0 0 -2" 대신 simkit.procedural.terrain을 사용합니다.
  • 이미 있는 파일을 다시 쓰기 전에 사용자에게 물어봅니다. 실수로 작업을 덮어쓰지 마십시오.
  • 절대 SKILL_DIR 아래의 파일을 수정하지 마십시오. 모든 생성된 파일은 <env>/ 아래에 있습니다.
  • @tendon, @sensor, @wrap 객체는 scene XML 트리의 <worldbody> 외부에 있어야 합니다. Worldbody 요소로 오인하지 마십시오.
  • default 클래스 <geom .../>에 group을 설정하지 마십시오(모든 기본값 상속 geom의 그룹을 재정의함). 각 geom에 group을 명시적으로 설정합니다.

중요: 스킬 디렉토리 참조

이 스킬에 대한 문서, 도움말 및 템플릿은 다음에 있습니다: SKILL_DIR/reference/ SKILL_DIR/templates/ SKILL_DIR/scripts/

SKILL_DIR 아래의 모든 것(이 파일 제외)은 Read 도구로 읽거나 Bash 도구로 실행할 수 있습니다. simkit Python 패키지가 거기에 있습니다: SKILL_DIR/scripts/simkit/.

check_platform.sh는 scripts/ 아래의 스크립트 중 하나입니다. setup_env.sh는 scripts/ 아래에 있습니다.

시작할 때: PY=$(bash SKILL_DIR/scripts/setup_env.sh)를 실행하십시오. 필요한 패키지가 설치되어 있지 않으면 약 30초가 소요됩니다. scripts/simkit/를 무언가에 import simkit 하기 전에 sys.path에 추가해야 할 수도 있습니다.

레시피 빌더: scripts/simkit/procedural/.

스모크 테스트 러너: scripts/simkit/smoke/.

Mujoco 장면 유틸리티: scripts/simkit/scene.py.

로봇: scripts/simkit/robots/.

작업 검사 프레임워크: scripts/simkit/task_checks.py, scripts/simkit/physics_examiner.py.

에셋 다운로드: scripts/simkit/assets/.

Isaac 내보내기: scripts/simkit/usd_export/.

템플릿: templates/ (build_env.py, env.py, view.py가 거기에 있음).

scripts/check_platform.py를 실행하면 OS(Windows/macOS/Linux), GPU(없음, NVIDIA RTX), 그리고 isaac_runnable_here 플래그(True/False)를 가져옵니다.

규칙 1: 어떻게 불려도 "phases"를 건너뛰지 마십시오. Phase 1에서 백엔드를 선택하고 Ant를 빌드하기 전에 Phase 2에서 확인하십시오. 확인되지 않은 빌드는 실패한 빌드입니다.

규칙 2: 절대 호기심에 에셋을 검색하지 마십시오: 브리프에 구체적인 객체가 없으면 find_assets를 호출하지 마십시오. 중립적인 "무엇을 배치해야 하나요?"는 시간 낭비입니다. 사용자의 요청에 답하는 객체만 찾으십시오.

규칙 3: 사용자에게 단일 브리프를 던지고 여러 턴에 걸쳐 사양을 뽑아내지 마십시오. 모든 것을 하나로 합치십시오: 배경, 객체, 로봇, 작업, 검사, 선택적 추가 사항. 사용자가 이미 답변을 가지고 있습니다. 그러면 한 번의 확인만 있으면 됩니다.

규칙 4: 최종 메시지에는 항상 EXACT TEXT FROM smoke/smoke_report.json을 포함시키십시오.

규칙 5: 스모크가 PASS할 때까지 절대 전달하지 마십시오. 규칙 5b: 전달 여부를 사용자에게 묻지 마십시오 - 기준은 명확합니다: PASS.

(규칙을 잊을 경우 SKILL_DIR/README.md 참조, 이 스킬 문서와 동일함).

관련 스킬