Skip to content
Agentmart
Submit a tool

alias

Use when creating shortcut aliases for existing larch skills with preset flags.

Skill by character-ai

IndexedMIT★ 7
Write a review

Install

Works with Claude Code. Read the repository before you give any tool access to your data.

npx agentmarket install skill/character-ai-alias

Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.

Get the weekly diff

The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.

We use your email only for this newsletter. Privacy

About

Use when creating shortcut aliases for existing larch skills with preset flags. Routes plugin-source aliases to skills/ unless --private forces .claude/skills/.

No reviews yet. Installed it? Reviews come from verified installers only. How reviews work

Permissions

What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.

Tools
No tools found
Secrets
None asked for
Install scripts
None found

Network hosts it talks to 1

  • codeload.github.com · found in install command

Files it touches

  • ~/.claude/skills/alias

Tools it pre-approves 2

From allowed-tools in SKILL.md: the agent may use these without asking you each time.

  • Bash,
  • Skill

What's inside

Skill name
alias
Description
Use when creating shortcut aliases for existing larch skills with preset flags. Routes plugin-source aliases to skills/ unless --private forces .claude/skills/.
License
MIT
Allowed tools
Bash,, Skill
Instructions
203 lines in SKILL.md · view on GitHub

Before installing

  • Pre-approves some shell commands

Files (1)

  • SKILL.md

SKILL.md (first lines)

**MANDATORY: Follow the complete shared lifecycle contract in `${CLAUDE_PLUGIN_ROOT}/skills/shared/run-lifecycle.md` with declared skill `alias`.**

# Alias Skill

**MANDATORY: READ ENTIRE FILE before composing user-facing prose: `${CLAUDE_PLUGIN_ROOT}/skills/shared/readability-style.md`.**

This skill follows the Process pattern: numbered steps, checkpointed delegation, fail-closed verification.

Create an alias skill that forwards to an existing larch skill with preset flags. Delegates to `/implement` for the full pipeline (implementation, code review, PR), then verifies the artifact landed on disk.

**Target directory** is resolved automatically:

- A **git repository is required**: the helper (`"${CLAUDE_PLUGIN_ROOT}/scripts/larch.sh" alias resolve-target`) anchors all paths at the typed repository worktree and fail-closes outside a git working tree. Run `git init` first if you want to use `/alias` in a fresh project.
- Inside a Claude plugin source repo (detected via the two-file predicate `.claude-plugin/plugin.json` AND `skills/implement/SKILL.md` at the git repo root, matching `validate-args.sh`), the alias is generated under `skills/<alias-name>/SKILL.md` (exported plugin skill, ships with the plugin).
- In any other git repository (consumer repos with their own larch installation), the alias is generated under `.claude/skills/<alias-name>/SKILL.md` (dev-only repo-private skill).
- `--private` forces `.claude/skills/<alias-name>/` even inside a plugin repo (escape hatch when the operator wants a private alias in plugin source). In non-plugin repos `--private` is a no-op.

Example (in a plugin source repo): `/alias i implement --merge` creates `<repo-root>/skills/i/SKILL.md` so that `/i <feature>` is equivalent to `/implement --merge <feature>`.

Example (in a consumer repo, OR with `--private` in a plugin repo): `/alias i implement --merge` creates `<repo-root>/.claude/skills/i/SKILL.md` (dev-only).

Example with merge: `/alias --merge i implement --merge` creates the alias AND merges the PR after CI passes.

## NEVER

1. **NEVER create an alias that targets `/alias`**: no alias-to-alias recursion. **Why:** would multiply indirection and break the flat forwarding contract. Enforced by Step 2 check #5.
2. **NEVER let an alias name shadow an existing larch skill**: neither in `skills/` (public) nor `.claude/skills/` (dev-only). **Why:** shadowing silently reroutes `/<name>` invocations. Enforced by Step 2 check #2 via dynamic probe.
3. **NEVER auto-remediate when `VERIFIED=false` in Step 4**: do NOT retry `/implement`, roll back, or delete the PR. **Why:** under `--merge` the PR may already be merged; retry would create a divergent PR. Human judgment required.
4. **NEVER assume success on `VERIFIED=false` just because `/implement` returned.** **Why:** `/implement` can return cleanly while writing the file to the wrong path, skipping the generator, or failing silently: the sentinel-file gate is the only authoritative signal.
5. **NEVER parse `--merge` or `--private` tokens after the first positional argument as flags for `/alias`.** **Why:** both flags have a dual role (consumed by `/alias` when before the first positional; passed through to the alias's preset flags otherwise); conflating the two is a silent footgun.
6. **NEVER hardcode `.claude/skills/<alias-name>` or `skills/<alias-name>` paths anywhere in Steps 2/3/4: always thread `$TARGET_DIR`.** **Why:** the resolved target directory is the single source of truth (computed once at Step 2 by `alias resolve-target`); a partial edit that re-introduces a hardcoded path in one site (e.g., the `/implement` recipe) but not another (e.g., the verify sentinel) creates a silent path split where `/implement` writes one tree and Step 4 verifies a different tree. Enforced by `make test-alias-structure` (CI).
7. **NEVER use `eval "$("${CLAUDE_PLUGIN_ROOT}/scripts/larch.sh" alias resolve-target ...)"` to consume the helper's stdout.** **Why:** `eval` of a path that contains shell metacharacters (spaces, `$(...)`, backticks) creates shell-injection risk if the command's stdout contract ever drifts. Use the non-eval allowlist parser shown in Step 2's bash block.

**Anti-halt continuation reminder.** After every child `Skill` tool call (e.g., `/implement`) returns, IMMEDIATELY continue with this skill's NEXT numbered step: do NOT end the turn on the child's cleanup output, and do NOT write a summary, handoff, status recap, or "returning to parent" message: those are halts in disguise. The rule is strictly subordinate to any explicit non-sequential control-flow directive in THIS file (e.g., `bail`, `skip to Step N`). A normal sequential `proceed to Step N+1` instruction is the default continuation this rule reinforces, NOT an exception. Every `scripts/larch.sh checks run-relevant` invocation anywhere in this file is covered by this rule. → shared/subskill-invocation.md#anti-halt; do not load for routine invocations: load only when debugging or adding a child-Skill invocation.

<!-- step:1: Parse Arguments -->

Parse flags from the start of `$ARGUMENTS` before treating the remainder as positional arguments.

- `--merge`: Set `alias_merge=true`. Default: `alias_merge=false`. When true, `--merge` is forwarded to the `/implement` invocation so the resulting PR is also merged.
- `--private`: Set `alias_private=true`. Default: `alias_private=false`. When true, the new alias is forced under `.claude/skills/<alias-name>/` regardless of plugin-repo detection (escape hatch for creating a private alias inside a plugin source repo). When absent: target is `skills/<alias-name>/` if running in a plugin source repo, else `.claude/skills/<alias-name>/`. In non-plugin repos `--private` is a no-op (the default is already `.claude/skills/`). The flag is consumed by `/alias` only: it does NOT appear in the generated alias's preset flags.
- `--run-id <ID>`: Flag semantics are in `${CLAUDE_PLUGIN_ROOT}/skills/shared/run-id-flag.md`.

| Position | Meaning |
|----------|---------|
| After first positional token | Pass-through to the generated alias's preset flags |

After flag stripping, parse the remaining positional arguments:
- First token = **alias name**
- Second token = **target skill name** (without `/` prefix)
- Remainder = **preset flags** (may be empty: a pure rename shortcut is valid)

<!-- step:2: Validate -->

All validation uses Bash since `${CLAUDE_PLUGIN_ROOT}` is a shell variable not resolvable in Read/Glob.

### Plugin-repo detection + target-dir resolution

Before running the validation table below, resolve the target directory (`$TARGET_DIR`) once via the helper script. The script's stdout is the single source of truth for `(plugin-detect, --private) → TARGET_DIR`; thread the resolved value through Check 6, Step 3 (`/implement` recipe + announce line), and Step 4 (verify sentinel). Distinct from `${CLAUDE_PLUGIN_ROOT}` (the plugin install path used by Check 2): `$REPO_ROOT` is the git working tree where the alias is materialized; the two can diverge in practice and Check 2's shadow probe is orthogonal to where the new alias is written.

```bash
# Build the optional --private flag dynamically.
PRIVATE_FLAG=()
if [[ "$alias_private" == "true" ]]; then
  PRIVATE_FLAG=(--private)
fi

# Non-eval line-by-line parse with explicit allowlist (per NEVER #7).
# Do NOT use `eval "$("${CLAUDE_PLUGIN_ROOT}/scripts/larch.sh" alias resolve-target ...)"`: paths containing spaces / $(...) /
# backticks would be re-interpreted by the shell.
REPO_ROOT=""; PLUGIN_REPO=""; TARGET_DIR=""
while IFS='=' read -r key val; do
  case "$key" in
    REPO_ROOT|PLUGIN_REPO|TARGET_DIR) declare "$key=$val" ;;
  esac
done < <("${CLAUDE_PLUGIN_ROOT}/scripts/larch.sh" alias resolve-target \
           --alias-name "<alias-name>" "${PRIVATE_FLAG[@]}")

# Fail-closed if the helper exited with empty values (e.g., not in a git repo).
# `alias resolve-target` writes its diagnostic to stderr; surface a usable error to the operator.
if [[ -z "$TARGET_DIR" || -z "$REPO_ROOT" || -z "$PLUGIN_REPO" ]]; then
  echo "**ERROR: alias resolve-target failed (likely not in a git repository, or repository access failed). Cannot determine target directory for alias '<alias-name>'.**"
  exit 1
fi
```

The helper's stdout schema and the two-file plugin-detect predicate (`.claude-plugin/plugin.json` AND `skills/implement/SKILL.md`) live in `crates/larch-cli/src/developer_tooling_commands.rs`. Operators wanting a private alias inside a plugin repo use `--private`.

### Validation table

| # | Check | Rule | On fail |
|---|-------|------|---------|
| 1 | Alias name format | Must match `^[a-z][a-z0-9-]*$` (lowercase, alphanumeric + hyphens, must start with a letter) | `E_ALIAS_NAME` |
| 2 | Reserved name (dynamic probe) | `${CLAUDE_PLUGIN_ROOT}` must be set; alias name must not collide with any directory under `${CLAUDE_PLUGIN_ROOT}/skills/<alias-name>` OR `${CLAUDE_PLUGIN_ROOT}/.claude/skills/<alias-name>`. See `### Check 2` block below. | `E_PLUGIN_ROOT_UNSET` or `E_SHADOW` |
| 3 | Target name format | Must match `^[a-z][a-z0-9-]*$` (same format as alias names) | `E_TARGET_NAME` |
| 4 | Target skill exists | `test -f "${CLAUDE_PLUGIN_ROOT}/skills/<target>/SKILL.md"`; if missing, also run `ls "${CLAUDE_PLUGIN_ROOT}/skills/"` for discoverability | `E_TARGET_MISSING` |
| 5 | Target is not `alias` | Forbid alias-to-alias recursion | `E_RECURSION` |
| 6 | Collision check | `test -e "$TARGET_DIR"` must be false (uses `-e` not `-d` so a regular file at that path is also caught) | `E_COLLISION` |

### Check 2: reserved-name dynamic probe

Fail-closed on unset `${CLAUDE_PLUGIN_ROOT}`, then probe both plugin-tree roots for a directory collision:

```bash
if [[ -z "${CLAUDE_PLUGIN_ROOT:-}" ]]; then
  echo "**ERROR: CLAUDE_PLUGIN_ROOT is unset: cannot probe larch skill tree for reserved-name collision.**"
  exit 1
fi
# probe BOTH roots: skills/ (public) and .claude/skills/ (dev-only: release)
if test -d "${CLAUDE_PLUGIN_ROOT}/skills/<alias-name>" \
  || test -d "${CLAUDE_PLUGIN_ROOT}/.claude/skills/<alias-name>"; then
  echo "**ERROR: alias name '<alias-name>' shadows an existing larch skill.**"
  exit 1
fi
```

One conceptual rule: "alias cannot shadow any larch skill": replacing the prior static enumeration that was drifting as new skills shipped.

### Error strings (reference)

From character-ai/larch, MIT.

More from character-ai/larch

Signals

Stars
7
Forks
4
Open issues
6
Last commit (this folder)
Aug 20, 2026 (2 months ago)
Last release
Sep 8, 2026 (1 month ago)

From GitHub (fetched Oct 24, 2026).

Details

License
MIT
First seen
Oct 24, 2026
Last checked
Oct 24, 2026

More from character-ai

Cite this page

alias skill. Agent Mart. https://agentmart.dev/skills/character-ai-alias (last updated 2026-10-24)