Skip to content

fix: pi.dev command reference transforms and template args passing#950

Merged
TabishB merged 2 commits into
mainfrom
TabishB/investigate-912
Apr 11, 2026
Merged

fix: pi.dev command reference transforms and template args passing#950
TabishB merged 2 commits into
mainfrom
TabishB/investigate-912

Conversation

@TabishB

@TabishB TabishB commented Apr 11, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Command reference transforms: Pi prompt bodies and skills now transform /opsx: references to /opsx- (matching hyphenated filenames), using the same transformToHyphenCommands approach as OpenCode
  • Template args injection: Adds $@ interpolation via **Provided arguments**: $@ after **Input**: headings, so user arguments (e.g., /opsx-propose add-dark-mode) are passed through to the agent
  • No filename changes: Filenames stay as opsx-<id>.md (cross-platform safe — colons are invalid on Windows NTFS, and pi.dev supports Windows)

Closes #912

Test plan

  • All 1351 existing tests pass
  • New test: pi adapter transforms /opsx: to /opsx- in body
  • New test: pi adapter injects $@ into body's Input section
  • Manual: run openspec init with pi selected, verify /opsx: refs in body are transformed to /opsx-
  • Manual: verify $@ appears in generated prompt files

🤖 Generated with Claude Code

Fix two pi.dev integration bugs:
- Use colon-based filenames (opsx:explore.md) so CLI commands render as
  /opsx:explore instead of /opsx-explore
- Inject $@ into template body so user arguments are passed through

Adds getLegacyFilePaths to ToolCommandAdapter for migration-safe cleanup
of old hyphenated files during init/update.
@1code-async

1code-async Bot commented Apr 11, 2026

Copy link
Copy Markdown
Contributor

Task completed.

I'll start by examining the PR changes to provide a thorough review.


View full conversation

Powered by 1Code

@coderabbitai

coderabbitai Bot commented Apr 11, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

The PR extends Pi adapter command generation to transform /opsx: command references to /opsx- hyphenated form and conditionally inject a "Provided arguments" line into prompt templates after the Input section. The same hyphen-command transformation is now applied when tool identifier is 'pi' during both initial skill generation and updates.

Changes

Cohort / File(s) Summary
Pi Adapter Enhancement
src/core/command-generation/adapters/pi.ts
Added transformToHyphenCommands call to convert /opsx:commandId references to /opsx-commandId format, and injectPiArgs call to conditionally insert **Provided arguments**: $@ after Input headings (unless $@ or $ARGUMENTS already present).
Transformer Integration
src/core/init.ts, src/core/update.ts
Extended conditional logic to apply transformToHyphenCommands for both 'opencode' and 'pi' tool values in skill markdown generation.
Test Coverage
test/core/command-generation/adapters.test.ts, test/core/update.test.ts
Added two new test cases validating hyphen command reference transformation and argument injection in Pi adapter; minor formatting adjustment.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

  • Issue #912 (pi.dev integration bugs: prompt template name, args passing) — This PR directly implements the two fixes described: transforming colon-based command names to hyphenated form and injecting argument placeholders into prompt Input sections.

Possibly related PRs

  • PR #735 — Both PRs involve the Pi adapter; retrieved PR adds the initial piAdapter while this PR extends its formatFile logic with command transformation and argument injection.
  • PR #626 — Both PRs work with transformToHyphenCommands; retrieved PR introduces the transformer for opencode, this PR extends it to pi tool flows.

Poem

🐰 A colon once lived in the Pi,
But hyphens made reference fly.
With arguments blessed,
Each prompt is dressed—
Now templates can't pass by! 🎯

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 60.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The pull request addresses both core requirements from issue #912: pi prompts now use colon-based filenames/command references (opsx:propose) via transformToHyphenCommands in adapters, and template arguments are injected via injectPiArgs inserting $@ after Input headings.
Out of Scope Changes check ✅ Passed All changes are directly aligned with the stated objectives: Pi adapter formatting, command reference transformation, args injection, and corresponding test coverage. No unrelated modifications detected.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: pi.dev command reference transforms and template args passing' accurately describes the main changes: command reference transformations and template argument injection for the Pi adapter.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch TabishB/investigate-912

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
src/core/init.ts (1)

788-806: Extract legacy alias cleanup into a shared helper.

This method now duplicates the same legacy-path unlink logic that already exists in UpdateCommand, so the next naming migration can easily make init and update diverge.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/core/init.ts` around lines 788 - 806, The legacy-path unlink logic in
removeLegacyCommandAliases duplicates code in UpdateCommand; extract this into a
shared helper (e.g., removeLegacyCommandFiles or cleanupLegacyCommandAliases)
that accepts (projectPath: string, adapter: ToolCommandAdapter, commandId:
string) and uses getCommandFilePaths, path.isAbsolute, path.join, fs.existsSync
and fs.promises.unlink to remove legacy files, then replace the body of
removeLegacyCommandAliases and the corresponding logic in UpdateCommand to call
the new helper to avoid duplication.
src/core/update.ts (1)

219-226: Add id to GeneratedCommand payload to eliminate array-index pairing.

The current code at lines 219–226 (and 710–717) derives commandId from commandContents[index]?.id while writing files from generatedCommands[index]. Although generateCommands() currently preserves 1:1 input order via .map(), the reliance on parallel-array indexing is fragile. If the implementation ever filters or transforms the command list, this cleanup could target the wrong legacy file or skip cleanup entirely.

Instead of relying on positional coupling, include the command id in the GeneratedCommand type payload. This makes the relationship explicit and eliminates the implicit invariant.

Also applies to: 710–717

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/core/update.ts` around lines 219 - 226, generatedCommands is being paired
with commandContents by index (generatedCommands[index] and
commandContents[index]?.id), which is fragile; update the GeneratedCommand
payload to include id and propagate it from generateCommands so each
GeneratedCommand contains its own id, then change the write loop to read
commandId directly from cmd.id instead of commandContents[index]?.id and call
removeLegacyCommandAliases(resolvedProjectPath, adapter, cmd.id); update any
other places (e.g., the loop around lines 710–717) that use positional pairing
to use the new cmd.id and adjust types/interfaces and generateCommands
implementation accordingly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/supported-tools.md`:
- Line 44: Update the overview paragraph that currently states command files use
"opsx-*" to include the Pi naming exception: change the sentence in the
docs/supported-tools.md overview to mention that while most tools use the opsx-*
pattern, Pi command files use the opsx:<id>.md form (give the example
`.pi/prompts/opsx:<id>.md`) and clarify how the `<id>` maps to Pi prompts;
update any related wording that asserts the pattern is universal so it reflects
this exception.

In `@src/core/command-generation/adapters/pi.ts`:
- Around line 47-49: getFilePath currently builds filenames using
`opsx:${commandId}.md` which contains a colon invalid on Windows; update the
`getFilePath` implementation (the getFilePath function that calls `path.join`)
to use a Windows-safe separator (e.g., `opsx-${commandId}.md`) or implement a
platform-aware fallback (replace/escape invalid characters) so filenames are
valid on Windows and match the other adapters' naming convention.

---

Nitpick comments:
In `@src/core/init.ts`:
- Around line 788-806: The legacy-path unlink logic in
removeLegacyCommandAliases duplicates code in UpdateCommand; extract this into a
shared helper (e.g., removeLegacyCommandFiles or cleanupLegacyCommandAliases)
that accepts (projectPath: string, adapter: ToolCommandAdapter, commandId:
string) and uses getCommandFilePaths, path.isAbsolute, path.join, fs.existsSync
and fs.promises.unlink to remove legacy files, then replace the body of
removeLegacyCommandAliases and the corresponding logic in UpdateCommand to call
the new helper to avoid duplication.

In `@src/core/update.ts`:
- Around line 219-226: generatedCommands is being paired with commandContents by
index (generatedCommands[index] and commandContents[index]?.id), which is
fragile; update the GeneratedCommand payload to include id and propagate it from
generateCommands so each GeneratedCommand contains its own id, then change the
write loop to read commandId directly from cmd.id instead of
commandContents[index]?.id and call
removeLegacyCommandAliases(resolvedProjectPath, adapter, cmd.id); update any
other places (e.g., the loop around lines 710–717) that use positional pairing
to use the new cmd.id and adjust types/interfaces and generateCommands
implementation accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 84bcac05-b30c-4c8e-954a-03c7710a5129

📥 Commits

Reviewing files that changed from the base of the PR and between 1445282 and d12997b.

📒 Files selected for processing (9)
  • docs/supported-tools.md
  • src/core/command-generation/adapters/pi.ts
  • src/core/command-generation/index.ts
  • src/core/command-generation/types.ts
  • src/core/init.ts
  • src/core/profile-sync-drift.ts
  • src/core/update.ts
  • test/core/command-generation/adapters.test.ts
  • test/core/update.test.ts

Comment thread docs/supported-tools.md Outdated
| Kiro (`kiro`) | `.kiro/skills/openspec-*/SKILL.md` | `.kiro/prompts/opsx-<id>.prompt.md` |
| OpenCode (`opencode`) | `.opencode/skills/openspec-*/SKILL.md` | `.opencode/commands/opsx-<id>.md` |
| Pi (`pi`) | `.pi/skills/openspec-*/SKILL.md` | `.pi/prompts/opsx-<id>.md` |
| Pi (`pi`) | `.pi/skills/openspec-*/SKILL.md` | `.pi/prompts/opsx:<id>.md` |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Document the new naming exception in the overview.

This row is correct, but the overview on Line 10 still says command files use opsx-*. With Pi now using opsx:<id>.md, that statement is no longer universally true.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/supported-tools.md` at line 44, Update the overview paragraph that
currently states command files use "opsx-*" to include the Pi naming exception:
change the sentence in the docs/supported-tools.md overview to mention that
while most tools use the opsx-* pattern, Pi command files use the opsx:<id>.md
form (give the example `.pi/prompts/opsx:<id>.md`) and clarify how the `<id>`
maps to Pi prompts; update any related wording that asserts the pattern is
universal so it reflects this exception.

Comment thread src/core/command-generation/adapters/pi.ts Outdated
- Transform /opsx: references to /opsx- in Pi command bodies and skills,
  matching the hyphenated filename convention (same approach as OpenCode)
- Inject $@ into template body so user arguments are passed through

Pi uses the filename (minus .md) as the slash command name, so
opsx-propose.md becomes /opsx-propose. This keeps filenames
cross-platform safe while ensuring command references in the body
match the actual command names.
@TabishB TabishB changed the title fix: pi.dev prompt naming and template args passing fix: pi.dev command reference transforms and template args passing Apr 11, 2026

@alfred-openspec alfred-openspec left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. This keeps Pi on Windows-safe hyphenated filenames, fixes the command references to match what Pi actually exposes, and passes args through cleanly.

@TabishB TabishB added this pull request to the merge queue Apr 11, 2026
Merged via the queue into main with commit caafd7c Apr 11, 2026
9 checks passed
@TabishB TabishB deleted the TabishB/investigate-912 branch April 11, 2026 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pi.dev integration bugs: prompt template name, args passing

2 participants