feat: add Ralph Loop self-referential development loop (#337)
* feat(config): add RalphLoopConfigSchema and hook name - Add ralph-loop to HookNameSchema enum - Add RalphLoopConfigSchema with enabled, default_max_iterations, state_dir - Add ralph_loop field to OhMyOpenCodeConfigSchema - Export RalphLoopConfig type * feat(ralph-loop): add hook directory structure with constants and types - Add constants.ts with HOOK_NAME, DEFAULT_STATE_FILE, COMPLETION_TAG_PATTERN - Add types.ts with RalphLoopState and RalphLoopOptions interfaces - Export RalphLoopConfig from config/index.ts * feat(ralph-loop): add storage module for markdown state file management - Implement readState/writeState/clearState/incrementIteration - Use YAML frontmatter format for state persistence - Support custom state file paths via config * feat(ralph-loop): implement main hook with session.idle handler - Add createRalphLoopHook factory with event handler - Implement startLoop, cancelLoop, getState API - Detect completion promise in transcript - Auto-continue with iteration tracking - Handle max iterations limit - Show toast notifications for status updates - Support session recovery and cleanup * test(ralph-loop): add comprehensive BDD-style tests - Add 17 test cases covering storage, hook lifecycle, iteration - Test completion detection, cancellation, recovery, session cleanup - Fix storage.ts to handle YAML value parsing correctly - Use BDD #given/#when/#then comments per project convention * feat(builtin-commands): add ralph-loop and cancel-ralph commands * feat(ralph-loop): register hook in main plugin * docs: add Ralph Loop feature to all README files * chore: regenerate JSON schema with ralph-loop config * feat(ralph-loop): change state file path from .opencode to .sisyphus 🤖 Generated with assistance of https://github.com/code-yeongyu/oh-my-opencode * feat(ralph-loop): integrate ralph-loop and cancel-ralph command handlers into plugin hooks - Add chat.message hook to detect and start ralph-loop or cancel-ralph templates - Add slashcommand hook to handle /ralph-loop and /cancel-ralph commands - Support custom --max-iterations and --completion-promise options 🤖 Generated with assistance of https://github.com/code-yeongyu/oh-my-opencode --------- Co-authored-by: sisyphus-dev-ai <sisyphus-dev-ai@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import type { CommandDefinition } from "../claude-code-command-loader"
|
||||
import type { BuiltinCommandName, BuiltinCommands } from "./types"
|
||||
import { INIT_DEEP_TEMPLATE } from "./templates/init-deep"
|
||||
import { RALPH_LOOP_TEMPLATE, CANCEL_RALPH_TEMPLATE } from "./templates/ralph-loop"
|
||||
|
||||
const BUILTIN_COMMAND_DEFINITIONS: Record<BuiltinCommandName, Omit<CommandDefinition, "name">> = {
|
||||
"init-deep": {
|
||||
@@ -14,6 +15,23 @@ $ARGUMENTS
|
||||
</user-request>`,
|
||||
argumentHint: "[--create-new] [--max-depth=N]",
|
||||
},
|
||||
"ralph-loop": {
|
||||
description: "(builtin) Start self-referential development loop until completion",
|
||||
template: `<command-instruction>
|
||||
${RALPH_LOOP_TEMPLATE}
|
||||
</command-instruction>
|
||||
|
||||
<user-task>
|
||||
$ARGUMENTS
|
||||
</user-task>`,
|
||||
argumentHint: '"task description" [--completion-promise=TEXT] [--max-iterations=N]',
|
||||
},
|
||||
"cancel-ralph": {
|
||||
description: "(builtin) Cancel active Ralph Loop",
|
||||
template: `<command-instruction>
|
||||
${CANCEL_RALPH_TEMPLATE}
|
||||
</command-instruction>`,
|
||||
},
|
||||
}
|
||||
|
||||
export function loadBuiltinCommands(
|
||||
|
||||
38
src/features/builtin-commands/templates/ralph-loop.ts
Normal file
38
src/features/builtin-commands/templates/ralph-loop.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
export const RALPH_LOOP_TEMPLATE = `You are starting a Ralph Loop - a self-referential development loop that runs until task completion.
|
||||
|
||||
## How Ralph Loop Works
|
||||
|
||||
1. You will work on the task continuously
|
||||
2. When you believe the task is FULLY complete, output: \`<promise>{{COMPLETION_PROMISE}}</promise>\`
|
||||
3. If you don't output the promise, the loop will automatically inject another prompt to continue
|
||||
4. Maximum iterations: Configurable (default 100)
|
||||
|
||||
## Rules
|
||||
|
||||
- Focus on completing the task fully, not partially
|
||||
- Don't output the completion promise until the task is truly done
|
||||
- Each iteration should make meaningful progress toward the goal
|
||||
- If stuck, try different approaches
|
||||
- Use todos to track your progress
|
||||
|
||||
## Exit Conditions
|
||||
|
||||
1. **Completion**: Output \`<promise>DONE</promise>\` (or custom promise text) when fully complete
|
||||
2. **Max Iterations**: Loop stops automatically at limit
|
||||
3. **Cancel**: User runs \`/cancel-ralph\` command
|
||||
|
||||
## Your Task
|
||||
|
||||
Parse the arguments below and begin working on the task. The format is:
|
||||
\`"task description" [--completion-promise=TEXT] [--max-iterations=N]\`
|
||||
|
||||
Default completion promise is "DONE" and default max iterations is 100.`
|
||||
|
||||
export const CANCEL_RALPH_TEMPLATE = `Cancel the currently active Ralph Loop.
|
||||
|
||||
This will:
|
||||
1. Stop the loop from continuing
|
||||
2. Clear the loop state file
|
||||
3. Allow the session to end normally
|
||||
|
||||
Check if a loop is active and cancel it. Inform the user of the result.`
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { CommandDefinition } from "../claude-code-command-loader"
|
||||
|
||||
export type BuiltinCommandName = "init-deep"
|
||||
export type BuiltinCommandName = "init-deep" | "ralph-loop" | "cancel-ralph"
|
||||
|
||||
export interface BuiltinCommandConfig {
|
||||
disabled_commands?: BuiltinCommandName[]
|
||||
|
||||
Reference in New Issue
Block a user