umputun/ralphex
GitHub将OpenSpec、spec-kit、GitHub/GitLab Issue或通用Markdown任务列表转换为ralphex格式计划。支持URL、Issue编号及本地路径解析,自动分类并生成新文件,不修改源文件或执行代码。
Install All Skills
npx skills add umputun/ralphex --all -g -y
More Options
List skills in collection
npx skills add umputun/ralphex --list
Skills in Collection (4)
assets/claude/skills/ralphex-adopt/SKILL.md
npx skills add umputun/ralphex --skill ralphex-adopt -g -y
SKILL.md
Frontmatter
{
"name": "ralphex-adopt",
"description": "Convert plans from various source formats (OpenSpec, spec-kit, GitHub\/GitLab issues with checklists, generic task-lists, free-form markdown) into ralphex-format plans in docs\/plans\/. Triggers on \"ralphex-adopt\", \"adopt plan\", \"convert plan to ralphex\", \"import plan as ralphex\".",
"allowed-tools": [
"Bash",
"Read",
"Write",
"Glob",
"Grep",
"AskUserQuestion"
]
}
ralphex-adopt - Convert Plans Into ralphex Format
SCOPE: Read a source plan in some other format and produce a new ralphex-format plan at docs/plans/YYYYMMDD-<slug>.md. The source is never modified. Existing target files are never silently overwritten.
Supported source shapes:
- OpenSpec change: directory containing
proposal.md,tasks.md, optionalspecs/**/spec.md - spec-kit spec: directory or file with spec/plan/tasks separation
- GitHub or GitLab issue: URL,
#N, orowner/repo#Nwith body that contains a task checklist - Generic task-list: any structured markdown/text with headings and bullet items
- Free-form markdown: prose brain dump with no fixed structure
This is a single-skill conversion: discover, classify, ask focused questions when in doubt, draft, review, write. Do not modify code, do not run tests, do not commit. Output is the new plan file only.
Step 0: Optional CLI Check
This check is informational only. Missing ralphex CLI must NOT break the flow — conversion does not require it. Do NOT block, exit, prompt the user, or wait for installation. Always continue to Step 1 regardless of the result.
which ralphex
If which ralphex returns non-zero, briefly mention that ralphex is needed to execute the converted plan later (not now), list install options once, and continue immediately:
- macOS (Homebrew):
brew install umputun/apps/ralphex - Linux (Debian/Ubuntu): download
.debfrom https://github.com/umputun/ralphex/releases - Linux (RHEL/Fedora): download
.rpmfrom https://github.com/umputun/ralphex/releases - Any platform with Go:
go install github.com/umputun/ralphex/cmd/ralphex@latest
If which ralphex succeeds, say nothing and proceed.
Step 1: Resolve Source From Argument Shape
Inspect $ARGUMENTS and pick exactly one source by shape, in this order:
-
Full URL (starts with
http://orhttps://):- GitHub issue/PR URL → use
gh issue view <url> --json title,body,labels(orgh pr view) - GitLab issue/MR URL → use
glab issue view <url>(orglab mr view) - Other URL → fetch with
curl -fsSLonly if it points at a raw markdown file; otherwise AskUser to paste the body
- GitHub issue/PR URL → use
-
Bare reference
#N:- Use the current git repository's host. Detect with
git remote get-url originand chooseghorglabaccordingly. - If
git remote get-url originfails (not a git repo, or nooriginremote), AskUserQuestion to disambiguate: "GitHub", "GitLab", "Provide qualifiedowner/repo#Ninstead", "Cancel". Re-resolve based on the answer. - GitHub:
gh issue view N --json title,body(trygh pr view Nif issue not found) - GitLab:
glab issue view N(tryglab mr view Nif not found)
- Use the current git repository's host. Detect with
-
Qualified reference
owner/repo#Norgroup/project#N:- GitHub:
gh issue view N --repo owner/repo - GitLab:
glab issue view N --repo group/project
- GitHub:
-
Existing path — first probe the literal argument as a filesystem path with
test -e "$ARGUMENTS":- File: read with the Read tool
- Directory: list with
ls -la <path>and inspect contents- If contains
proposal.mdANDtasks.md→ likely OpenSpec, proceed to Step 2 - If contains a single
*.md→ use that file - Otherwise AskUser which file inside the directory is the plan
- If contains
-
Bare name — only if the argument failed every check above (not a URL, not
#Norowner/repo#N, andtest -ereturned false). A bare name has no path separators and contains no path-like characters:- Search filesystem with Glob for plausible matches (e.g.,
**/*<name>*.md,**/*<name>*/proposal.md) - If exactly one match → use it
- If multiple matches → AskUser to pick one (use AskUserQuestion with up to 4 most relevant; if more, summarize and AskUser to paste the path)
- If no matches → AskUser whether they meant a path, an issue number, or something else
- Search filesystem with Glob for plausible matches (e.g.,
-
No argument:
- Use AskUserQuestion: "Where is the source plan?" with options like "Paste it", "Provide a file path", "Provide an issue number/URL", "Cancel".
After resolving, store: source kind (github-issue, gitlab-issue, file, directory, pasted), source content (full text or directory listing + key files), and source identifier for the slug suggestion.
Step 2: Detect Format
Look at the resolved content and classify it as one of:
- OpenSpec: directory has both
proposal.mdandtasks.md. May also havespecs/**/spec.mddeltas. - spec-kit: directory or single file shows the spec-kit shape — separate spec/plan/tasks sections, often with explicit "Specification", "Implementation Plan", "Tasks" headings.
- Issue with checklist: source kind is
github-issueorgitlab-issue, and the body contains one or more- [ ]items. - Generic task-list: any structured source with headings and bullet items that is not OpenSpec, spec-kit, or an issue. Section heading style and item-marker style may vary.
- Free-form: prose-only or near-prose source with no clear task list. Includes brain-dump style text.
If multiple signals point in different directions (e.g., a directory with both a proposal.md and a clearly spec-kit-shaped plan.md), AskUser to confirm which format to use before drafting.
Step 3: Confidence Guard — Ask Before Drafting
Before writing any draft, scan the source for items the agent cannot confidently map. For each uncertainty, AskUser before drafting, never embed placeholder markers (???, TBD, [FIXME]) into the converted plan.
Common uncertainties:
- Which headings should become Task sections vs. Overview/Context vs. Technical Details?
- How should a long flat list be split into Tasks (logical phases vs. fixed groups)?
- A bullet item is vague ("clean up the auth module") — what concrete steps are intended?
- Source mixes intent (feature + refactor + bug fix) — should this become one plan or be flagged as multi-plan?
- Source is in a non-English natural language — ask whether to translate Overview/Context prose or preserve the original (the structural keyword
Taskin headers is always English regardless). - Source is very large (>1000 lines) or very small (<10 lines) — confirm scope before processing.
Use AskUserQuestion with concrete options. If the question is genuinely open-ended (more than 4 possibilities), present a numbered list in chat and ask the user to reply with a number.
Do not draft, then ask. Ask, then draft.
Step 4: Convert Per Format
All converted plans must satisfy ralphex's plan-format rules:
- File starts with
# <Plan Title>H1. - Standard sections in order:
## Overview,## Context,## Development Approach,## Testing Strategy,## Progress Tracking, optional## Technical Details(when source has architecture/spec details to preserve),## Implementation Steps, optional## Post-Completion. - Task headers use the structural form
### Task <N>: <title>. The keywordTaskis always English, even when the plan title and task titles are in another natural language. ralphex's plan parser only recognizes EnglishTaskandIterationkeywords; localized variants (Задача,タスク,Tarea, etc.) will not be detected. - Checkboxes (
- [ ]/- [x]) appear only inside Task sections. Do not put checkboxes in Overview, Context, Success criteria, or any other section — they cause the executor to spawn extra iterations. - Every Task should end with a "write tests" checkbox and a "run project tests" checkbox, phrased generically (project may be in any language).
- The final Task is always
### Task <last>: Verify acceptance criteriacontaining items that re-run the test suite, run the project linter, and confirm requirements from Overview were met.
Per-format mapping rules:
OpenSpec
proposal.md"## Why" or equivalent →## Overview(the problem statement and motivation)proposal.md"## What Changes" →## Context(impacted components and constraints)specs/**/spec.mddelta sections (ADDED / MODIFIED / REMOVED requirements) →## Technical Details(concrete behavior changes)tasks.mdnumbered list →## Implementation Stepsgrouped into### Task N:sections. Each top-level numbered group becomes a Task; sub-bullets become checkboxes.- Add
write testsandrun project testscheckboxes to each Task even if absent in source. - Append a final
### Task <last>: Verify acceptance criteriaTask.
spec-kit
- "Specification" section →
## Overviewand## Context - "Implementation Plan" / architecture section →
## Technical Details - "Tasks" section →
## Implementation Stepswith one### Task N:per logical phase - Add
write tests,run project tests, and finalVerify acceptance criteriaTask.
GitHub / GitLab Issue with Checklist
- Issue title →
# <Plan Title>(drop trailing punctuation, normalize whitespace) - Issue body prose above the first checklist →
## Overview - Issue labels and metadata →
## Context(e.g., "Reported in repo X, labels: bug, p1, area/auth") - Top-level
- [ ]items in body →## Implementation Steps- If the body has H3 sub-headings that group items, preserve those grouping into Tasks.
- Otherwise, group every 5–7 items into one Task; create a synthetic title summarizing the group.
- Preserve
- [x]checked state from the source. - Add
write testsandrun project testsper Task; append finalVerify acceptance criteriaTask.
Generic Task-List
- Infer the heading style (
#,##,###, or numbered headings) from the source. - Infer the item style (
- [ ],* [ ],1.,-, plain dashes). - Normalize:
- Top-level grouping headings become
### Task N: <title>(use EnglishTaskkeyword regardless of the source language). - Item lines become
- [ ]checkboxes inside the Task. - Preserve checked state if the source uses any form of "done" marker.
- Top-level grouping headings become
- If grouping is unclear (single flat list, ambiguous heading hierarchy), AskUser before drafting how to split.
- Add
write tests,run project tests, and finalVerify acceptance criteriaTask.
Free-Form Markdown
- Infer intent from the prose (feature / bug fix / refactor / migration / docs).
- First paragraph or two →
## Overview. - Background, constraints, references →
## Context. - Decompose the body into 3–7 Task groups by logical phase (read carefully; do not invent steps the source does not imply).
- For each Task, write 3–6 concrete checkboxes that map directly to phrases in the source. Do not embed
[FIXME]or???— if a phrase is too vague, AskUser in Step 3 first. - Add
write tests,run project tests, and finalVerify acceptance criteriaTask.
Output Skeleton (all formats)
# <Plan Title>
## Overview
<one or two paragraphs describing what is being built and why>
## Context
- <impacted components>
- <relevant constraints>
- <reference to source: e.g., "Adopted from issue #312" or "Adopted from OpenSpec change auth-rework">
## Development Approach
- Testing approach: regular (or TDD if source explicitly calls it out)
- Complete each task fully before moving to the next
- Update this plan when scope changes during implementation
## Testing Strategy
- Unit tests required for every code-changing Task
- Run project tests after each Task before proceeding
## Progress Tracking
- Mark completed items with `[x]` immediately when done
- Update plan if implementation deviates from original scope
## Technical Details
<optional: detailed behavior, data shapes, references to spec sections; omit this section if the source had no such content>
## Implementation Steps
### Task 1: <title>
- [ ] <concrete action>
- [ ] <concrete action>
- [ ] write tests for new functionality
- [ ] run project tests - must pass before next task
### Task 2: <title>
- [ ] <concrete action>
- [ ] write tests for new/changed functionality
- [ ] run project tests - must pass before next task
### Task <last>: Verify acceptance criteria
- [ ] verify all requirements from Overview are implemented
- [ ] run full project test suite
- [ ] run project linter - all issues must be fixed
## Post-Completion
*Items requiring manual intervention - no checkboxes, informational only*
- <manual verification steps if any>
- <external system updates if any>
Step 5: Review Loop With revdiff
Create a temp file and capture its path. Each Bash tool call runs in its own subshell, so shell variables (including $DRAFT) do not persist between calls. You must capture the literal path printed by mktemp and substitute that exact string into every subsequent tool call (Write, launcher, rm) — do not rely on $VAR references across calls.
Use a portable mktemp form. The -t prefix form differs between macOS BSD and Linux GNU. A template ending in XXXXXX is portable, but a suffix after XXXXXX (e.g., XXXXXX.md) is silently treated as a literal filename by BSD mktemp and would cause concurrent runs to collide on the same path. Generate the random path first, then rename to add the .md extension:
TMP=$(mktemp "${TMPDIR:-/tmp}/ralphex-adopt-XXXXXX") && mv "$TMP" "$TMP.md" && printf '%s\n' "$TMP.md"
Read the path from stdout (e.g., /tmp/ralphex-adopt-aB3xY9.md) and remember it. Refer to that literal string below as <draft-path>. Write the draft content to <draft-path> via the Write tool.
An EXIT trap is not used because each Bash call is its own subshell — the trap would fire immediately. Cleanup is explicit at the end of Step 6 (success) and on every cancel path (rm -f <draft-path> with the literal path substituted).
Run revdiff directly on the draft (bypass ~/.claude/scripts/draft-review.sh — that wrapper runs a writing-style lint that misfires on plan-shaped content and writes a publish-approval marker this skill does not need). Substitute the literal <draft-path> you captured above:
LAUNCHER="$HOME/.claude/plugins/marketplaces/revdiff/.claude-plugin/skills/revdiff/scripts/launch-revdiff.sh"
test -x "$LAUNCHER" && "$LAUNCHER" --wrap --only=<draft-path>
If the launcher path does not exist (test -x fails), skip directly to the in-chat fallback below — the user has revdiff installed via Homebrew or go install but does not have the Claude marketplace plugin layout.
Read the launcher's stdout from the Bash tool result directly. Do not assign it to a shell variable — variables do not persist between Bash tool calls (see Step 5 preamble).
- Empty stdout → user reviewed and approved silently. Proceed to Step 6.
- Non-empty stdout → user left annotations. Read each annotation, revise the draft accordingly (rewrite the literal
<draft-path>in place via Write), then re-run revdiff. Repeat until stdout is empty.
If the launcher path is missing, OR launch-revdiff.sh fails with any revdiff-related error (exit code non-zero with "revdiff" in stderr — "not found in PATH", "command not found", etc.), fall back to in-chat review:
- Print the draft content in chat.
- Use AskUserQuestion: "Approve draft?" with options "Accept", "Revise" (capture feedback as next message), "Reject" (cancel the conversion).
- On "Revise", treat the next user message as annotation text and revise; loop until "Accept".
Step 6: Write Target File
Compute the target filename:
- Date: today's date in
YYYYMMDDform (no dashes, e.g.,20260430). - Slug: derive from the plan title — lowercase, ASCII-only, words joined by
-, max ~50 characters. Drop articles (a/an/the) and trailing punctuation.
Use AskUserQuestion to confirm or edit the slug before writing:
- header: "Filename"
- question: "Use slug
<computed-slug>fordocs/plans/<date>-<slug>.md?" - options:
- label: "Yes, use this slug"
- label: "Edit slug" (capture next user message as the new slug)
- label: "Cancel"
If the target file already exists:
- Use AskUserQuestion: "
docs/plans/<filename>already exists. What should we do?" - options:
- label: "Bump suffix" — append
-v2, then-v3, ... to the slug; checkdocs/plans/anddocs/plans/completed/for collisions, increment until both are clear - label: "Pick a new slug" (capture next message)
- label: "Cancel"
- label: "Bump suffix" — append
- Never silent-overwrite.
Sanity-check the draft before writing:
- The draft must contain at least one
### Taskline that matches the form### Task <N>: <title>. - The draft must contain at least one
- [ ]checkbox under a Task section. - If either check fails, return to Step 4 to revise (do not write the file).
Once the filename is confirmed and sanity checks pass:
mkdir -p docs/plans
Write the draft content to docs/plans/<final-name>.md via the Write tool. Then explicitly clean up the temp file by substituting the literal <draft-path> captured in Step 5:
rm -f <draft-path>
Also run the same rm -f <draft-path> on any cancel path before exiting (Step 1, Step 3, Step 5 reject, Step 6 cancel) — always with the literal path substituted, never as $DRAFT.
Report to the user:
Adopted plan: docs/plans/<final-name>.md
Source: <source kind and identifier>
Tasks: <N>
Next: run `ralphex docs/plans/<final-name>.md` to execute.
Edge Cases
- Missing path: if user passed a path that does not exist, AskUser to correct or cancel.
- Ambiguous bare name: more than one match — AskUser to pick.
- URL fetch failure: AskUser to paste body as fallback.
- Directory with no recognizable structure: list contents, AskUser to point at the file.
- Format detection conflict: multiple signals — AskUser to choose format.
- Zero task-like content: source has no items the agent can convert — AskUser whether to infer Tasks from prose or cancel.
- Mixed localization: source mixes English and another language — confirm whether to keep the original language for prose. Structural
Taskkeyword stays English regardless. - Huge source (>1000 lines): warn before processing and AskUser whether to proceed, summarize, or split into multiple plans.
- Tiny source (<10 lines): warn that the result will be sparse; AskUser whether to proceed or expand interactively.
- Output collision: target file already exists — never silent overwrite (see Step 6).
- Idempotency: re-running on the same source uses today's date. Old converted plans in
docs/plans/completed/are never modified.
Tool Fallbacks
- revdiff missing: fall back to in-chat AskUser Accept/Revise/Reject loop (see Step 5).
- gh missing (when source is a GitHub issue/URL): AskUser to paste the issue body manually.
- glab missing (when source is a GitLab issue/URL): AskUser to paste the issue body manually.
- Both gh and glab missing for a
#Nargument: AskUser to paste the issue body or provide a different reference.
Constraints
- Never modify the source plan or directory.
- Never write to
docs/plans/without an explicit user-confirmed slug. - Never silently overwrite an existing target file.
- Never embed placeholder markers (
???,TBD,[FIXME]) in the output — AskUser before drafting instead. - Never assume the target project is a specific language. Test/run-test checkboxes must use generic phrasing such as "write tests" and "run project tests".
- Never cite ralphex internal source files (e.g.,
pkg/...) in the converted plan content. - Do not run tests, do not run linters, do not commit, do not push. The skill only produces a plan file.
assets/claude/skills/ralphex-plan/SKILL.md
npx skills add umputun/ralphex --skill ralphex-plan -g -y
SKILL.md
Frontmatter
{
"name": "ralphex-plan",
"description": "Create structured implementation plan in docs\/plans\/"
}
Implementation Plan Creation
Create an implementation plan in docs/plans/YYYYMMDD-<task-name>.md with interactive context gathering.
Prerequisites: Verify CLI Installation
Check if ralphex CLI is installed (needed to execute the plan after creation):
which ralphex
If not found, inform user they'll need it to execute the plan:
- macOS (Homebrew):
brew install umputun/apps/ralphex - Linux (Debian/Ubuntu): download
.debfrom https://github.com/umputun/ralphex/releases - Linux (RHEL/Fedora): download
.rpmfrom https://github.com/umputun/ralphex/releases - Any platform with Go:
go install github.com/umputun/ralphex/cmd/ralphex@latest
Proceed with plan creation regardless, but remind user to install before execution.
Step 0: Parse Intent and Gather Context
Before asking questions, understand what the user is working on:
-
Parse user's command arguments to identify intent:
- "add feature Z" / "implement W" → feature development
- "fix bug" / "debug issue" → bug fix plan
- "refactor X" / "improve Y" → refactoring plan
- "migrate to Z" / "upgrade W" → migration plan
- generic request → explore current work
-
Launch Explore agent (via Task tool with
subagent_type: Explore) to gather relevant context based on intent:For feature development:
- locate related existing code and patterns
- check project structure (README, config files, existing similar implementations)
- identify affected components and dependencies
For bug fixing:
- look for error logs, test failures, or stack traces
- find related code that might be involved
- check recent git changes in problem areas
For refactoring/migration:
- identify all files/components affected
- check test coverage of affected areas
- find dependencies and integration points
For generic/unclear requests:
- check
git statusand recent file activity - examine current working directory structure
- identify primary language/framework from file extensions and config files
-
Synthesize findings into context summary:
- what work is in progress
- which files/areas are involved
- what the apparent goal is
- relevant patterns or structure discovered
Step 1: Present Context and Ask Focused Questions
Show the discovered context, then ask questions one at a time using the AskUserQuestion tool:
"Based on your request, I found: [context summary]"
Ask questions one at a time (do not overwhelm with multiple questions):
-
Plan purpose: use AskUserQuestion - "What is the main goal?"
- provide multiple choice with suggested answer based on discovered intent
- wait for response before next question
-
Scope: use AskUserQuestion - "Which components/files are involved?"
- provide multiple choice with suggested discovered files/areas
- wait for response before next question
-
Constraints: use AskUserQuestion - "Any specific requirements or limitations?"
- can be open-ended if constraints vary widely
- wait for response before next question
-
Testing approach: use AskUserQuestion - "Do you prefer TDD or regular approach?"
- options: "TDD (tests first)" and "Regular (code first, then tests)"
- store preference for reference during implementation
- wait for response before next question
-
Plan title: use AskUserQuestion - "Short descriptive title?"
- provide suggested name based on intent
After all questions answered, synthesize responses into plan context.
Step 1.5: Explore Approaches
Once the problem is understood, propose implementation approaches:
- Propose 2-3 different approaches with trade-offs for each
- Lead with recommended option and explain reasoning
- Present conversationally - not a formal document yet
Example format:
I see three approaches:
**Option A: [name]** (recommended)
- How it works: ...
- Pros: ...
- Cons: ...
**Option B: [name]**
- How it works: ...
- Pros: ...
- Cons: ...
Which direction appeals to you?
Use AskUserQuestion tool to let user select preferred approach before creating the plan.
Skip this step if:
- the implementation approach is obvious (single clear path)
- user explicitly specified how they want it done
- it's a bug fix with clear solution
Step 2: Create Plan File
Check docs/plans/ for existing files, then create docs/plans/YYYYMMDD-<task-name>.md:
Plan Structure
# [Plan Title]
## Overview
- Clear description of the feature/change being implemented
- Problem it solves and key benefits
- How it integrates with existing system
## Context (from discovery)
- Files/components involved: [list from step 0]
- Related patterns found: [patterns discovered]
- Dependencies identified: [dependencies]
## Development Approach
- **Testing approach**: [TDD / Regular - from user preference in planning]
- Complete each task fully before moving to the next
- Make small, focused changes
- **CRITICAL: every task MUST include new/updated tests** for code changes in that task
- tests are not optional - they are a required part of the checklist
- write unit tests for new functions/methods
- write unit tests for modified functions/methods
- add new test cases for new code paths
- update existing test cases if behavior changes
- tests cover both success and error scenarios
- **CRITICAL: all tests must pass before starting next task** - no exceptions
- **CRITICAL: update this plan file when scope changes during implementation**
- Run tests after each change
- Maintain backward compatibility
## Testing Strategy
- **Unit tests**: required for every task (see Development Approach above)
- **E2E tests**: if project has UI-based e2e tests (Playwright, Cypress, etc.):
- UI changes → add/update e2e tests in same task as UI code
- Backend changes supporting UI → add/update e2e tests in same task
- Treat e2e tests with same rigor as unit tests (must pass before next task)
- Store e2e tests alongside unit tests (or in designated e2e directory)
## Progress Tracking
- Mark completed items with `[x]` immediately when done
- Add newly discovered tasks with ➕ prefix
- Document issues/blockers with ⚠️ prefix
- Update plan if implementation deviates from original scope
- Keep plan in sync with actual work done
## What Goes Where
- **Implementation Steps** (`[ ]` checkboxes): tasks achievable within this codebase - code changes, tests, documentation updates
- **Post-Completion** (no checkboxes): items requiring external action - manual testing, changes in consuming projects, deployment configs, third-party verifications
- **Checkbox placement**: Checkboxes belong only in Task sections (`### Task N:` or `### Iteration N:`). Do not put checkboxes in Success criteria, Overview, or Context — they cause extra loop iterations.
## Implementation Steps
<!--
Task structure guidelines:
- Each task = ONE logical unit (one function, one endpoint, one component)
- Use specific descriptive names, not generic "[Core Logic]" or "[Implementation]"
- Aim for ~5 checkboxes per task (more is OK if logically atomic)
- **CRITICAL: Each task MUST end with writing/updating tests before moving to next**
- tests are not optional - they are a required deliverable of every task
- write tests for all NEW code added in this task
- write tests for all MODIFIED code in this task
- include both success and error scenarios in tests
- list tests as SEPARATE checklist items, not bundled with implementation
Example (NOTICE: tests are separate checklist items):
### Task 1: Add password hashing utility
- [ ] create `auth/hash` module with HashPassword and VerifyPassword functions
- [ ] implement secure hashing with configurable cost
- [ ] write tests for HashPassword (success + error cases)
- [ ] write tests for VerifyPassword (success + error cases)
- [ ] run project tests - must pass before task 2
### Task 2: Add user registration endpoint
- [ ] create `POST /api/users` handler
- [ ] add input validation (email format, password strength)
- [ ] integrate with password hashing utility
- [ ] write tests for handler success case with table-driven cases
- [ ] write tests for handler error cases (invalid input, missing fields)
- [ ] run project tests - must pass before task 3
-->
### Task 1: [specific name - what this task accomplishes]
- [ ] [specific action with file reference - code implementation]
- [ ] [specific action with file reference - code implementation]
- [ ] write tests for new/changed functionality (success cases)
- [ ] write tests for error/edge cases
- [ ] run tests - must pass before next task
### Task N-1: Verify acceptance criteria
- [ ] verify all requirements from Overview are implemented
- [ ] verify edge cases are handled
- [ ] run full test suite (unit tests)
- [ ] run e2e tests if project has them
- [ ] run linter - all issues must be fixed
- [ ] verify test coverage meets project standard (80%+)
*Note: manual testing, deployment verification, and external checks go in Post-Completion (no checkboxes). Task section checkboxes must be automatable by the agent.*
### Task N: [Final] Update documentation
- [ ] update README.md if needed
- [ ] update project knowledge docs if new patterns discovered
*Note: ralphex automatically moves completed plans to `docs/plans/completed/`*
## Technical Details
- Data structures and changes
- Parameters and formats
- Processing flow
## Post-Completion
*Items requiring manual intervention or external systems - no checkboxes, informational only*
**Manual verification** (if applicable):
- Manual UI/UX testing scenarios
- Performance testing under load
- Security review considerations
**External system updates** (if applicable):
- Consuming projects that need updates after this library change
- Configuration changes in deployment systems
- Third-party service integrations to verify
Step 3: Offer to Start
After creating the file, tell user:
"Created plan: docs/plans/YYYYMMDD-<task-name>.md
Ready to start implementation?"
If yes, begin with task 1.
Execution Enforcement
CRITICAL testing rules during implementation:
-
After completing code changes in a task:
- STOP before moving to next task
- Add tests for all new functionality
- Update tests for modified functionality
- Run project test command
- Mark completed items with
[x]in plan file - Use TodoWrite tool to track progress and mark todos completed immediately (do not batch)
-
If tests fail:
- Fix the failures before proceeding
- Do NOT move to next task with failing tests
- Do NOT skip test writing
-
Only proceed to next task when:
- All task items completed and marked
[x] - Tests written/updated
- All tests passing
- All task items completed and marked
-
Plan tracking during implementation:
- Update checkboxes immediately when tasks complete
- Add ➕ prefix for newly discovered tasks
- Add ⚠️ prefix for blockers
- Modify plan if scope changes significantly
-
On completion:
- Verify all checkboxes marked
- Run final test suite
- ralphex automatically moves plan to
docs/plans/completed/
-
Partial implementation exception:
- If a task provides partial implementation where tests cannot pass until a later task:
- Still write the tests as part of this task (required)
- Add TODO comment in test code noting the dependency
- Mark the test checkbox as completed with note:
[x] write tests ... (fails until Task X) - Do NOT skip test writing or defer until later
- When the dependent task completes, remove the TODO comment and verify tests pass
- If a task provides partial implementation where tests cannot pass until a later task:
This ensures each task is solid before building on top of it.
Key Principles
- One question at a time - do not overwhelm user with multiple questions in a single message
- Multiple choice preferred - easier to answer than open-ended when possible
- YAGNI ruthlessly - remove unnecessary features from all designs, keep scope minimal
- Lead with recommendation - have an opinion, explain why, but let user decide
- Explore alternatives - always propose 2-3 approaches before settling (unless obvious)
- Duplication vs abstraction - when code repeats, ask user: prefer duplication (simpler, no coupling) or abstraction (DRY but adds complexity)? explain trade-offs before deciding
assets/claude/skills/ralphex-update/SKILL.md
npx skills add umputun/ralphex --skill ralphex-update -g -y
SKILL.md
Frontmatter
{
"name": "ralphex-update",
"description": "Smart-merge updated ralphex defaults into customized prompts\/agents",
"allowed-tools": [
"Bash",
"Read",
"Write",
"Glob",
"AskUserQuestion"
]
}
ralphex-update - Smart Prompt Merging
SCOPE: Compare current embedded defaults with user's installed config, and intelligently merge updates into customized files. Preserves user intent while incorporating structural changes.
Step 0: Verify CLI Installation
which ralphex
If not found, guide installation:
- macOS (Homebrew):
brew install umputun/apps/ralphex - Any platform with Go:
go install github.com/umputun/ralphex/cmd/ralphex@latest
Do not proceed until which ralphex succeeds.
Step 1: Extract Current Defaults
Create temp directory and dump embedded defaults:
DUMP_DIR=$(mktemp -d /tmp/ralphex-defaults-XXXX)
ralphex --dump-defaults "$DUMP_DIR"
echo "$DUMP_DIR"
Save the dump directory path for later use.
Step 2: Determine Config Directory
Resolve the user's config directory:
# check environment variable first
echo "${RALPHEX_CONFIG_DIR:-}"
If RALPHEX_CONFIG_DIR is empty, use default:
- macOS/Linux:
~/.config/ralphex/
Verify the directory exists:
ls -la <config-dir>/
If it doesn't exist, inform user that ralphex hasn't been configured yet and there's nothing to update.
How ralphex Config Files Work
ralphex installs config, prompt, and agent files with all content commented out (every line prefixed with # ). At runtime, stripComments() removes these lines, finds nothing, and falls back to embedded defaults compiled into the binary. These all-commented files are functionally identical to missing files — they are do-nothing placeholders.
When ralphex is updated, new embedded defaults take effect automatically for every file that hasn't been customized. No file changes are needed.
A file is customized only if it contains at least one uncommented, non-empty line that was intentionally modified by the user. The --dump-defaults command produces the raw (uncommented) embedded content for comparison.
Step 3: Compare Files
For each file in the defaults dump (config, prompts/*.txt, agents/*.txt), compare with the corresponding file in the user's config directory.
Algorithm to detect customized files: a file is customized if it contains at least one non-empty line that does NOT start with #. Files that are missing, empty, or contain only comment lines (# ...) and whitespace are do-nothing defaults.
Classify each file into one of these categories:
Skip (do-nothing default)
- File is missing in user's config, OR
- File is empty, OR
- File contains only comments and whitespace (every non-empty line starts with
#) - Action: no action needed — embedded defaults handle it automatically
Note: files that exist only in the dump directory (no corresponding user file) are also do-nothing — do NOT offer to install them. Files that exist only in the user's config directory (no corresponding dump file) are user-created custom files — ignore them entirely.
Skip (unchanged)
- File has uncommented content that matches the raw dump default
- Action: no action needed — user's file already matches current defaults
How to compare: strip all #-prefixed lines from BOTH the user's file and the dump file, then compare the remaining non-comment content. This handles the config file where the dump has descriptive comment lines mixed with value lines — only the actual values matter for comparison.
Smart merge needed
- File has uncommented content that differs from the raw dump default (after stripping
#-prefixed lines from both sides) - Action: needs Claude to semantically analyze and propose merge
Step 4: Present Summary
Show the user a summary with two groups:
ralphex config update summary:
No changes needed (N files):
prompts/task.txt, prompts/review_first.txt, agents/quality.txt, prompts/codex.txt, ...
Smart merge needed (N files):
prompts/review_second.txt, agents/implementation.txt
If nothing needs merging, report "all config files are up to date — no changes needed" and skip to cleanup.
Otherwise, use AskUserQuestion to confirm proceeding:
- header: "Proceed"
- question: "Review smart merges? Each customized file will be reviewed one by one."
- options:
- label: "Yes, proceed" description: "Review and merge customized files one at a time"
- label: "Skip, just show details" description: "Show what changed without modifying anything"
If user selects "Skip, just show details": for each file needing smart merge, show the diff between the user's file and the new default, then skip to Step 6 (Cleanup) without modifying any files.
Step 5: Process Smart Merges
For each customized file that needs merging:
-
Read both versions - the new default and the user's current version
-
Analyze the differences semantically:
- What did the user customize? (added content, changed wording, different instructions)
- What changed in the new default? (structural changes, new template variables, new sections, removed sections)
-
Propose a merged version that:
- Preserves user additions not present in defaults
- Applies structural/pattern changes from new defaults
- Updates template variable references (e.g., new
{{VARIABLE}}usage) - Preserves user's tone and style choices
- Flags direct conflicts where both changed the same thing
-
Show the user:
- Brief summary of what changed in defaults
- Brief summary of what user customized
- The proposed merged version
-
Use AskUserQuestion for each file:
- header: "Merge"
- question: "How to handle
?" - options:
- label: "Accept merge" description: "Use the proposed merged version"
- label: "Keep mine" description: "Keep your current version unchanged"
- label: "Use new default" description: "Replace with new default (discard customizations)"
-
Apply the user's choice
Step 6: Cleanup
Remove the temp directory:
rm -rf <dump-dir>
Report final summary:
Update complete:
Skipped: N files (no changes needed)
Smart-merged: N files (M accepted, K kept)
Merge Principles
When proposing smart merges, follow these rules:
- Preserve user additions: content the user added that doesn't exist in defaults should be kept
- Apply structural changes: if defaults restructured prompts (e.g., changed from sequential to parallel agents), apply the new structure while keeping user's custom content
- Update template variables: if new
{{VARIABLE}}references were added to defaults, include them in the merge - Preserve user tone/style: if user rewrote instructions in a different style, keep their style while incorporating new functionality
- Flag conflicts clearly: if both user and defaults changed the same section differently, present both versions and let the user choose
- Don't lose information: when in doubt, keep both versions with clear markers
Constraints
- This command is ONLY for updating ralphex configuration files
- Do NOT modify any project source code
- Do NOT run ralphex execution or review
- Do NOT touch files outside the config directory
- Always clean up the temp directory when done
assets/claude/skills/ralphex/SKILL.md
npx skills add umputun/ralphex --skill ralphex -g -y
SKILL.md
Frontmatter
{
"name": "ralphex",
"description": "Run ralphex autonomous plan execution with progress monitoring",
"allowed-tools": [
"Bash",
"Read",
"AskUserQuestion",
"TaskOutput",
"Glob"
],
"argument-hint": "optional plan file path"
}
ralphex - Autonomous Plan Execution
SCOPE: This command ONLY launches ralphex, monitors progress, and reports status. Do NOT take any other actions.
Step 0: Verify CLI Installation
Check if ralphex CLI is installed:
which ralphex
If not found, guide installation based on platform:
- macOS (Homebrew):
brew install umputun/apps/ralphex - Linux (Debian/Ubuntu): download
.debfrom https://github.com/umputun/ralphex/releases - Linux (RHEL/Fedora): download
.rpmfrom https://github.com/umputun/ralphex/releases - Any platform with Go:
go install github.com/umputun/ralphex/cmd/ralphex@latest
Use AskUserQuestion to confirm installation method, then guide through it. Do not proceed until which ralphex succeeds.
Step 1: Check for Plan Argument
Check $ARGUMENTS for optional plan file path:
- if argument provided: validate file exists using Read tool, skip plan selection in Step 3
- if no argument: will ask for plan selection in Step 3
Step 2: Ask Execution Mode
Use AskUserQuestion:
- header: "Mode"
- question: "Which execution mode should ralphex use?"
- options:
- label: "Full (Recommended)" description: "Task execution + Claude review + Codex loop + final Claude review"
- label: "Review" description: "Skip tasks, run full review pipeline (Claude + Codex + Claude)"
- label: "Codex-only" description: "Skip tasks and first Claude review, run only Codex loop"
Step 3: Plan Selection (if no argument provided)
If Full mode selected:
- Use Glob:
docs/plans/*.md(excludes completed/) - Plan is REQUIRED
- IMPORTANT: Glob returns oldest-first, so REVERSE the list to get most recent first
- Build AskUserQuestion with up to 4 most recent plans
- First option (most recent) should have "(Recommended)" suffix
- User MUST select one
If Review or Codex-only mode selected:
- Use Glob:
docs/plans/**/*.md(includes completed/ for context) - Plan is OPTIONAL
- IMPORTANT: Glob returns oldest-first, so REVERSE the list to get most recent first
- Build AskUserQuestion with up to 4 most recent plans PLUS "None" option at the end
- First plan option (most recent) should have "(Recommended)" suffix
- "None" option description: "Review existing changes without a plan file"
- If user selects "None", run without plan file
Step 4: Ask Max Iterations
Use AskUserQuestion:
- header: "Iterations"
- question: "Maximum number of task iterations?"
- options:
- label: "50 (Recommended)" description: "Default - suitable for most plans"
- label: "25" description: "Shorter plans or quick iterations"
- label: "100" description: "Large plans with many tasks"
Step 5: Launch ralphex in Background
Build and run the command:
ralphex \
[--review] # if user selected "Review" mode
[--codex-only] # if user selected "Codex-only" mode
[--max-iterations N] # from user selection (25, 50, or 100)
[plan-file] # from argument OR plan selection (omit if "None" selected)
Run using Bash tool with run_in_background: true. Save the task_id from the response - needed for status checks later.
Determine progress filename based on mode and plan selection:
- Full mode + plan:
.ralphex/progress/progress-{plan-stem}.txt - Review mode + plan:
.ralphex/progress/progress-{plan-stem}-review.txt - Codex-only + plan:
.ralphex/progress/progress-{plan-stem}-codex.txt - Full mode + no plan:
.ralphex/progress/progress.txt - Review mode + no plan:
.ralphex/progress/progress-review.txt - Codex-only + no plan:
.ralphex/progress/progress-codex.txt
Where {plan-stem} is the plan filename without extension (e.g., fix-bugs from fix-bugs.md).
Step 6: Confirm Launch
- Wait 10-15 seconds for initialization
- Read last 20 lines of progress file:
tail -20 [progress-filename] - Confirm ralphex started by checking for "Plan:", "Branch:", "Started:" lines
- Report launch confirmation:
ralphex started. Task ID: [task_id]
Plan: [plan file from progress file]
Branch: [branch from progress file]
Mode: [mode from progress file]
Progress file: [progress-filename]
Manual monitoring:
tail -f [progress-filename] # live stream
tail -50 [progress-filename] # recent activity
ralphex runs autonomously (can take hours). Process continues if you close this conversation.
Ask "check ralphex" to get status update.
STOP HERE after reporting launch status. Do not continue monitoring automatically.
Step 7: Progress Check (only on explicit user request)
If user explicitly asks "check ralphex", "ralphex status", or "how is ralphex doing":
- Use TaskOutput tool with
block: falseto check process status (use task_id from Step 5) - Read last 40 lines of progress file (use filename from Step 5)
If process still running:
- Report current phase from progress file:
- "task iteration N" → Task Execution phase
- "codex iteration N" → Codex External Review phase
- "review pass 1/2" → Claude Review phase
- Show recent activity lines
If process exited (TaskOutput shows completion):
- Exit code 0 → success, report "ralphex completed successfully"
- Exit code non-zero → failure, report "ralphex failed"
- Read final lines of progress file for summary
After reporting status, STOP. Do not offer to do anything else.
Constraints
- This command is ONLY for launching and monitoring ralphex
- Do NOT offer to help with code, commits, PRs, or anything else
- Do NOT make suggestions or recommendations beyond status reporting
- Do NOT take any actions on the codebase
- After launch confirmation: wait for user to explicitly request status check
- After status check: report and stop
Nested Claude Code Sessions
ralphex automatically strips the CLAUDECODE env var from child processes, allowing it to run from inside Claude Code. If the nested session error is somehow encountered, ralphex detects it via error pattern matching and exits gracefully instead of looping.
Running from a standalone terminal is still recommended for the best experience.


