5 Commits

Author SHA1 Message Date
sfishman
028eccf544 address review: bound grep to tail -n 100; restore explicit error paths
- Split pipeline into two steps (extract lines, then parse) mirroring the
  original structure.
- set +e around the jq call so failures reach the $? check instead of
  aborting under set -e.
- The "no text content" branch remains removed (that was the original bug —
  all-tool-use turns now correctly yield empty text and the loop continues).
2026-03-04 00:25:42 +00:00
sfishman
8644df9ad5 fix(ralph-loop): isolate loop state to the session that started it
The state file lives at .claude/ralph-loop.local.md — project-scoped,
not session-scoped. The plugin's Stop hook fires in every Claude Code
session open in that project directory. So if session A starts a loop,
session B's Stop events also find the state file and block, feeding A's
prompt into B and consuming A's iteration budget.

This was masked by the transcript-parsing bug fixed in the previous
commit: that bug deleted the state file on the first Stop in any
session, so neither session looped. Fixing it exposed the leak.

Fix: setup writes CLAUDE_CODE_SESSION_ID into the frontmatter; the hook
compares against .session_id from its stdin JSON and exits silently on
mismatch. State files without session_id (written by old setup scripts)
fall through to preserve existing behavior.
2026-03-02 22:52:00 +00:00
sfishman
adfc379663 fix(ralph-loop): stop hook fails when last assistant block is tool_use
Claude Code writes each assistant content block (text/tool_use/thinking)
as its own JSONL line. The hook's `grep role:assistant | tail -1` would
grab whichever block happened to be last — often tool_use — then jq's
text filter returned empty string, triggering the 'no text content' path
which deletes the state file and exits without blocking.

Net effect: the loop silently never fires. In one observed session, 62%
of assistant lines were tool_use-only; the hook deleted state on the
very first Stop event every time.

Fix: slurp all assistant lines with jq -rs, flatten to text blocks only,
take the last. Empty result is now non-fatal — no text means no <promise>
tag, so the loop continues. Also absorbs jq parse errors (control chars
in text) via || fallback instead of aborting under set -e.
2026-03-02 20:39:50 +00:00
Claude
aecd4c852f Add Apache 2.0 LICENSE files to all internal plugins
- Added Apache 2.0 license to the root of each plugin directory
- Ensures compliance with open-source licensing requirements
2026-02-20 01:06:49 +00:00
Noah Zweben
44328beed4 Rename ralph-wiggum plugin to ralph-loop per legal guidance (#142)
- Rename plugin from "ralph-wiggum" to "ralph-loop" to avoid trademark concerns
- Update all internal references to use "Ralph Loop" as the prominent name
- Keep explanatory text noting it "implements the Ralph Wiggum technique" (allowed)
- Rename plugin directory from plugins/ralph-wiggum to plugins/ralph-loop
- Update marketplace.json with new plugin name and source path
- Update plugin-dev documentation references

This change follows legal's recommendation to replace "Wiggum" with "Loop"
in the plugin name while still explaining the technique origin.

Slack thread: https://anthropic.slack.com/archives/C09KU300P7F/p1767741142753959

Co-authored-by: Claude <noreply@anthropic.com>
2026-01-06 15:22:54 -08:00