Skip to content

feat(cli): intelligent prs init with inline migration flow#147

Merged
mrwogu merged 22 commits intomainfrom
prs-init
Mar 22, 2026
Merged

feat(cli): intelligent prs init with inline migration flow#147
mrwogu merged 22 commits intomainfrom
prs-init

Conversation

@mrwogu
Copy link
Owner

@mrwogu mrwogu commented Mar 21, 2026

Summary

Redesigns prs init to auto-detect existing AI instruction files and offer inline migration, plus adds prs migrate as a first-class command.

  • Gateway prompt: when existing instruction files (CLAUDE.md, .cursorrules, etc.) are detected, prs init offers "Migrate existing" vs "Fresh start" — no more passive hints
  • Two migration strategies: static import (fast, deterministic, multi-file merge into modular .prs) and AI-assisted (installs skill + generates kick-start prompt to clipboard)
  • Multi-file importer: new importMultipleFiles() in @promptscript/importer with section merger, dedup, modular output (project.prs + context.prs + standards.prs + restrictions.prs + commands.prs)
  • prs migrate command: alias to init migration path, supports --static, --llm, --files flags
  • Enriched detection: MigrationCandidate now includes file size, format, and tool name for better UX
  • Fresh start skill install: prs init now installs the PromptScript skill to all targets even without --migrate, so AI tools can help immediately
  • Safety: git repo detection, optional .prs-backup/ with timestamped dirs, --backup flag
  • Non-interactive: -y is safe (skips migration), -y --auto-import opts into static import for CI

New files

  • packages/cli/src/utils/clipboard.ts — cross-platform clipboard
  • packages/cli/src/utils/backup.ts — backup + git detection
  • packages/cli/src/utils/migration-prompt.ts — kick-start prompt generator
  • packages/importer/src/merger.ts — section merge with per-block strategies
  • packages/importer/src/multi-importer.ts — batch import → modular .prs
  • packages/cli/src/commands/migrate.tsprs migrate command

Breaking changes

  • AIToolsDetection.migrationCandidates type changed from string[] to MigrationCandidate[] (internal CLI interface only)
  • "Already initialized" now exits with code 2 (was 0)
  • --migrate flag deprecated (still works, shows warning)

Test Plan

  • 636 tests passing (43 test files)
  • pnpm run format — clean
  • pnpm run lint — 10/10 projects pass
  • pnpm run typecheck — 11/11 projects pass
  • pnpm prs validate --strict — no issues
  • pnpm schema:check — up-to-date
  • pnpm skill:check — all copies in sync
  • Manual: prs init in repo with CLAUDE.md shows gateway prompt
  • Manual: prs init -y --auto-import in repo with instruction files produces modular .prs
  • Manual: prs migrate --llm generates prompt and copies to clipboard

mrwogu added 17 commits March 20, 2026 22:51
Prevent future release-please breakage by adding a restriction
against manually editing CHANGELOG.md, which is managed by
release-please.
Address review findings:
- PS004 → PS018 (PS004 already taken by required-guards)
- Clarify cumulative block lists in registry
- Scope regex replace to @meta block only
- Add CLI registration details and file manifest
- Define preset severities and edge cases for custom blocks
- Use existing compareVersions from core
- Remove directives from interface (YAGNI)
Catches typos and invented block names with Levenshtein fuzzy
matching suggestions (e.g., @agenst → "Did you mean @agentS?").
- Add isValidSemver guard in PS018 to prevent compareVersions throw
- Specify meta block boundary finding for --fix implementation
- Use rule names (not IDs) as preset keys per convention
- PS019 uses walkBlocks + isBlockType from existing utilities
- Move Levenshtein to core/utils for reuse
- Add explicit no-downgrade rule for --fix
- Add documentation update plan
- Expand files modified with grouped sections
Design for redesigned prs init command that auto-detects existing
AI instruction files and offers migration inline. Supports two
migration strategies: static import (fast, deterministic) and
AI-assisted (skill + kick-start prompt). Includes multi-file
import with modular .prs output structure.

Key decisions:
- Gateway choice: "Migrate existing" vs "Fresh start"
- Modular output: project.prs + context.prs + standards.prs + etc.
- prs migrate as alias to init migration path
- Non-interactive: -y safe defaults, --import for explicit auto-import
10 tasks across 6 chunks covering:
- Phase 1: clipboard, backup, migration prompt utilities
- Phase 2: section merger + multi-file importer in @promptscript/importer
- Phase 3: enriched migration candidates + enhanced init command
- Phase 4: prs migrate command + CLI registration
- Phase 5: SKILL.md docs + verification pipeline

Reviewed and fixed: reserved keyword (autoImport), complete handler
code, test coverage for LLM/backup flows, --files support.
Add importMultipleFiles() to merge sections from multiple AI instruction
files into separate modular .prs files (context.prs, standards.prs,
restrictions.prs, commands.prs, project.prs). Add emitModularFiles()
to emitter.ts and export all new types from package index.
- Add MigrationCandidate interface with path, format, sizeBytes, sizeHuman, toolName
- Change AIToolsDetection.migrationCandidates from string[] to MigrationCandidate[]
- Expand INSTRUCTION_FILES to include .windsurfrules, .clinerules, .goosehints, augment-guidelines.md, codex.md
- Add formatFileSize and toolNameForFile helpers with FILE_TOOL_NAMES lookup map
- Update formatMigrationHint to display size and tool name per candidate
- Add new fields to InitOptions (autoImport, backup, _forceMigrate, _forceLlm, _migrateFiles)
- Add MigrateOptions interface
- Add dedicated test suite in utils/__tests__/ai-tools-detector.spec.ts
- Fix existing ai-tools-detector.spec.ts to include readFile mock
- Update init.ts migration hint display logic to match new format
- Add gateway prompt showing migration candidates with size/tool info
- Add strategy selection (static import vs AI-assisted migration)
- Implement static migration flow using multi-file importer
- Implement LLM migration flow with prompt generation and clipboard
- Add backup handling before migration (git-aware defaults)
- Extract skill installation into reusable installSkillToTargets()
- Skills now always installed (not gated by --migrate flag)
- Set exit code 2 when already initialized
- Support _forceMigrate/_forceLlm internal flags for prs migrate
- Support --auto-import flag for non-interactive static import
The init command now always installs the PromptScript skill to
target directories (fresh start behavior), so the smoke test
asserting skill absence without --migrate needs to be inverted.
@codecov
Copy link

codecov bot commented Mar 21, 2026

Codecov Report

❌ Patch coverage is 95.93220% with 12 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
packages/cli/src/cli.ts 12.50% 6 Missing and 1 partial ⚠️
packages/cli/src/commands/init.ts 97.41% 3 Missing ⚠️
packages/cli/src/utils/ai-tools-detector.ts 93.75% 1 Missing ⚠️
packages/importer/src/emitter.ts 97.91% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

- Add test for deduplication report display (deduplicatedCount > 0)
- Add test for clipboard failure fallback (prints prompt to console)
- Add test for emitEmptyProject when all imports fail
- Add test for low-confidence review comment in emitModularFiles
- Add test for readFile failure during size enrichment (catch block)
- Add test for mergeSections with empty sections array
@codecov
Copy link

codecov bot commented Mar 21, 2026

Bundle Report

Changes will increase total bundle size by 152.41kB (14.41%) ⬆️⚠️, exceeding the configured threshold of 5%.

Bundle name Size Change
promptscript-cli 1.21MB 152.41kB (14.41%) ⬆️⚠️

Affected Assets, Files, and Routes:

view changes for bundle: promptscript-cli

Assets Changed:

Asset Name Size Change Total Size Change (%)
index.js 148.26kB 1.1MB 15.64% ⚠️
skills/promptscript/SKILL.md 230 bytes 19.74kB 1.18%
src/types.d.ts 595 bytes 4.24kB 16.31% ⚠️
src/types.d.ts.map 359 bytes 2.82kB 14.58% ⚠️
src/utils/ai-tools-detector.d.ts 310 bytes 1.83kB 20.41% ⚠️
src/utils/ai-tools-detector.d.ts.map 219 bytes 1.1kB 24.97% ⚠️
src/commands/migrate.d.ts (New) 480 bytes 480 bytes 100.0% 🚀
src/utils/backup.d.ts.map (New) 416 bytes 416 bytes 100.0% 🚀
src/commands/migrate.d.ts.map (New) 342 bytes 342 bytes 100.0% 🚀
src/utils/backup.d.ts (New) 331 bytes 331 bytes 100.0% 🚀
src/utils/migration-prompt.d.ts.map (New) 324 bytes 324 bytes 100.0% 🚀
src/utils/migration-prompt.d.ts (New) 244 bytes 244 bytes 100.0% 🚀
src/utils/clipboard.d.ts.map (New) 195 bytes 195 bytes 100.0% 🚀
src/utils/clipboard.d.ts (New) 103 bytes 103 bytes 100.0% 🚀

Use counter variable instead of accessing .mock.calls on untyped
mock to avoid TS2339 error in strict typecheck.
@mrwogu
Copy link
Owner Author

mrwogu commented Mar 21, 2026

Code review

Found 2 issues:

  1. _migrateFiles option is declared in InitOptions, set by migrateCommand from the --files flag, but never read in initCommand. Running prs migrate --files CLAUDE.md silently ignores the flag and imports all auto-detected files instead. The types.ts JSDoc says "Internal: specific files to migrate (used by prs migrate --files)" but the contract is unmet.

_forceLlm?: boolean;
/** Internal: specific files to migrate (used by prs migrate --files) */
_migrateFiles?: string[];
}

_forceMigrate: true,
_forceLlm: options.llm ?? false,
_migrateFiles: options.files,
yes: options.static ?? false,
autoImport: options.static ?? false,

  1. formatMigrationHint still recommends prs init --migrate (deprecated in this same PR) instead of the new prs migrate command. Users who choose "Fresh start" and later want to migrate are directed to a deprecated flag.

lines.push(' These can be migrated to PromptScript for unified management.');
lines.push(' Run: prs init --migrate');
lines.push(' See: https://getpromptscript.dev/latest/guides/ai-migration-best-practices');
return lines;

Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

mrwogu added 3 commits March 22, 2026 08:55
- handleStaticMigration now filters candidates by _migrateFiles when
  provided, so prs migrate --files actually restricts which files
  are imported
- formatMigrationHint now recommends "prs migrate" instead of the
  deprecated "prs init --migrate"
# Conflicts:
#	packages/cli/src/cli.ts
@mrwogu mrwogu merged commit 30ce56d into main Mar 22, 2026
14 of 15 checks passed
@mrwogu mrwogu deleted the prs-init branch March 22, 2026 11:57
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.

1 participant