You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Install reflection on Claude Code (/plugin) + OpenCode (plugin section); macOS keychain auth; cheaper CI eval (#142)
* feat: install reflection on Claude Code (/plugin) and OpenCode (plugin section)
Claude Code port (claude/):
- Fix Stop hook contract: event name "Stop" (was "stop"), array hook
format, read last_assistant_message from hook stdin, emit
{decision:"block",reason} to re-prompt; exit 0 to approve.
- Mirror reflection-3.ts PREMATURE-STOP ANTIPATTERNS into judge.mjs
(PERMISSION-SEEKING / STOPPED-WITH-TODOS / FALSE-COMPLETE).
- Auth: ANTHROPIC_API_KEY fallback in addition to OAuth; fail-safe
approve-stop on judge error. Add REFLECTION_CC_FAKE_JUDGE test hook.
- Add root .claude-plugin/marketplace.json (source ./claude) so
`/plugin marketplace add dzianisv/opencode-plugins` + `/plugin install
reflection-cc` work. Un-ignore .claude-plugin/ in .gitignore.
OpenCode plugin-section install (packages/reflection/):
- Publishable npm package `opencode-reflection` mirroring the auto-review
packaging pattern: index.ts re-export, prepack/postpack symlink swap,
files allowlist. Add to opencode.json "plugin": ["opencode-reflection"]
(or a local path) instead of the copy script.
- README: document both install paths.
Verified: typecheck clean, claude e2e 2/2 (3 need live API creds),
npm pack --dry-run = 3 files / 20.8kB, plugin-load test unaffected.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
* fix(claude): read OAuth credentials from macOS keychain
On macOS, Claude Code stores credentials in the login keychain (generic
password "Claude Code-credentials"), not ~/.claude/.credentials.json. The
judge's OAuth path only read the file, so the in-hook judge could never
authenticate on a Mac and silently fell back to no-inject — i.e. the
plugin did nothing for most Mac users.
loadAuth() now falls back to `security find-generic-password -s
"Claude Code-credentials" -w` on darwin. Verified end-to-end: a real
classifyStop() call authenticates via the keychain token and returns a
verdict from the live Anthropic API.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
* docs: map reflection plugin to Reflexion (Weng 2023) taxonomy
Document that the plugin is a Reflexion-style actor/evaluator/verbal-self-
reflection loop (not ReAct/CoH/AD), with a one-to-one mapping: the loop
heuristics (PLANNING_LOOP, ACTION_LOOP) mirror Reflexion's inefficient/
hallucinated-trajectory detectors and MAX_ATTEMPTS=3 mirrors its bounded
reflection memory. Notes where it differs (fires on stop/idle to catch
premature stops; LLM-as-judge rubric mined from 227 real stops).
Co-Authored-By: Claude Opus 4.8 <[email protected]>
* perf(evals): run judge suite on gpt-5.4-nano with a pass-rate threshold
Cut CI judge-eval cost ~25x by switching the provider from gpt-5.1 to the
cheapest deployed dev-endpoint model, gpt-5.4-nano. Benchmarked all 34
cases: gpt-5.1 34/34, gpt-5.4 / gpt-5.4-mini / gpt-5.4-nano all 33/34 —
the single miss is calibration variance on one borderline case shared by
the whole 5.4 family, not a premature-stop-logic failure.
run-promptfoo.mjs now honors EVAL_PASS_THRESHOLD: when set, a run that
promptfoo failed is re-checked against the suite pass rate (only ever
relaxes a fail, never reddens a pass; falls back to native exit on any
parse error) and prints the tolerated cases. CI judge step sets 0.97
(tolerate <=1 of 34); a 2nd failure turns CI red. gpt-5.1 remains a
one-line swap for full fidelity. Production judge still blocks small
models via JUDGE_BLOCKED_PATTERNS — this is CI-eval only.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
---------
Co-authored-by: engineer <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
"description": "Re-prompts Claude Code when it stops prematurely — catches PERMISSION-SEEKING, STOPPED-WITH-TODOS, and FALSE-COMPLETE failure modes (78% of real agent stops are premature), and injects targeted recovery instructions via the Stop hook.",
OpenCode resolves the entry point from `package.json``exports`, imports the default export (a `Plugin` function), and calls it automatically at startup. No manual file copying or `bun install` required — OpenCode handles dependency installation.
81
+
82
+
Restart OpenCode after editing `opencode.json` to activate.
5.**Continuation**: Agent receives feedback and continues working
157
183
184
+
### Relation to Reflexion (Weng 2023 / Shinn et al. 2023)
185
+
186
+
This plugin is, in the taxonomy of Lilian Weng's [*LLM Powered Autonomous Agents*](https://lilianweng.github.io/posts/2023-06-23-agent/),
187
+
a **Reflexion**-style self-improvement loop — not ReAct, Chain-of-Hindsight, or
188
+
Algorithm Distillation. The mapping is almost one-to-one:
189
+
190
+
| Reflexion concept (Weng / Shinn et al.) | This plugin |
191
+
| --- | --- |
192
+
|**Actor** — the policy LLM that acts | The coding agent (OpenCode / Claude Code) itself |
193
+
|**Evaluator** — scores the trajectory | The LLM-as-judge self-assessment (`buildSelfAssessmentPrompt` / `classifyStop`), run in an unbiased hidden session |
194
+
|**Self-reflection** — verbal feedback added to memory for the next attempt | The feedback string injected back into the chat / the Stop-hook `block` reason — natural-language, not a scalar reward |
195
+
|**Heuristic: "inefficient" trajectory (too long without success)**|`PLANNING_LOOP` detector — many tool calls with a near-zero write ratio (`PLANNING_LOOP_MIN_TOOL_CALLS`, `PLANNING_LOOP_WRITE_RATIO_THRESHOLD`) |
"description": "Re-prompts Claude Code when it stops prematurely due to failure modes like summary-drift-stop or tool-available-punt",
5
-
"author": "dzianisv",
5
+
"description": "Re-prompts Claude Code when it stops prematurely — catches PERMISSION-SEEKING, STOPPED-WITH-TODOS, and FALSE-COMPLETE failure modes, and injects targeted recovery instructions.",
Add the Stop hook directly to `~/.claude/settings.json`:
8
29
9
30
```json
10
31
{
@@ -24,9 +45,9 @@ Re-prompts Claude Code when it stops prematurely due to failure modes like summa
24
45
}
25
46
```
26
47
27
-
The plugin manifest under `.claude-plugin/` is included for future marketplace publication, but in CC v2.1.150`--plugin-dir` and the `enabledPlugins` config path do NOT activate `Stop` hooks for headless `-p` sessions. The settings-based install above is the authoritative path until that gap closes.
48
+
**One-session try:** write the JSON above to a file and pass`--settings ./reflect-settings.json`.
28
49
29
-
**One-session try:**`claude --settings '<json above>'` ... or write the JSON to a file and pass `--settings ./reflect-settings.json`.
50
+
> Note: the Stop hook event name is `"Stop"` (capital S) — lowercase `"stop"` is silently ignored by Claude Code.
0 commit comments