@juicesharp/rpiv-args

Pi extension: pass shell-style $1 / $ARGUMENTS placeholders to your Pi skills

Package details

extension

Install @juicesharp/rpiv-args from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@juicesharp/rpiv-args
Package
@juicesharp/rpiv-args
Version
1.1.4
Published
May 3, 2026
Downloads
5,408/mo · 3,321/wk
Author
juicesharp
License
MIT
Types
extension
Size
15.6 KB
Dependencies
0 dependencies · 1 peer
Pi manifest JSON
{
  "extensions": [
    "./index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

rpiv-args

npm version License: MIT

Pass arguments to your skills like a shell command. rpiv-args adds $1, $ARGUMENTS, $@, ${@:N}, and ${@:N:L} placeholders to Pi Agent skills — write /skill:deploy api production and your skill body sees $1 = api, $2 = production. Skills without placeholders are untouched, so installing rpiv-args is safe for any existing skill collection.

Install

pi install npm:@juicesharp/rpiv-args

Or run /rpiv-setup if you have @juicesharp/rpiv-pi installed.

Placeholders

Placeholder Replaced with Example
$1, $2, … Positional argument (1-indexed) /skill:foo a b c$1 = a, $2 = b
$ARGUMENTS All arguments as a single string /skill:foo a b ca b c
$@ Same as $ARGUMENTS /skill:foo a b ca b c
${@:N} Arguments from position N onward /skill:foo a b c${@:2} = b c
${@:N:L} L arguments starting at position N /skill:foo a b c d${@:2:2} = b c

Indexing is 1-based$1 is the first argument, $2 is the second. Out-of-range positions resolve to an empty string. For ${@:N[:L]}, N is clamped to ≥ 1 and out-of-range slices yield an empty string.

Multi-word values use shell-style quoting:

/skill:deploy "staging server" --force

$1 = staging server, $2 = --force, $ARGUMENTS = staging server --force

How it works

rpiv-args intercepts the input event (fires before Pi's built-in skill expansion). When a skill body contains at least one placeholder, the extension:

  1. Parses arguments using shell-style quoting
  2. Substitutes all placeholders in the body
  3. Wraps the result in a <skill> block byte-identical to Pi's native format
  4. Appends the raw arguments after the block — matches Pi's standard output so any tool that parses <skill> blocks continues to work unchanged

When no placeholders are found in the skill body, the output is byte-identical to Pi's built-in expansion — zero behavioral change.

Writing skills with arguments

$ARGUMENTS vs $1 — which to use

Use $ARGUMENTS (or $@) when the input is freeform text the LLM should interpret naturally:

---
name: fix-issue
description: Fix a GitHub issue by number or description
---

Fix the following issue: $ARGUMENTS
/skill:fix-issue login page crashes on mobile

Fix the following issue: login page crashes on mobile

Use $1, $2 only for skills with a fixed, structured invocation pattern:

---
name: migrate-component
description: Migrate a component between frameworks
---

Migrate the $1 component from $2 to $3.
Preserve all existing behavior and tests.
/skill:migrate-component SearchBar React Vue

Migrate the SearchBar component from React to Vue.

Why this matters

If a positional skill receives natural language input:

/skill:migrate-component can you migrate the search bar please

Migrate the can component from you to migrate.broken.

The LLM is good at interpreting $ARGUMENTS as a whole, but positional placeholders blindly split on spaces. Use $ARGUMENTS unless your skill has a strict arg structure.

argument-hint frontmatter

Add an argument-hint to document what the skill expects:

---
name: fix-issue
description: Fix a GitHub issue
argument-hint: [issue-number-or-description]
---
---
name: migrate-component
description: Migrate a component between frameworks
argument-hint: [component] [from] [to]
---

rpiv-args ignores this field — substitution is triggered by placeholders in the body, not the hint.

Note: Pi currently surfaces argument-hint in autocomplete for prompt templates (commands/*.md) but not for skills (/skill:<name>). The field is read by Pi but not displayed in the /skill: autocomplete UI at present — treat it as documentation metadata until upstream Pi exposes it.

Full example

---
name: deploy
description: Deploy a service to an environment
argument-hint: [service] [environment]
---

Deploy service $1 to $2.

## Steps
1. Run the test suite for $1
2. Build the Docker image
3. Push to the $2 registry
4. Verify the deployment
/skill:deploy api production

→ The LLM receives:

<skill name="deploy" location="...">
Deploy service api to production.

## Steps
1. Run the test suite for api
2. Build the Docker image
3. Push to the production registry
4. Verify the deployment
</skill>

api production

Note: the raw arguments (api production) are also appended after the </skill> block — this is Pi's standard behavior and is preserved for backward compatibility.

Backward compatibility

  • Skills without placeholders → output is byte-identical to Pi's built-in expansion
  • Skills with placeholders → body gets substitution, raw args still appended after block
  • The argument-hint frontmatter field is read but not enforced in v1

Limitations

Limitation Detail
No type validation $1 expecting a file path receives whatever the user types
No flag parsing --env=prod is a single positional token, not a parsed flag
Literal substitution Placeholders are replaced even inside code blocks and inline code
steer()/followUp() paths session.steer() / session.followUp() bypass the input event (see agent-session.js:861-887); placeholders are not resolved on those paths. Use the primary prompt path for argument-substituted skills.
No recursive substitution A $ARGUMENTS value containing $1 is not re-expanded

License

MIT