Skip to content
Musher Docs

Working with Typed Handles

After pulling a bundle, you access its contents through typed handles — objects that provide structured access to each asset's metadata and content.

Asset Categories

Each bundle organizes assets into categories. Use the corresponding accessor method to get a list of typed handles:

MethodReturnsContent access
files()list[FileHandle].text(), .bytes()
skills()list[SkillHandle].skill_md(), .files()
prompts()list[PromptHandle].text()
toolsets()list[ToolsetHandle].text(), .parse_json()
agent_specs()list[AgentSpecHandle].text(), .parse_json()

Iterate All Assets

python
import musher

bundle = musher.pull("acme/code-review-kit")

# All files (every asset, regardless of type)
for fh in bundle.files():
    print(f"{fh.logical_path} ({fh.media_type or 'unknown'})")

# Skills only
for skill in bundle.skills():
    print(f"Skill: {skill.name}")
    print(f"  Description: {skill.description}")

# Prompts only
for prompt in bundle.prompts():
    print(f"Prompt: {prompt.name}")
    print(prompt.text())

# Toolsets (JSON content)
for toolset in bundle.toolsets():
    print(f"Toolset: {toolset.name}")
    config = toolset.parse_json()
    print(config)

Look Up a Single Asset

Use singular accessor methods to look up a specific asset by name. These raise KeyError (Python) or throw BundleAssetNotFoundError (TypeScript) if the asset is not found.

python
bundle = musher.pull("acme/code-review-kit")

# Look up by name (raises KeyError if not found)
skill = bundle.skill("code-review")
prompt = bundle.prompt("review-template")
toolset = bundle.toolset("lint-rules")

# Look up a file by logical path (returns None if not found)
readme = bundle.file("README.md")
if readme:
    print(readme.text())

Select a Subset

Use select() to filter a bundle to only the assets you need. This returns a filtered view with the same typed accessors but limited to the selected assets.

python
bundle = musher.pull("acme/code-review-kit")

# Select specific skills and prompts
selection = bundle.select(
    skills=["code-review", "security-scan"],
    prompts=["review-template"],
)

for skill in selection.skills():
    print(skill.name)

Skill Handles in Depth

SkillHandle is the richest handle type. Beyond the name and description, it provides access to the skill's content and supporting files:

python
skill = bundle.skill("code-review")

# The skill's SKILL.md content
skill_md = skill.skill_md()
print(skill_md.text())

# All files within the skill directory
for fh in skill.files():
    print(f"  {fh.logical_path}")

# Look up a specific file within the skill
config = skill.file("config.json")
if config:
    print(config.text())