almost
This commit is contained in:
38
tasks/ralph-loop-fixes/01-fix-loadconfig-graceful-default.md
Normal file
38
tasks/ralph-loop-fixes/01-fix-loadconfig-graceful-default.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# 01. Fix `loadConfig` to return defaults gracefully when `.ralph/config.yaml` is missing
|
||||
|
||||
meta:
|
||||
id: ralph-loop-fixes-01
|
||||
feature: ralph-loop-fixes
|
||||
priority: P1
|
||||
depends_on: []
|
||||
tags: [implementation, utils]
|
||||
|
||||
objective:
|
||||
- `loadConfig()` should return `DEFAULT_CONFIG` silently when `.ralph/config.yaml` does not exist, without logging a warning to stderr
|
||||
|
||||
deliverables:
|
||||
- Modified `src/utils.ts` — `loadConfig()` function
|
||||
|
||||
steps:
|
||||
- Open `src/utils.ts` and locate `loadConfig()`
|
||||
- Add `fs.existsSync()` check before `fs.readFileSync()`
|
||||
- If config file does not exist, return a deep copy of `DEFAULT_CONFIG` without any console output
|
||||
- If config file exists but is malformed, fall back to defaults silently
|
||||
- Remove or suppress the `console.warn()` call
|
||||
|
||||
tests:
|
||||
- Manual: Run `/ralph resume` in a project directory with no `.ralph/` directory — should not print warning
|
||||
- Manual: Run `/ralph run` in a project with `.ralph/progress.json` but no `config.yaml` — should proceed with defaults
|
||||
|
||||
acceptance_criteria:
|
||||
- No console warning when config.yaml is missing
|
||||
- `loadConfig()` returns a valid `RalphConfig` object in all cases
|
||||
- Existing behavior with valid config.yaml is unchanged
|
||||
|
||||
validation:
|
||||
- Check `src/utils.ts` loadConfig function returns silently on missing file
|
||||
- Verify no `console.warn` or `console.error` in the missing-config path
|
||||
|
||||
notes:
|
||||
- Current code at line ~145 in utils.ts: `fs.readFileSync(configPath, "utf-8")` throws ENOENT
|
||||
- The try-catch does catch it but still logs the warning — the warning is noisy for normal usage where config is optional
|
||||
42
tasks/ralph-loop-fixes/02-fix-spawnpi-print-mode.md
Normal file
42
tasks/ralph-loop-fixes/02-fix-spawnpi-print-mode.md
Normal file
@@ -0,0 +1,42 @@
|
||||
# 02. Replace `spawnPi` with `--print` mode and stdin piping
|
||||
|
||||
meta:
|
||||
id: ralph-loop-fixes-02
|
||||
feature: ralph-loop-fixes
|
||||
priority: P1
|
||||
depends_on: []
|
||||
tags: [implementation, utils]
|
||||
|
||||
objective:
|
||||
- Replace `spawnPi()` so it invokes `pi --print` with prompt content piped via stdin, instead of using non-existent `--no-stream` and `--prompt` flags
|
||||
|
||||
deliverables:
|
||||
- Modified `src/utils.ts` — `spawnPi()` function
|
||||
- Updated `src/executor.ts` — import and call site for `spawnPi`
|
||||
|
||||
steps:
|
||||
- Open `src/utils.ts` and locate `spawnPi()`
|
||||
- Replace `spawnSync` args from `["--no-stream", "--prompt", promptFile, ...]` to `["--print"]`
|
||||
- Read the prompt file content and pass it as `input` to `spawnSync`
|
||||
- The `input` option accepts a string that is piped to the child process stdin
|
||||
- Keep `encoding`, `timeout`, and `maxBuffer` options as-is
|
||||
- Update the function signature if needed (no longer needs `promptFile` path, can take prompt content directly, or read it internally)
|
||||
|
||||
tests:
|
||||
- Manual: Spawn pi with a simple prompt — verify it returns text output and exits cleanly
|
||||
- Manual: Verify `result.stdout` contains the pi response text (not NDJSON or event stream)
|
||||
|
||||
acceptance_criteria:
|
||||
- `spawnPi()` exits with code 0 on successful execution
|
||||
- `result.stdout` contains plain text response from pi
|
||||
- No "Unknown options: --no-stream, --prompt" error
|
||||
|
||||
validation:
|
||||
- Run `pi --print` with piped input manually to verify behavior
|
||||
- Check spawnSync call uses `["--print"]` args and `input` option
|
||||
|
||||
notes:
|
||||
- Pi's `--print` flag runs in non-interactive mode: reads from stdin, writes to stdout, exits
|
||||
- `spawnSync` accepts an `input` option (string) that pipes to child stdin
|
||||
- Current broken args: `["--no-stream", "--prompt", promptFile]`
|
||||
- The `extractTextFromEvent()` function can be simplified or removed since `--print` returns plain text
|
||||
47
tasks/ralph-loop-fixes/03-replace-sendmessage-with-ctx-ui.md
Normal file
47
tasks/ralph-loop-fixes/03-replace-sendmessage-with-ctx-ui.md
Normal file
@@ -0,0 +1,47 @@
|
||||
# 03. Replace `sendMessage` with `ctx.ui` progress API
|
||||
|
||||
meta:
|
||||
id: ralph-loop-fixes-03
|
||||
feature: ralph-loop-fixes
|
||||
priority: P1
|
||||
depends_on: [ralph-loop-fixes-04]
|
||||
tags: [implementation, executor]
|
||||
|
||||
objective:
|
||||
- Replace all `piApi.sendMessage({ customType: "ralph-progress", display: true })` calls with `ctx.ui.notify()` and `ctx.ui.setStatus()` to avoid TUI crash from unregistered custom message renderer
|
||||
|
||||
deliverables:
|
||||
- Modified `src/executor.ts` — remove `sendProgressMessage()`, replace with `ctx.ui` calls
|
||||
- Modified `src/executor.ts` — remove `formatToolUsage()` if no longer needed, or keep for status text
|
||||
|
||||
steps:
|
||||
- Open `src/executor.ts`
|
||||
- Remove `sendProgressMessage()` function entirely
|
||||
- In `runTask()`, replace `sendProgressMessage(piApi, task, project, "starting")` with `ctx.ui.setStatus("ralph", "Running ${task.id}: ${task.title}")`
|
||||
- In `runTask()` success path, replace `sendProgressMessage(..., "completed")` with `ctx.ui.notify()` for completion summary
|
||||
- In `runTask()` failure path, replace `sendProgressMessage(..., "failed")` with `ctx.ui.notify()` for error
|
||||
- In `executeBatch()`, replace batch start `piApi.sendMessage()` with `ctx.ui.setStatus()`
|
||||
- In `executeTask()`, replace retry `piApi.sendMessage()` with `ctx.ui.notify()`
|
||||
- Remove `piApi: ExtensionAPI` parameter from all executor functions (replaced by `ctx: ExtensionCommandContext`)
|
||||
- Remove unused `ExtensionAPI` import from executor.ts
|
||||
|
||||
tests:
|
||||
- Manual: Run a task and verify progress appears in the Pi UI without crash
|
||||
- Manual: Verify no `child.render is not a function` error
|
||||
|
||||
acceptance_criteria:
|
||||
- No TUI crash during task execution
|
||||
- Progress messages visible to user via `ctx.ui`
|
||||
- `sendProgressMessage()` function removed from codebase
|
||||
- `piApi.sendMessage()` no longer called anywhere in executor
|
||||
|
||||
validation:
|
||||
- Grep for `sendMessage` in executor.ts — should only appear in comments or not at all
|
||||
- Grep for `customType.*ralph-progress` — should be removed
|
||||
- Verify `ctx.ui.notify` and `ctx.ui.setStatus` are used instead
|
||||
|
||||
notes:
|
||||
- `ctx.ui.notify(message, type)` shows a notification — use "info" for progress, "error" for failures
|
||||
- `ctx.ui.setStatus(key, text)` sets footer status text — good for "Running task X" updates
|
||||
- `ctx.ui.setStatus(key, undefined)` clears the status
|
||||
- The TUI crash (`child.render is not a function`) happens because `customType: "ralph-progress"` has no registered renderer via `pi.registerMessageRenderer()`
|
||||
@@ -0,0 +1,47 @@
|
||||
# 04. Thread `ExtensionCommandContext` through `executeBatch`
|
||||
|
||||
meta:
|
||||
id: ralph-loop-fixes-04
|
||||
feature: ralph-loop-fixes
|
||||
priority: P1
|
||||
depends_on: []
|
||||
tags: [implementation, plumbing]
|
||||
|
||||
objective:
|
||||
- Pass `ctx: ExtensionCommandContext` from command handlers through to all executor functions that need it, replacing the missing `piApi: ExtensionAPI` parameter
|
||||
|
||||
deliverables:
|
||||
- Modified `index.ts` — all `executeBatch()` calls pass `ctx` as 6th parameter
|
||||
- Modified `src/executor.ts` — `executeBatch()`, `executeTask()`, `runTask()`, `executeBatchParallel()` accept `ctx: ExtensionCommandContext`
|
||||
|
||||
steps:
|
||||
- Open `src/executor.ts`
|
||||
- Add `import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent"`
|
||||
- Update `executeBatch()` signature: add `ctx: ExtensionCommandContext` as 6th parameter (after `progress`)
|
||||
- Update `executeTask()` signature: add `ctx: ExtensionCommandContext` parameter
|
||||
- Update `runTask()` signature: add `ctx: ExtensionCommandContext` parameter
|
||||
- Update `executeBatchParallel()` signature: add `ctx: ExtensionCommandContext` parameter
|
||||
- Thread `ctx` through all internal calls (batch → task → run)
|
||||
- Open `index.ts`
|
||||
- In `handleRun()`: pass `ctx` to `executeBatch()`
|
||||
- In `handleResume()`: pass `ctx` to `executeBatch()`
|
||||
- In `handleNext()`: pass `ctx` to `executeBatch()`
|
||||
|
||||
tests:
|
||||
- Manual: `/ralph run` should execute without "undefined is not a function" errors
|
||||
- Manual: `/ralph resume` should execute without context-related errors
|
||||
|
||||
acceptance_criteria:
|
||||
- `executeBatch()` receives a valid `ExtensionCommandContext` in all call paths
|
||||
- No `undefined` access errors when executor calls `ctx.ui.*`
|
||||
- TypeScript compiles without errors
|
||||
|
||||
validation:
|
||||
- Run `npx tsc --noEmit` in extension directory
|
||||
- Verify `ctx` parameter exists in all executor function signatures
|
||||
- Verify all call sites in index.ts pass `ctx`
|
||||
|
||||
notes:
|
||||
- `ExtensionCommandContext` extends `ExtensionContext` and adds session control methods
|
||||
- Command handlers receive `ExtensionCommandContext`, not bare `ExtensionContext`
|
||||
- The `piApi` parameter was `ExtensionAPI` which has `sendMessage()` — we're replacing it with `ctx` which has `ctx.ui` for UI access
|
||||
39
tasks/ralph-loop-fixes/05-fix-sequential-mode-labels.md
Normal file
39
tasks/ralph-loop-fixes/05-fix-sequential-mode-labels.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# 05. Fix sequential mode batch labels
|
||||
|
||||
meta:
|
||||
id: ralph-loop-fixes-05
|
||||
feature: ralph-loop-fixes
|
||||
priority: P2
|
||||
depends_on: [ralph-loop-fixes-04]
|
||||
tags: [implementation, ui]
|
||||
|
||||
objective:
|
||||
- Suppress "Batch N:" label for single-task batches; use numbered list format (1., 2., 3.) for sequential task execution to match original behavior
|
||||
|
||||
deliverables:
|
||||
- Modified `src/executor.ts` — `executeBatch()` console output
|
||||
|
||||
steps:
|
||||
- Open `src/executor.ts` and locate `executeBatch()`
|
||||
- In the batch header log, check if `tasks.length === 1`
|
||||
- If single task: log `[ralph] Running task ${task.id}: ${task.title}` (no "Batch N" wrapper)
|
||||
- If multiple tasks: keep existing `=== Batch N (M tasks) ===` format
|
||||
- Track global task counter for sequential numbered output if needed
|
||||
|
||||
tests:
|
||||
- Manual: Run a single-task batch — verify no "Batch N" in output
|
||||
- Manual: Run a multi-task batch — verify "Batch N" still appears
|
||||
|
||||
acceptance_criteria:
|
||||
- Single-task batches do not show "Batch N:" prefix
|
||||
- Multi-task batches still show batch header
|
||||
- Output format matches original: `[ralph] Running task 001: Title`
|
||||
|
||||
validation:
|
||||
- Check `console.log` output in executeBatch for conditional formatting
|
||||
- Verify single-task path uses task-focused label
|
||||
|
||||
notes:
|
||||
- Original behavior: single tasks show numbered list (1., 2., 3.), batches show "Batch N:"
|
||||
- Current code always shows `[ralph] === Batch N (M tasks) ===` regardless of batch size
|
||||
- This is cosmetic but matches user preference for compact UI
|
||||
40
tasks/ralph-loop-fixes/06-simplify-parsertoolsusage.md
Normal file
40
tasks/ralph-loop-fixes/06-simplify-parsertoolsusage.md
Normal file
@@ -0,0 +1,40 @@
|
||||
# 06. Simplify `parseToolUsage` for plain text output
|
||||
|
||||
meta:
|
||||
id: ralph-loop-fixes-06
|
||||
feature: ralph-loop-fixes
|
||||
priority: P2
|
||||
depends_on: [ralph-loop-fixes-02]
|
||||
tags: [implementation, utils]
|
||||
|
||||
objective:
|
||||
- Remove NDJSON event parsing from `parseToolUsage()` since `pi --print` returns plain text, not structured event streams
|
||||
|
||||
deliverables:
|
||||
- Modified `src/utils.ts` — `parseToolUsage()` function
|
||||
|
||||
steps:
|
||||
- Open `src/utils.ts` and locate `parseToolUsage()`
|
||||
- Remove the NDJSON parsing block (lines that check `line.startsWith("data: ")` and `JSON.parse`)
|
||||
- Keep only the regex fallback that counts tool mentions in plain text output
|
||||
- Remove `extractTextFromEvent()` if no longer needed (plain text from `--print` needs no extraction)
|
||||
- Update `executor.ts` to call `parseToolUsage()` directly on `result.stdout` without `extractTextFromEvent()`
|
||||
|
||||
tests:
|
||||
- Manual: Run a task that uses multiple tools — verify tool counts are captured from plain text output
|
||||
- Manual: Verify no JSON parse errors in tool usage parsing
|
||||
|
||||
acceptance_criteria:
|
||||
- `parseToolUsage()` works correctly on plain text output
|
||||
- No JSON parsing logic remains in `parseToolUsage()`
|
||||
- Tool counts ([read], [write], [edit], [bash]) are still extracted via regex
|
||||
|
||||
validation:
|
||||
- Grep for `JSON.parse` in parseToolUsage — should be removed
|
||||
- Grep for `data:` prefix check — should be removed
|
||||
- Verify regex-based tool counting still present and functional
|
||||
|
||||
notes:
|
||||
- `pi --print` returns plain text, not NDJSON event stream
|
||||
- The regex fallback patterns (`\[read\]`, `read(`, etc.) are sufficient for counting tool mentions
|
||||
- `extractTextFromEvent()` was only needed for NDJSON — can be removed or simplified to identity function
|
||||
26
tasks/ralph-loop-fixes/README.md
Normal file
26
tasks/ralph-loop-fixes/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Ralph-Loop Extension Fixes
|
||||
|
||||
Objective: Fix critical bugs preventing `/ralph resume` from working — broken CLI flags, unthreaded context, missing config, and TUI crash.
|
||||
|
||||
Status legend: [ ] todo, [~] in-progress, [x] done
|
||||
|
||||
Tasks
|
||||
- [x] 01 — Fix `loadConfig` to return defaults gracefully when `.ralph/config.yaml` is missing → `01-fix-loadconfig-graceful-default.md`
|
||||
- [x] 02 — Replace `spawnPi` with `--print` mode and stdin piping → `02-fix-spawnpi-print-mode.md`
|
||||
- [x] 03 — Replace `sendMessage` with `ctx.ui` progress API → `03-replace-sendmessage-with-ctx-ui.md`
|
||||
- [x] 04 — Thread `ExtensionCommandContext` through `executeBatch` → `04-thread-ctx-through-execute-batch.md`
|
||||
- [x] 05 — Fix sequential mode batch labels → `05-fix-sequential-mode-labels.md`
|
||||
- [x] 06 — Simplify `parseToolUsage` for plain text output → `06-simplify-parsertoolsusage.md`
|
||||
|
||||
Dependencies
|
||||
- 02 depends on nothing (standalone utils fix)
|
||||
- 03 depends on 04 (needs ctx available in executor)
|
||||
- 04 depends on nothing (standalone plumbing fix)
|
||||
- 05 depends on 04 (executor changes)
|
||||
- 06 depends on 02 (output format changes from --print)
|
||||
|
||||
Exit criteria
|
||||
- `/ralph resume` runs without errors in a project with no `.ralph/config.yaml`
|
||||
- Pi subprocess spawns successfully with `--print` mode
|
||||
- Progress messages display via `ctx.ui` without TUI crash
|
||||
- All batch execution paths receive context parameter
|
||||
Reference in New Issue
Block a user