cc-haha 64691f7672 fix(plugin): reverse-engineering 0.4.0 -> 0.4.2 review fixes
Self-review of v0.4.0 surfaced three real bugs (would have produced
incorrect output to the user / LLM) plus a handful of consistency
gaps. None of these block enabling the plugin or break the smoke,
but together they erode trust in what the plugin tells the user.

Real bugs fixed
---------------

1. commands/triage.md and commands/report.md used a bash-style
   `${user_config.ARTIFACT_DIR:-artifacts/re-runs}` default-fallback.
   The substitute regex in src/utils/plugins/pluginOptionsStorage.ts
   is a plain `\$\{user_config\.([^}]+)\}` capture -- it would have
   keyed off the literal string `ARTIFACT_DIR:-artifacts/re-runs`,
   missed it, and returned the unsubstituted match, leaking the
   `:-default` syntax into the LLM prompt. Worse, manifest defaults
   (plugin.json `userConfig.ARTIFACT_DIR.default`) are NOT auto-merged
   into runtime options -- `loadPluginOptions` only reads
   settings.json + secureStorage. So the only way `${user_config.X}`
   resolves at all is if the user explicitly set it in the UI; for
   plugin authors who want a sensible fallback, the variable form
   isn't actually useful here. Switched both commands to a prose
   directive ("use ARTIFACT_DIR setting if present; otherwise default
   to artifacts/re-runs") that the LLM can resolve from context. This
   matches how the SKILL.md files already wrote the same idea.

2. agents/reverse-engineer.md "When you do NOT have the right MCP
   server available" still told the agent to point users at the
   `userConfig` toggle for each MCP. Those toggles
   (ENABLE_GHIDRA / ENABLE_RADARE2 / ENABLE_JADX / ENABLE_APKTOOL /
   ENABLE_FRIDA) were removed in the v0.4.0 cleanup -- they never
   actually controlled MCP loading, only made the userConfig dialog
   look more important than it was. The fix points users at
   Settings -> MCP for runtime enable/disable and at the README's
   prerequisites table for install instructions, both of which are
   the actual sources of truth post-cleanup.

3. agents/reverse-engineer.md description listed binwalk as a
   first-class tool in the toolchain bullet. binwalk is not bundled
   as an MCP -- skills/firmware-blob shells out to the binwalk CLI
   directly through Bash. Dropped from the description so the LLM
   doesn't hallucinate a binwalk MCP server when none exists.

Consistency gaps fixed
----------------------

4. README.md opening summary still claimed "five MCP servers ...
   six skills"; reality is seven MCP servers and eleven skills since
   v0.3.0/v0.4.0. The capability tables further down were correct,
   only the lead paragraph was stale. Replaced with a less number-
   coupled summary.

5. README install snippet hard-coded `C:\Users\70641\cc-haha\plugins`
   in three places. Replaced with `(Resolve-Path .\plugins).Path` so
   any contributor's checkout works without editing -- and noted
   `<repo-root>` semantics in prose for non-Windows readers.

6. README References section didn't list the new GDB and LLDB MCPs
   added in v0.4.0. Added entries for signal-slot/mcp-gdb and
   stass/lldb-mcp.

7. Added a README section "LLDB MCP -- fallback if uvx fetch fails"
   covering the upstream-packaging gap in stass/lldb-mcp (it ships
   as a single .py without an installable entry point, so
   `uvx --from git+...` may report `python: can't open file
   'lldb_mcp.py'` on first start). The fallback recipe (clone +
   absolute python3 path) is now in the README rather than something
   each user has to rediscover.

8. plugin.json keywords were narrower than marketplace.json tags:
   keywords had 7 entries, tags had 16. Brought keywords up to the
   12 most useful for plugin discovery (firmware, embedded, debugger,
   single-step, ghidra, radare2, frida, gdb, lldb).

9. skills/triage Step 3 routing table mapped "Live process /
   instrumented session" directly to frida-dynamic. The agent's
   Stage 3 says to read dynamic-debug-overview FIRST and let it pick
   between Frida / GDB / LLDB. Updated triage to match -- now any
   runtime question routes to dynamic-debug-overview, which then
   picks the right lane.

10. agent description had "iOS -> r2 + optionally class-dump", but
    skills/ios-analysis actually keeps Ghidra (with the iOS loader)
    in scope as well. Updated agent to "r2 (preferred, via the
    radare2 MCP) or Ghidra with the iOS loader" so the LLM knows
    Ghidra is also a path on iOS.

Manifest version bump 0.4.0 -> 0.4.2 (two patch bumps because the
first fix pass missed the loadPluginOptions semantics; bumping again
re-materialised the cache after the corrected commands content was
written).

Verification
------------

  bun run plugins/reverse-engineering/scripts/validate.ts
    -> 0 fail / 0 warn (marketplace + plugin schema both clean)

  bun run plugins/reverse-engineering/scripts/smoke.ts
    -> 13 passed / 0 failed
       version=0.4.2, commands=2, agents=1, skills=11, mcpServers=7,
       skill ids match the on-disk glob

  Cache materialised at
  ~/.claude/plugins/cache/cc-haha-builtin/reverse-engineering/0.4.2/
  carries the corrected commands without the bash-style
  default-fallback.

Confidence: high
Scope-risk: narrow (plugin-only patch; no source code touched, no
breaking change to existing skill names or component counts).
Tested: validate (pass), smoke (13/13 pass), cache content spot-check
of commands/report.md.
Not-tested: live `/reverse-engineering:triage` against a real sample
end-to-end; the substitution change is text-only and the runtime
loader was unaffected.
2026-06-11 01:48:36 +08:00
..