Creating Slash Commands
Creating a Prompt-Based Slash Command
Create a simple chat alias for a frequently used, complex prompt.
---
description: "Run a quick security audit on the current changes"
---
Review the git diff of the current changes and look for security vulnerabilities.
Check for hardcoded secrets, injection vectors, and broken access control.
Place this in prompts/security-audit.md to automatically register the /security-audit command. The markdown filename determines the slash command name, and the description populates the command menu in the UI.
Passing Arguments to a Prompt Command
Inject user input from the chat bar directly into your prompt template.
---
description: "Explain a specific concept or file — /explain <target>"
argument-hint: "<target>"
---
## Raw Arguments
```text
$ARGUMENTS
Bug Reporting: If this command fails, use the
/bugcommand to report it.
Explain the target provided in the raw arguments above. Keep the explanation concise and focus on how it fits into the project architecture.
When a user runs `/explain src/main.ts`, the `$ARGUMENTS` token is replaced with `src/main.ts`. The `argument-hint` frontmatter provides inline help in the command palette.
> **Note:** The bug reporting blockquote is a project standard and must immediately follow the `$ARGUMENTS` block.
## Creating an Interactive TypeScript Command
Register a programmable extension command to interact with the workspace, manipulate the UI, or trigger background tasks.
```typescript
import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
export function registerHelloCommand(pi: ExtensionAPI): void {
pi.registerCommand("hello", {
description: "Display a custom notification greeting",
handler: async (args, ctx) => {
const name = args?.trim() || "Developer";
if (!ctx.hasUI) {
return; // Ensure the session supports UI before notifying
}
ctx.ui.notify(`Hello, ${name}! Your workspace is ${ctx.cwd}`, "info");
},
});
}
Place this in a new file within the extensions/ directory and call it during extension initialization. The handler function receives the raw argument string and a context object containing the session state, UI tools, and workspace details.
Tip: See Daemon & Websocket Networking for details on handling asynchronous background tasks within command handlers.
Adding Argument Autocomplete to a Command
Provide interactive tab-completions for your custom slash commands.
// Add to the `completions` record in extensions/orchestrator/extended-autocomplete.ts
"hello": (prefix: string) => {
return filter([
{ value: "--verbose", label: "--verbose", description: "Show detailed greeting output" },
{ value: "--quiet", label: "--quiet", description: "Suppress the notification bell" }
], prefix);
},
Add your completion logic to extensions/orchestrator/extended-autocomplete.ts. The filter helper automatically handles fuzzy matching against the user's current typed prefix.
Warning: If you are adding autocomplete for a prompt template (like the
/explainexample above), you must also add the command name to thepromptTemplateCommandsset located in the same file to intercept the routing.