Capture generic slash-command skill invocations - #1333
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR expands prompt-based skill invocation capture from the Pi-specific /skill:<name> shape to a generic “leading slash command” shape (/<command>), enabling Codex/Cursor/OpenCode/Gemini/Factory-style prompt skills to be persisted as prompt_invocation skill events (storing only the command token for privacy).
Changes:
- Add a generic prompt slash-command parser and event appender (
prompt_slash_command), including filesystem-path rejection and Pi/skill:normalization for dedupe. - Update TurnStart lifecycle handling to append the generic prompt-derived skill event only when the agent matches the session owner (or ownership is unset).
- Add unit tests for parsing variants and lifecycle tests for TurnStart recording + forwarded-hook dedupe.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| cmd/entire/cli/lifecycle.go | Appends a generic prompt-derived skill event on TurnStart after session ownership is known. |
| cmd/entire/cli/lifecycle_test.go | Adds lifecycle coverage for recording the prompt-derived event and avoiding duplicates from forwarded hooks. |
| cmd/entire/cli/agent/skill_events.go | Introduces the prompt_slash_command signal constant. |
| cmd/entire/cli/agent/skill_events_prompt.go | Implements parsing/normalization/denylist logic and dedupe for prompt slash-command skill events. |
| cmd/entire/cli/agent/skill_events_prompt_test.go | Adds table-driven tests for parser variants and adapter-vs-generic dedupe behavior. |
dipree
force-pushed
the
feat/generic-slash-skill-events
branch
2 times, most recently
from
June 2, 2026 20:32
397fd1f to
e096289
Compare
Generalize the turn-start prompt parser to record a skill/prompt event for any leading `/<command>`, not just one fixed namespace. A slash command only reaches a recorded prompt if it submitted a model turn, so runtime/UI-only commands (`/mcp`, `/model`, `/help`, ...) are naturally excluded — they never fire the turn-start hook. The one remaining non-command class is pasted absolute filesystem paths (`/Users/...`, `/tmp/...`), rejected via a filesystem-root denylist; a bare root-name command (`/dev`) stays a command, only `/dev/null`-style continuations are rejected. Only the command token is stored (never prompt args). Pi's `/skill:<name>` is normalized to the bare name so it dedupes against Pi's native event. Built-in vs custom is just a label; both are injected prompts and recorded. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dipree
force-pushed
the
feat/generic-slash-skill-events
branch
from
June 2, 2026 20:37
e096289 to
48cac9e
Compare
alishakawaguchi
approved these changes
Jun 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Prompt-based skill/prompt invocations were only captured for one fixed slash-command shape. Agents that invoke skills via ordinary slash commands (Codex, Cursor, OpenCode, Gemini, Factory) recorded no skill events, even though a leading
/<command>is exactly such an invocation.Solution
Record a
prompt_invocationskill event for any leading/<command>in a submitted prompt.This is safe because a slash command only reaches a recorded prompt if it submitted a model turn:
/mcp,/model,/help,/clear, …) are handled in the agent REPL, never submit a turn, and never fire the turn-start hook — so they're excluded for free, no denylist needed./Users/...,/tmp/...) are the only non-command class and are rejected via a filesystem-root denylist. A bare root-name command (/dev) stays a command; only a root followed by a path segment (/dev/null) is rejected.Details:
/skill:<name>is normalized to the bare name so it dedupes against Pi's native event.handleLifecycleTurnStartalready appends for every agent that exposesevent.Prompt.Behavior note: Claude Code sessions now also get
prompt_invocationevents for slash commands, alongsidetool_invocationevents from its native Skill tool (different event types, not deduped).Testing
go test ./cmd/entire/cli/agent ./cmd/entire/cli;mise run fmt+golangci-lintclean.:/path namespacing, arg-stripping, the Pi form, bare root-name commands, and path/non-command rejection.🤖 Generated with Claude Code