Skip to content

Create skill for scaffolding a external workflow#635

Open
mimiliaogo wants to merge 4 commits into
isaac-sim:mainfrom
mimiliaogo:mimil/create-arena-external-workflow-skill
Open

Create skill for scaffolding a external workflow#635
mimiliaogo wants to merge 4 commits into
isaac-sim:mainfrom
mimiliaogo:mimil/create-arena-external-workflow-skill

Conversation

@mimiliaogo
Copy link
Copy Markdown

@mimiliaogo mimiliaogo commented Apr 24, 2026

  • Adds a Claude skill that scaffolds a new external IsaacLab-Arena project: directory structure, pyproject.toml, Dockerfile, run_docker.sh, and entrypoint.sh
  • IsaacLab-Arena is baked into the docker image at /opt/arena/; user project is bind-mounted at /workspaces/<project_name>/ for live editing
  • Dockerfile, run_docker.sh, and entrypoint.sh are described as targeted deltas from Arena's source files so the skill stays in sync with upstream
  • External environments are registered via Arena's existing --external_environment_class_path flag

Signed-off-by: Mimi Liao <mimil@nvidia.com>
Copy link
Copy Markdown
Contributor

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Isaac Lab Review Bot

Summary

This PR adds a Claude skill definition file (.claude/skills/arena-scaffold-external-workflow/SKILL.md) that documents how to scaffold external projects that build on IsaacLab-Arena. The skill is documentation/instructions for an AI assistant, not executable code. It describes creating directory structures, Docker configurations, and git submodule setups for external workflows.

Architecture Impact

Self-contained. This is a skill definition file for Claude Code (an AI coding assistant) that lives in .claude/skills/. It doesn't affect Isaac Lab runtime, imports, or any executable code paths. The scaffolding instructions reference Arena's Docker infrastructure but don't modify it.

Implementation Verdict

Minor fixes needed — documentation inconsistencies and a potential issue with the pyproject.toml template.

Test Coverage

Not applicable for a skill documentation file. However, the skill itself includes a verification step (lines 282-298) that validates the scaffolded project works correctly.

CI Status

No CI checks available. For a documentation-only file in .claude/skills/, this is acceptable, though a markdown lint check would be beneficial.

Findings

🟡 Warning: SKILL.md:11 — Inconsistent command name
The skill is named arena-scaffold-external-workflow in the frontmatter (line 2), but the invocation command is /arena-create-external-workflow. These should match for discoverability. The completion message (line 298) also uses arena-create-external-workflow.

name: arena-scaffold-external-workflow  # line 2
/arena-create-external-workflow <project_name>  # line 11

🟡 Warning: SKILL.md:95-97 — pyproject.toml include pattern may not work as intended
The pattern "isaaclab_arena_environments*" in [tool.setuptools.packages.find] won't match <project_name>/isaaclab_arena_environments because setuptools finds packages relative to the project root. The nested package should be discovered automatically via "<project_name>*" since it's under that directory. Including it separately suggests it should be a top-level package, which contradicts the directory structure shown in lines 61-67.

include = ["<project_name>*", "isaaclab_arena_environments*"]

Either move isaaclab_arena_environments to be a top-level directory, or remove it from the include list since <project_name>* should capture nested packages.

🔵 Improvement: SKILL.md:18-19 — Grammar issue in prerequisites
"Before running this skill, make sure user must have" should be "Before running this skill, the user must have" or "Before running this skill, make sure the user has".

🔵 Improvement: SKILL.md:131 — Dockerfile default value mismatch
The Dockerfile ARG ARENA_IMAGE=isaaclab_arena:latest uses :latest as default, but the run_docker.sh instructions (lines 163-165) explain that DOCKER_VERSION_TAG will be something like cuda_gr00t_gn16. The default value will never be used in practice since it's always overridden, but having :latest as a default is misleading since that tag likely won't exist.

🔵 Improvement: SKILL.md:287-288 — Key path table inconsistency
The table shows "IsaacLab" with container path /workspaces/isaaclab_arena/submodules/IsaacLab and host source "(baked into image)", but earlier documentation (lines 245-248) explains that the submodule must be initialized on the host because it's volume-mounted at runtime. The host source column should reference submodules/IsaacLab-Arena/submodules/IsaacLab/.

🔵 Improvement: SKILL.md:134-143 — Missing WORKDIR instruction in Dockerfile
The Dockerfile template doesn't set WORKDIR /workspaces/<project_name>, which would be helpful for users who exec into the container and expect to land in their project directory. The base image likely sets a different working directory.

@mimiliaogo mimiliaogo changed the title Create skills for scaffolding a external workflow Create skill for scaffolding a external workflow Apr 24, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new Claude skill to scaffold an external IsaacLab-Arena–based workflow/project, including project structure, packaging stub, and Docker build/run instructions that reuse the Arena base image.

Changes:

  • Introduces /arena-… skill documentation for scaffolding an external workflow project layout.
  • Specifies a thin project Dockerfile that builds from isaaclab_arena:latest and installs the new package editable.
  • Describes how to patch Arena’s run_docker.sh to build a two-stage image flow and mount both Arena + project sources.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .claude/skills/arena-scaffold-external-workflow/SKILL.md Outdated
Comment thread .claude/skills/arena-scaffold-external-workflow/SKILL.md Outdated
Comment on lines +101 to +106
[tool.setuptools.packages.find]
include = ["<project_name>*", "isaaclab_arena_environments*"]
```

The `include` list must cover both your top-level package and `isaaclab_arena_environments` so they are both importable after `pip install -e`.

Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The suggested pyproject.toml package discovery guidance is inconsistent with the directory layout shown in Step 3/Host layout. With isaaclab_arena_environments/ nested under <project_name>/, it will be discovered as <project_name>.isaaclab_arena_environments and already matches <project_name>*; the separate include pattern isaaclab_arena_environments* won’t match anything unless it’s a top-level package. Please either adjust the layout to make isaaclab_arena_environments top-level, or simplify the include list and update the explanation accordingly.

Copilot uses AI. Check for mistakes.
Comment on lines +207 to +217
**Change 3 — Replace the Arena volume mount and add the project mount** (in `DOCKER_RUN_ARGS`):

Replace:
```bash
"-v" "$SCRIPT_DIR/..:${WORKDIR}"
```
With:
```bash
"-v" "$ARENA_DIR:${WORKDIR}" # Arena submodule (live source)
"-v" "$SCRIPT_DIR/..:${PROJECT_WORKDIR}" # Project root (live source)
```
Copy link

Copilot AI Apr 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Change 3’s “Replace” snippet doesn’t match Arena’s current docker/run_docker.sh in this repo: it mounts the repo with "-v" ".:${WORKDIR}" (not $SCRIPT_DIR/..). As written, someone following these instructions won’t find the line to replace. Update the guidance to reference the actual mount line from Arena’s script (and then show the updated two-mount version).

Copilot uses AI. Check for mistakes.
Comment thread .claude/skills/arena-create-external-workflow/SKILL.md
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 24, 2026

Greptile Summary

This PR adds a new Claude Code skill (/arena-create-external-workflow) that scaffolds a complete external project built on top of IsaacLab-Arena, generating a directory layout, pyproject.toml, Dockerfile, run_docker.sh, and entrypoint.sh. The skill adapts Arena's own Docker infrastructure rather than duplicating it, keeping Arena as a baked dependency at /opt/arena while bind-mounting only the user's project at runtime.

  • Dockerfile scaffolding (Step 4): Introduces ARENA_DIR=/opt/arena to decouple the Arena install from the project WORKDIR, with five targeted changes to Arena's Dockerfile.isaaclab_arena. Change 1 contains an ordering bug: ENV ISAACLAB_PATH=${ARENA_DIR}/... is inserted after ARG INSTALL_GROOT (line 8) without removing the existing ENV ISAACLAB_PATH=${WORKDIR}/... at line 34; the later declaration wins, leaving ISAACLAB_PATH pointing to a non-existent path and breaking the build at RUN ${ISAACLAB_PATH}/isaaclab.sh -i.
  • run_docker.sh scaffolding (Step 5): Three changes update the image name, simplify the build block to a single stage, and replace the volume mount anchor; GR00T is removed from runtime mounts since it is baked into the image.
  • Python package / pyproject.toml (Step 2): Previously-flagged isaaclab_arena_environments* include entry has been removed; the package discovery now correctly uses only <project_name>*.

Confidence Score: 3/5

Not safe to merge as-is — the Dockerfile instructions will produce a broken image that fails to build.

Step 4 Change 1 inserts ENV ISAACLAB_PATH=${ARENA_DIR}/submodules/IsaacLab near the top of the Dockerfile without removing Arena's existing ENV ISAACLAB_PATH=${WORKDIR}/submodules/IsaacLab at line 34. Docker evaluates ENV declarations in source order, so the unmodified line 34 overrides the new one, baking the wrong path. After Change 2 moves IsaacLab to /opt/arena/, the build halts at RUN ${ISAACLAB_PATH}/isaaclab.sh -i with a missing-file error.

.claude/skills/arena-create-external-workflow/SKILL.md — specifically the Step 4 Dockerfile instructions around ENV ISAACLAB_PATH and ARG WORKDIR placement.

Important Files Changed

Filename Overview
.claude/skills/arena-create-external-workflow/SKILL.md New skill for scaffolding an external Arena workflow. A newly identified issue: Dockerfile Change 1 inserts ENV ISAACLAB_PATH=${ARENA_DIR}/... too early in the file without removing the existing ENV ISAACLAB_PATH=${WORKDIR}/... at line 34 of Arena's Dockerfile, causing the later declaration to override the fix and breaking the build at isaaclab.sh -i.

Reviews (4): Last reviewed commit: "Rework external workflow skill: /opt/are..." | Re-trigger Greptile

Comment on lines +9 to +12
/arena-create-external-workflow <project_name>
```

`<project_name>` is both the Python package name (e.g. `my_robot_tasks`) and the Docker image name. Use `snake_case`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Skill name / invocation mismatch

The frontmatter declares name: arena-scaffold-external-workflow, which means Claude Code registers the slash command as /arena-scaffold-external-workflow. The "How to invoke" section however documents /arena-create-external-workflow — a completely different name. Users following the docs will get a "skill not found" error.

Comment on lines +188 to +193
--file $ARENA_DIR/docker/Dockerfile.isaaclab_arena \
$ARENA_DIR
fi

# ── Stage 2: Project image ────────────────────────────────────────────────────
# Note: no --pull here — isaaclab_arena is a local image, not on Docker Hub.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 "Replace" snippet for main volume mount does not match source

The instruction tells Claude to replace "-v" "$SCRIPT_DIR/..:${WORKDIR}", but the actual Arena run_docker.sh line 129 reads "-v" ".:${WORKDIR}" (a bare ., not $SCRIPT_DIR/..). When Claude reads the real file and tries to match this "before" text it will fail to locate the target, producing an incorrect or skipped patch.

The correct "before" text should be:

"-v" ".:${WORKDIR}"

Comment on lines +195 to +200
if [ "$(docker images -q $DOCKER_IMAGE_NAME:$DOCKER_VERSION_TAG 2>/dev/null)" ] && \
[ "$FORCE_REBUILD" = false ]; then
echo "Docker image $DOCKER_IMAGE_NAME:$DOCKER_VERSION_TAG already exists. Not rebuilding."
else
docker build $NO_CACHE --progress=plain \
--build-arg ARENA_IMAGE="${ARENA_IMAGE_NAME}:${DOCKER_VERSION_TAG}" \
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 GR00T "before" snippet does not match source

The instruction shows "-v" "$SCRIPT_DIR/../submodules/Isaac-GR00T:..." as the line to replace, but the actual Arena run_docker.sh line 176 uses "-v" "./submodules/Isaac-GR00T:${WORKDIR}/submodules/Isaac-GR00T" (relative path, no $SCRIPT_DIR). The quoted "before" won't match, so Claude will leave the line untouched and the GR00T mount will still reference the wrong path at runtime.

Comment thread .claude/skills/arena-create-external-workflow/SKILL.md
Comment thread .claude/skills/arena-create-external-workflow/SKILL.md
└── docker/
```

**Why this matters:** Arena's `run_docker.sh` mounts the Arena repo at `/workspaces/isaaclab_arena`. Your project mounts alongside it at `/workspaces/<project_name>`. They are siblings, not nested.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we follow https://isaac-sim.github.io/IsaacLab-Arena/release/0.2.0/pages/arena_in_your_repo/external_installation.html#dockerfile
to layout the container workspace?

Just to be consistent with our doc.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The layout and Dockerfile mentioned in the doc doesn't work out of box without re-writing the existing Dockerfile. I decided to use two stages of image build since we don't want to maintain two similar Dockerfiles. I'm open to discuss what's a better solution.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings April 28, 2026 15:31
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review is ineligible. To be eligible to request a review, you need a paid Copilot license, or your organization must enable Copilot code review.

Copy link
Copy Markdown
Collaborator

@xyao-nv xyao-nv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much cleaner than the last MR! Thanks for cleaning it up!
One concern regarding the discrepancy from our doc vs what is implemented here, how Arena submodule is copied into the container and installed.

Would like to have this skill consistent with the doc to avoiding confusing users. Or any concern from our doc's dockerfile suggestion? We are also update the doc too.

Copy link
Copy Markdown
Contributor

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Isaac Lab Review Bot

Summary

This is a follow-up review. The new commit addresses the grammar issue from the previous review (line 18-19 now reads "make sure the user has the following in place").

Previous Findings Status

  • Grammar issue (line 18-19) — Addressed. Now reads "make sure the user has the following in place".
  • ⏸️ Command name inconsistency — Still present (arena-scaffold-external-workflow vs /arena-create-external-workflow).
  • ⏸️ pyproject.toml include pattern — Still present, may cause package discovery issues.
  • ⏸️ Other improvements — Dockerfile default tag, path table inconsistency, missing WORKDIR — unchanged.

Implementation Verdict

Minor fixes needed — the grammar fix is good, but the command name inconsistency and pyproject.toml pattern issues remain unaddressed from the previous review.

Comment thread .claude/skills/arena-create-external-workflow/SKILL.md
Redesign skill to bake IsaacLab-Arena into the image at build time
(cp -r into submodules/, COPY to /opt/arena) rather than using git
submodules and a two-stage image build. Adds entrypoint.sh as a
required output, decouples ISAACLAB_PATH from WORKDIR via ARENA_DIR,
and updates all three import checks to verify /opt/arena paths.

Signed-off-by: Mimi Liao <mimil@nvidia.com>
Comment thread .claude/skills/arena-create-external-workflow/SKILL.md
Copy link
Copy Markdown
Contributor

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Isaac Lab Review Bot

Summary

This PR adds a Claude skill for scaffolding external IsaacLab-Arena workflows. The skill provides comprehensive documentation for creating Docker-based projects that build on Arena. This is a documentation/skill file only—no runtime code changes.

Architecture Impact

Self-contained. This is a Claude skill definition file (.claude/skills/) that provides instructions for Claude to follow when users invoke the command. No impact on Isaac Lab runtime, APIs, or existing functionality.

Implementation Verdict

Minor fixes needed

Test Coverage

N/A — This is a documentation/skill file, not executable code. The skill includes verification steps for users to validate the scaffolded project works correctly.

CI Status

No CI checks available yet.

Findings

🟡 Warning: SKILL.md:1-3 — Skill name inconsistency between filename and frontmatter
The directory is named arena-scaffold-external-workflow but the frontmatter declares name: arena-create-external-workflow, and the invocation command is /arena-create-external-workflow. This inconsistency could cause confusion about the canonical command name. Either rename the directory to arena-create-external-workflow/ or update the frontmatter and invocation to use arena-scaffold-external-workflow.

🟡 Warning: SKILL.md:106 — pyproject.toml package discovery may fail

[tool.setuptools.packages.find]
where = ["."]
include = ["<project_name>*"]

The where = ["."] combined with the directory structure places pyproject.toml inside <project_name>/<project_name>/pyproject.toml, but the package is at <project_name>/<project_name>/ (same level). This means where should be [".."] to find the package, or the pyproject.toml should be at the project root (<project_name>/pyproject.toml). The current layout will likely fail to discover the package.

🔵 Improvement: SKILL.md:341 — Typo in completion message

arena-create-external-workflow complete — <project_name> createed.

"createed" should be "created".

🔵 Improvement: SKILL.md:324-327 — Verification paths inconsistent with layout
The verification ls command checks <project_name>/<project_name>/pyproject.toml but Step 2 shows writing to <project_name>/pyproject.toml (the header says <project_name>/pyproject.toml, not <project_name>/<project_name>/pyproject.toml). Clarify the actual intended path.

Redesign the scaffolding skill so that IsaacLab-Arena is baked into the
docker image at /opt/arena (never mounted), and only the user's project
is bind-mounted at /workspaces/<project_name>. Decouples ISAACLAB_PATH
from WORKDIR via a new ARENA_DIR variable.

- Replace git submodule + --reference with a plain cp -r from a local
  Arena clone, avoiding the alternates trap for teammates.
- Restructure Dockerfile guidance as deltas from Arena's source rather
  than duplicating the full file, so the skill stays in sync with Arena.
- Add docker/entrypoint.sh step (one-line change from Arena's: use
  ARENA_DIR instead of WORKDIR for the _isaac_sim symlink).
- Simplify run_docker.sh to a single-stage build; drop the Arena and
  Isaac-GR00T volume mounts since both are now baked.
- Drop the isaaclab_arena_environments package conflict by registering
  external environments via --external_environment_class_path instead
  of namespace shadowing.
- Move pyproject.toml to project root for standard find_packages
  discovery; exclude submodules/ from the package scan.
- Rename skill directory to match the invocation command.

Signed-off-by: Mimi Liao <mimil@nvidia.com>
Copilot AI review requested due to automatic review settings May 5, 2026 21:49
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .claude/skills/arena-create-external-workflow/SKILL.md
Comment thread .claude/skills/arena-create-external-workflow/SKILL.md
Comment thread .claude/skills/arena-create-external-workflow/SKILL.md
Comment thread .claude/skills/arena-create-external-workflow/SKILL.md
Comment thread .claude/skills/arena-create-external-workflow/SKILL.md
Comment thread .claude/skills/arena-create-external-workflow/SKILL.md
Copy link
Copy Markdown
Contributor

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤖 Isaac Lab Review Bot

Summary

All previous findings have been addressed in this update.

Follow-up Assessment

Previous concern about skill name inconsistency — The directory has been renamed from arena-scaffold-external-workflow/ to arena-create-external-workflow/, matching the frontmatter and invocation command.

Previous concern about pyproject.toml package discovery — The document now clearly shows pyproject.toml at the project root (<project_name>/pyproject.toml) in Step 2, and the layout diagram confirms this placement. The where = ["."] is now correct.

Previous typo "createed" — Fixed to "created" on line 343.

Previous verification path inconsistency — The verification ls command (line 324) now correctly references <project_name>/pyproject.toml (not <project_name>/<project_name>/pyproject.toml), consistent with the Step 2 instructions.

CI Status

The "Cleanup artifacts: failure" appears unrelated to this PR's changes (it's a workflow maintenance task, not a code issue).

Implementation Verdict

Ship it

Comment thread .claude/skills/arena-create-external-workflow/SKILL.md
@mimiliaogo mimiliaogo requested a review from xyao-nv May 5, 2026 22:02
git init

# Copy Arena into the project — used only at docker build time, not at runtime
cp -r ~/IsaacLab-Arena submodules/IsaacLab-Arena
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pseudo link might be better, right? Single place for src code.

Copy link
Copy Markdown
Collaborator

@xyao-nv xyao-nv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTC. Thank you for patiently iteraley with me over the past few weeks. +1 given.
Passing to my coworker @cvolkcvolk for another +1 before merging.

@xyao-nv
Copy link
Copy Markdown
Collaborator

xyao-nv commented May 13, 2026

Just curious, @mimiliaogo how do you expect skills to be tested on CI? Any practice your team is doing?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants