feat(claw-code): add Claw Code platform support to installer#208
Conversation
|
Warning Rate limit exceeded
To keep reviews running without waiting, you can enable usage-based add-on for your organization. This allows additional reviews beyond the hourly cap. Account admins can enable it under billing. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (28)
📝 WalkthroughWalkthroughAdds a new Claw Code plugin, "evolve-lite", implementing local entity storage, learn/recall/save/publish/subscribe/sync/unsubscribe skills, repo/config/audit utilities, hook-driven entity retrieval, and platform installer wiring for Claw plugin lifecycle management. Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Claw as Claw (Host)
participant Hook as retrieve_entities.sh
participant Retriever as retrieve_entities.py
participant Entities as .evolve/entities/
participant Claude as Claude (LLM)
User->>Claw: Submit prompt / trigger tool
Claw->>Hook: run PreToolUse hook
Hook->>Retriever: pipe HOOK_TOOL_INPUT
Retriever->>Entities: load_all_entities()
Entities-->>Retriever: markdown entities
Retriever->>Claw: formatted entity markdown
Claw->>Claude: inject entities as context
Claude->>Claude: select/filter entities → decide tool call
sequenceDiagram
actor User
participant Learn as learn SKILL
participant Saver as save_entities.py
participant Entities as .evolve/entities/
participant FS as File system
User->>Learn: Provide conversation
Learn->>Saver: pipe entities JSON
Saver->>Entities: load_all_entities()
Entities-->>Saver: existing normalized contents
Saver->>Saver: deduplicate incoming entities
Saver->>FS: write_entity_file() atomic write (.tmp -> O_EXCL -> replace)
FS-->>Saver: file written
Saver-->>User: summary (added count, path)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 12
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
platform-integrations/install.sh (1)
3-7:⚠️ Potential issue | 🟡 MinorDocstring/usage still lists only Bob, Claude Code, and Codex — add Claw Code.
The header comment block and the
argparsedescription at line 1054 both advertise support for only Bob/Claude/Codex, but--platformnow also acceptsclaw-codeand thealllist includes it. Low-impact but trivial and user-facing.📝 Suggested doc sync
-# Installs Evolve Lite (and optionally Full) integrations for Bob, Claude Code, and Codex. +# Installs Evolve Lite (and optionally Full) integrations for Bob, Claude Code, Claw Code, and Codex. # # Usage: -# ./install.sh install [--platform bob|claude|codex|all] [--mode lite|full] [--dir DIR] [--dry-run] -# ./install.sh uninstall [--platform bob|claude|codex|all] [--dir DIR] [--dry-run] +# ./install.sh install [--platform bob|claude|claw-code|codex|all] [--mode lite|full] [--dir DIR] [--dry-run] +# ./install.sh uninstall [--platform bob|claude|claw-code|codex|all] [--dir DIR] [--dry-run] # ./install.sh status [--dir DIR]And at line 1054:
- description="Install Evolve integrations for Bob, Claude Code, and Codex.", + description="Install Evolve integrations for Bob, Claude Code, Claw Code, and Codex.",🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@platform-integrations/install.sh` around lines 3 - 7, Update the usage header and the argparse/platform description to include "Claw Code" (and the CLI token "claw-code") so documentation matches the implemented options; specifically edit the top comment block that lists supported platforms and the argparse help string (the description around the --platform/options parsing) to mention Claw Code and ensure the "all" list text includes claw-code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In
`@platform-integrations/claw-code/plugins/evolve-lite/hooks/retrieve_entities.sh`:
- Around line 2-11: The header comments in retrieve_entities.sh currently imply
an active PreToolUse hook (referencing HOOK_EVENT, HOOK_TOOL_NAME,
HOOK_TOOL_INPUT and saying "PreToolUse hook: retrieve relevant entities before
each tool execution"), but the manifest/README show hooks are not registered;
either register this hook in the manifest or update the comments to clarify this
is optional/manual and not automatically invoked—edit the retrieve_entities.sh
header to state that these environment variables are provided only if the
PreToolUse hook is registered (or remove the "fires before every tool call"
wording) so readers aren't misled about automatic injection.
In `@platform-integrations/claw-code/plugins/evolve-lite/lib/entity_io.py`:
- Around line 258-285: The exception handler can reference an uninitialized
local variable target and raise UnboundLocalError, masking the original error;
initialize target to None before the try block (near where tempfile.mkstemp is
called) so that the except BaseException: cleanup logic (checks on target,
os.unlink of tmp_path, and removal of a 0-byte placeholder) can safely run; keep
the existing loop that assigns target via unique_filename(...) and atomic rename
via os.replace(...) but ensure target is defined as None prior to entering the
try to avoid the unbound reference.
In `@platform-integrations/claw-code/plugins/evolve-lite/README.md`:
- Around line 145-169: Update the documented plugin tree in README.md to include
the missing hooks/ directory and its script(s); specifically add a hooks/ entry
under evolve-lite/ (e.g., hooks/retrieve_entities.sh) so the printed structure
in the Plugin Structure section matches the actual package contents and
references the bundled hook script(s).
In
`@platform-integrations/claw-code/plugins/evolve-lite/skills/learn/scripts/save_entities.py`:
- Around line 41-45: The code reads new_entities = input_data.get("entities",
[]) and only checks truthiness, which allows non-list types (e.g., dict) to slip
through and later break iteration; update the validation to ensure new_entities
is a list (use isinstance(new_entities, list)), and if not, log a descriptive
error via log(...) and print to stderr then exit (same pattern used currently)
so only a list proceeds to the loop that processes entities; refer to the
new_entities variable and the existing log/print/sys.exit calls to implement
this check.
- Around line 8-16: The import fails because lib/ is not on Python's import path
when the script runs from .claw/skills/evolve-lite/; modify the top of
save_entities.py to insert the project's lib directory into sys.path before
importing entity_io so that the module and its functions (find_entities_dir,
get_default_entities_dir, load_all_entities, write_entity_file, log/_log) can be
resolved; specifically, compute the lib path relative to the script (e.g., using
__file__ and os.path) and add it to sys.path prior to the existing from
entity_io import ... line.
In
`@platform-integrations/claw-code/plugins/evolve-lite/skills/recall/scripts/retrieve_entities.py`:
- Around line 28-35: The current hook env-var logging loop (uses log, hook_keys,
and os.environ) prints full values which can leak sensitive data such as
HOOK_TOOL_INPUT; change it to only log keys and either a redacted placeholder or
safe metadata (e.g., "<redacted>" or value length/type) for sensitive names
(specifically HOOK_TOOL_INPUT and any keys containing "TOOL_INPUT", "SECRET",
"PASSWORD", or "KEY"); keep non-sensitive keys readable if desired but avoid
printing full content for any key that matches those patterns or a configurable
sensitive set.
- Around line 16-20: The import of entity_io fails when the script is executed
directly because lib/ isn't on sys.path; update the top of the module so that
before importing entity_io you compute the plugin root (e.g., from the script's
__file__ parent directories), prepend the plugin's lib directory to sys.path,
then import entity_io and its symbols (find_entities_dir, load_all_entities,
log). Ensure this change is placed above the existing import line so functions
like find_entities_dir/load_all_entities and any uses in main() can be resolved
at runtime.
In `@platform-integrations/claw-code/plugins/evolve-lite/skills/recall/SKILL.md`:
- Around line 3-19: The docs claim recall runs automatically via hooks and reads
a JSON prompt from stdin, which conflicts with the current Claw integration
being manual; update the "Entity Retrieval" section (and the numbered steps
under "How It Works") to either (A) state that recall is manually invoked and
describe the manual invocation flow and expected stdin/json format, or (B) add
the missing hook registration details including the hook name, where to register
it, and the behavior of the recall script (reading a JSON payload with a
`prompt` field from stdin, loading entities from `.evolve/entities/`, and
writing formatted entities to stdout) so the documentation and the actual
implementation (references: the "Entity Retrieval" section title and the
numbered steps 1–5) are consistent.
In
`@platform-integrations/claw-code/plugins/evolve-lite/skills/save-trajectory/scripts/save_trajectory.py`:
- Around line 58-73: The generate_filename function currently races by checking
candidate.exists() then creating the file later; change it to atomically claim a
filename by attempting to create the file with os.open(..., os.O_CREAT |
os.O_EXCL | os.O_WRONLY) inside the initial check and inside the suffix loop (in
generate_filename and the similar block around lines 110-118), closing the
returned fd and returning the Path on success; if os.open raises
FileExistsError, continue to the next suffix, and only raise RuntimeError after
exhausting suffixes. Ensure os is imported and use the same base_name/candidate
logic but replace exists() checks with atomic os.open attempts.
- Around line 102-107: The current validation only checks truthiness of messages
from trajectory.get("messages") so non-list types like a non-empty string or
object can pass; change the check to ensure messages is an instance of list and
has length > 0 (e.g., validate with isinstance(messages, list) and len(messages)
> 0) before proceeding, and if that fails use the existing log/print/exit
behavior; update references to the messages variable and the
trajectory.get("messages", []) usage in save_trajectory.py to perform this
stricter validation.
- Around line 46-55: The get_trajectories_dir function ignores the EVOLVE_DIR
env var; update it to prefer EVOLVE_DIR (if set and non-empty) as the base
directory, falling back to CLAUDE_PROJECT_ROOT (when present) and then to the
existing default (./.evolve/trajectories); ensure you construct the Path from
EVOLVE_DIR and append "trajectories" when appropriate, call
base.mkdir(parents=True, exist_ok=True, mode=0o700) and return base.resolve() as
before.
In
`@platform-integrations/claw-code/plugins/evolve-lite/skills/save-trajectory/SKILL.md`:
- Around line 110-134: Remove the duplicated "### Step 5: Save via Helper
Script" block that contains the hardcoded $HOME one-liner; keep the second, more
robust snippet that computes real_home via pwd.getpwuid(...) and honors
CLAW_CONFIG_HOME (the version that sets real_home, config_home, script, and runs
python3 "$script" "$tmp"). Delete the earlier duplicate heading, its hardcoded
one-liner (the snippet using script="$HOME/.claw/..."), and the repeated
"Important" paragraph so only a single Step 5 with the CLAW_CONFIG_HOME-aware
invocation remains; ensure the tmp and script variables and the trap line are
preserved from the kept snippet.
---
Outside diff comments:
In `@platform-integrations/install.sh`:
- Around line 3-7: Update the usage header and the argparse/platform description
to include "Claw Code" (and the CLI token "claw-code") so documentation matches
the implemented options; specifically edit the top comment block that lists
supported platforms and the argparse help string (the description around the
--platform/options parsing) to mention Claw Code and ensure the "all" list text
includes claw-code.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6e0cf944-dbac-44fe-8b32-714342dad7a1
📒 Files selected for processing (13)
platform-integrations/claw-code/plugins/evolve-lite/.claude-plugin/plugin.jsonplatform-integrations/claw-code/plugins/evolve-lite/README.mdplatform-integrations/claw-code/plugins/evolve-lite/hooks/retrieve_entities.shplatform-integrations/claw-code/plugins/evolve-lite/lib/__init__.pyplatform-integrations/claw-code/plugins/evolve-lite/lib/entity_io.pyplatform-integrations/claw-code/plugins/evolve-lite/skills/learn/SKILL.mdplatform-integrations/claw-code/plugins/evolve-lite/skills/learn/scripts/save_entities.pyplatform-integrations/claw-code/plugins/evolve-lite/skills/recall/SKILL.mdplatform-integrations/claw-code/plugins/evolve-lite/skills/recall/scripts/retrieve_entities.pyplatform-integrations/claw-code/plugins/evolve-lite/skills/save-trajectory/SKILL.mdplatform-integrations/claw-code/plugins/evolve-lite/skills/save-trajectory/scripts/save_trajectory.pyplatform-integrations/claw-code/plugins/evolve-lite/skills/save/SKILL.mdplatform-integrations/install.sh
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Bring claw-code's evolve-lite plugin up to parity with claude's after
rebase: port post-rebase updates to learn/recall/save/save-trajectory,
add the publish/subscribe/sync/unsubscribe sharing skills, and sync
shared lib/ (audit.py, config.py, entity_io.py). SKILL.md command
examples are adapted to claw's sh -lc path-resolution pattern instead
of \${CLAUDE_PLUGIN_ROOT}.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
da91792 to
c9e4649
Compare
- claw-code retrieve_entities.sh: clarify the PreToolUse hook is optional and not auto-registered by the packaged plugin - entity_io.write_entity_file: initialize target=None so the except handler can't raise UnboundLocalError (claude + claw-code) - save_entities.py: reject malformed payloads where `entities` is not a list (claude + claw-code + codex + bob) - claw-code recall retrieve_entities.py: redact HOOK_*/CLAWD_* env values (HOOK_TOOL_INPUT may carry prompts/secrets); only HOOK_EVENT and HOOK_TOOL_NAME remain logged verbatim - save_trajectory.py: prefer EVOLVE_DIR over CLAUDE_PROJECT_ROOT (matches the documented contract); claim trajectory filenames atomically with O_CREAT|O_EXCL to survive same-second races; require `messages` to be a non-empty list instead of accepting any truthy value (claude + claw-code) - claw-code save-trajectory/SKILL.md: drop the duplicate Step 5 block — keep only the CLAW_CONFIG_HOME-aware variant Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 9
♻️ Duplicate comments (5)
platform-integrations/claw-code/plugins/evolve-lite/hooks/retrieve_entities.sh (1)
2-11:⚠️ Potential issue | 🟡 MinorMark this as optional unless the hook is registered.
The header still says this runs before every tool call and injects context automatically, but the current Claw packaging says hooks are not enabled by default. Reword this as an optional PreToolUse hook or register it explicitly.
📝 Suggested wording
-# PreToolUse hook: retrieve relevant entities before each tool execution. +# Optional PreToolUse hook: retrieve relevant entities before tool execution. # -# In claw-code, PreToolUse is the closest equivalent to Claude Code's -# UserPromptSubmit hook. It fires before every tool call, injecting stored -# guidelines and preferences from the evolve-lite entity store into context. +# If registered by a Claw hook configuration, this script can retrieve stored +# guidelines and preferences from the evolve-lite entity store before tool calls.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@platform-integrations/claw-code/plugins/evolve-lite/hooks/retrieve_entities.sh` around lines 2 - 11, The header in retrieve_entities.sh incorrectly claims the script runs before every tool call by default; update the top-of-file documentation (the comments referencing PreToolUse and the Claw-code hook environment variables HOOK_EVENT, HOOK_TOOL_NAME, HOOK_TOOL_INPUT) to state this is an optional PreToolUse hook that only runs if the hook is registered (or add instructions to register it explicitly), and adjust wording to remove the assertion that it injects context automatically on every tool call unless hooks are enabled.platform-integrations/claw-code/plugins/evolve-lite/skills/recall/SKILL.md (1)
3-21:⚠️ Potential issue | 🟡 MinorAlign the recall docs with the manual Claw flow.
This still describes automatic hook-driven injection, but the packaged Claw flow is manual. Either document the registration point or rephrase the workflow as user-invoked recall.
📝 Suggested wording
-description: Retrieves relevant entities from a knowledge base. Designed to be invoked automatically via hooks to inject context-appropriate entities before task execution. +description: Retrieves relevant entities from a knowledge base for manual review before or during task execution. @@ -1. The PreToolUse hook fires before each tool call -2. Script reads tool input from stdin (best-effort, ignored beyond logging) +1. If registered, the PreToolUse hook fires before each tool call +2. The script reads tool input from stdin (best-effort, ignored beyond logging)🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@platform-integrations/claw-code/plugins/evolve-lite/skills/recall/SKILL.md` around lines 3 - 21, The docs in SKILL.md describe automatic hook-driven injection (PreToolUse) but the packaged Claw flow is manual; update the README to either (A) document the registration point where the recall skill is wired into the Claw flow (mention the PreToolUse hook and how to register/invoke the skill) or (B) rephrase the "How It Works" steps to state that recall is user-invoked in the packaged flow (change steps 1–5 to reflect manual invocation and when the script should be run), and keep references to the entities path `.evolve/entities/` and the PreToolUse hook so readers can locate the code.platform-integrations/claw-code/plugins/evolve-lite/skills/save-trajectory/SKILL.md (1)
110-134:⚠️ Potential issue | 🟡 MinorRemove the duplicate Step 5 block.
The first shell snippet hardcodes
$HOME, while the second one is the more robustCLAW_CONFIG_HOME-aware version. Keeping both leaves conflicting instructions and triggers MD024.♻️ Suggested cleanup
-### Step 5: Save via Helper Script - -Write the trajectory JSON to a temporary file using the **Write** tool, then pass the file path to the helper script: - -1. Write the JSON to `.evolve/tmp/trajectory_input.json` using the Write tool (create the directory if needed) -2. Run the helper script with the file path as an argument: - -```bash -tmp=.evolve/tmp/trajectory_input.json; mkdir -p .evolve/tmp; trap 'rm -f "$tmp"' EXIT; script=".claw/skills/evolve-lite:save-trajectory/scripts/save_trajectory.py"; [ -f "$script" ] || script="$HOME/.claw/skills/evolve-lite:save-trajectory/scripts/save_trajectory.py"; python3 "$script" "$tmp" -``` - -**Important**: Do NOT use inline Python scripts, heredocs, or stdin piping to pass the trajectory JSON. Always use the Write tool to create a temp file first. This avoids escaping issues with backslashes, quotes, and newlines in conversation content. - ### Step 5: Save via Helper Script🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@platform-integrations/claw-code/plugins/evolve-lite/skills/save-trajectory/SKILL.md` around lines 110 - 134, Remove the duplicated "Step 5: Save via Helper Script" block and keep only the robust shell snippet that uses real_home and CLAW_CONFIG_HOME (the version with real_home="$(python3 -c "import os,pwd; print(pwd.getpwuid(os.getuid()).pw_dir")" and config_home="${CLAW_CONFIG_HOME:-$real_home/.claw}"). Delete the earlier snippet that hardcodes $HOME and the extra repeated "Important" paragraph so the file contains a single clear Step 5 heading followed by the CLAW_CONFIG_HOME-aware command and the existing warning about using the Write tool.platform-integrations/claw-code/plugins/evolve-lite/lib/entity_io.py (1)
271-296:⚠️ Potential issue | 🔴 CriticalInitialize
targetbeforetryto prevent cleanup-timeUnboundLocalError.If an exception occurs before Line 279 assigns
target, Line 295 can raise a new error and hide the original failure.Suggested fix
# Write to a unique temp file first (avoids predictable .tmp collisions) fd, tmp_path = tempfile.mkstemp(dir=type_dir, suffix=".tmp", prefix=slug) + target = None try: os.write(fd, content.encode("utf-8")) @@ - if target and os.path.exists(str(target)) and os.path.getsize(str(target)) == 0: + if target and os.path.exists(str(target)) and os.path.getsize(str(target)) == 0: os.unlink(str(target))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@platform-integrations/claw-code/plugins/evolve-lite/lib/entity_io.py` around lines 271 - 296, The cleanup path can raise UnboundLocalError because target may not be assigned before the try block; initialize target = None before the try and update the cleanup guard to check "if target is not None and os.path.exists(str(target)) and os.path.getsize(str(target)) == 0:" so the code that deletes the 0-byte placeholder only runs when a target was actually created; keep existing logic around fd, tmp_path, unique_filename(...) and os.replace(...) unchanged.platform-integrations/claw-code/plugins/evolve-lite/skills/recall/scripts/retrieve_entities.py (1)
35-38:⚠️ Potential issue | 🟠 MajorRedact sensitive hook env values from logs.
Line 37 logs full values for all
HOOK_*/CLAWD_*variables; this can expose prompts/tool input/secrets in debug logs.Suggested fix
hook_keys = [k for k in os.environ if k.startswith(("HOOK_", "CLAWD_"))] for key in sorted(hook_keys): - log(f" {key}={os.environ[key]}") + sensitive = ( + key == "HOOK_TOOL_INPUT" + or "TOOL_INPUT" in key + or "SECRET" in key + or "PASSWORD" in key + or key.endswith("_KEY") + ) + if sensitive: + log(f" {key}=<redacted>") + else: + log(f" {key}={os.environ[key]}")🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@platform-integrations/claw-code/plugins/evolve-lite/skills/recall/scripts/retrieve_entities.py` around lines 35 - 38, The loop that logs environment hook values exposes secrets: update the section that builds hook_keys and the for loop over sorted(hook_keys) to redact values before logging (e.g., log only the key with a masked value like "<redacted>" or a safe partial such as first/last N chars), so change the log(f" {key}={os.environ[key]}") usage in this block to a version that does not emit full os.environ[key] contents; keep hook_keys, sorting, and log() calls but pass the sanitized/masked value instead.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@platform-integrations/claw-code/plugins/evolve-lite/lib/config.py`:
- Around line 177-207: The _cast function is unquoting YAML scalar strings then
still coercing them to bool/number/null; detect when the original input was
quoted and in that case avoid further casting: inside _cast record a flag (e.g.,
was_quoted) before you strip quotes (currently done at start), unescape
single-quote behavior as you already do, and if was_quoted simply return the
stripped string (including the special-case of quoted empty string returning
""), otherwise proceed with the existing boolean/null/int/float/list coercion
logic; reference the existing _cast function and its quoted-handling block to
implement this early-return behavior.
- Around line 330-361: The _coerce_repo function currently accepts any non-empty
name string; update it to enforce a safe-name validation (reject names
containing path separators like "/" or "\" or traversal segments like "." or
"..", and allow only a constrained charset such as alphanumerics, underscores,
hyphens, and dots) before returning the repo dict and return None on validation
failure; locate _coerce_repo and add a validation step after name =
entry.get("name") that trims the name, checks the pattern/segments, and rejects
unsafe names (or call an existing helper like safe_name/sanitize_name if
available) so downstream path construction cannot be exploited.
In `@platform-integrations/claw-code/plugins/evolve-lite/README.md`:
- Around line 202-208: The README incorrectly states EVOLVE_DIR overrides both
entity and trajectory storage; update the text to clarify that EVOLVE_DIR only
overrides entity storage and that trajectories are derived from
CLAUDE_PROJECT_ROOT by save_trajectory.py and stored under the project's
.evolve/trajectories (i.e., mention CLAUDE_PROJECT_ROOT and save_trajectory.py
explicitly), so readers know trajectories are not redirected by EVOLVE_DIR.
In
`@platform-integrations/claw-code/plugins/evolve-lite/skills/recall/scripts/retrieve_entities.py`:
- Around line 117-119: The code calls list(input_data.keys()) after
json.loads(raw) without ensuring the parsed JSON is an object; guard this by
checking the parsed value (input_data) is a dict before calling .keys() and log
a safe representation otherwise (e.g., log the type or the value), or wrap the
keys() usage in a conditional/try to avoid AttributeError; update the block
around json.loads(raw), input_data, and the log call to perform an
isinstance(input_data, dict) check and handle non-dict JSON gracefully.
In
`@platform-integrations/claw-code/plugins/evolve-lite/skills/subscribe/scripts/subscribe.py`:
- Around line 95-99: The git clone call using subprocess.run (clone_cmd built
from args.remote, args.branch, args.scope and dest) can hang or raise
CalledProcessError and leave a partial clone; wrap subprocess.run in a
try/except that passes a timeout (e.g., GIT_CLONE_TIMEOUT constant) to
subprocess.run, catch subprocess.TimeoutExpired and
subprocess.CalledProcessError, and on those failures clean up the
partially-created dest directory (use shutil.rmtree if dest exists) before
surfacing a clear CLI-friendly error via logging or a raised exception; ensure
you reference and use the existing clone_cmd, args.branch, args.remote and
args.scope when re-running or reporting the failure.
In
`@platform-integrations/claw-code/plugins/evolve-lite/skills/sync/scripts/sync.py`:
- Around line 44-53: The _head_hash function calls subprocess.run for "git
rev-parse HEAD" but doesn't catch subprocess.TimeoutExpired, so a git timeout
can abort the entire sync; modify _head_hash to wrap the subprocess.run call in
a try/except that catches subprocess.TimeoutExpired (and optionally OSError) and
returns None on timeout/error, mirroring the behavior in _git, and keep using
result.returncode check and result.stdout.strip() when successful to locate and
handle failures safely.
- Around line 140-143: The --config branch passes filepath= to load_config but
load_config expects project_root, causing a TypeError; change the call to pass
the config path as the project_root parameter (e.g., replace
load_config(filepath=args.config) with load_config(project_root=args.config) or
simply load_config(args.config)) so both branches call load_config with the
correct argument (referencing args.config, load_config, and cfg).
In `@platform-integrations/claw-code/plugins/evolve-lite/skills/sync/SKILL.md`:
- Around line 25-31: The two separate blockquote examples—one starting with
"Synced 2 repo(s): memory [write]..." and the next "No subscriptions configured.
Add one with /evolve-lite:subscribe..."—include an extra blank line between them
which triggers MD028; remove that blank line so the quoted examples form a
contiguous block, or alternatively convert both examples into a single fenced
code block to preserve formatting without an empty line.
In
`@platform-integrations/claw-code/plugins/evolve-lite/skills/unsubscribe/scripts/unsubscribe.py`:
- Around line 59-83: The removal logic currently deletes the repo clone
(shutil.rmtree(dest)) as soon as the name matches without checking the repo's
scope; update unsubscribe flow (in unsubscribe.py around the code that builds
new_repos and deletes dest) to detect the matched repo's scope (e.g., inspect
the matched repo dict in repos for a "scope" or "permission" field) and, if it
is write-scope, require explicit confirmation or a --force flag before calling
shutil.rmtree(dest) (prompt the user or check a parsed force boolean), otherwise
skip deletion but still remove the subscription from cfg; ensure set_repos(cfg,
new_repos), save_config(cfg, project_root) and audit_append(...) remain correct
and only run after confirmation/forced deletion decisions.
---
Duplicate comments:
In
`@platform-integrations/claw-code/plugins/evolve-lite/hooks/retrieve_entities.sh`:
- Around line 2-11: The header in retrieve_entities.sh incorrectly claims the
script runs before every tool call by default; update the top-of-file
documentation (the comments referencing PreToolUse and the Claw-code hook
environment variables HOOK_EVENT, HOOK_TOOL_NAME, HOOK_TOOL_INPUT) to state this
is an optional PreToolUse hook that only runs if the hook is registered (or add
instructions to register it explicitly), and adjust wording to remove the
assertion that it injects context automatically on every tool call unless hooks
are enabled.
In `@platform-integrations/claw-code/plugins/evolve-lite/lib/entity_io.py`:
- Around line 271-296: The cleanup path can raise UnboundLocalError because
target may not be assigned before the try block; initialize target = None before
the try and update the cleanup guard to check "if target is not None and
os.path.exists(str(target)) and os.path.getsize(str(target)) == 0:" so the code
that deletes the 0-byte placeholder only runs when a target was actually
created; keep existing logic around fd, tmp_path, unique_filename(...) and
os.replace(...) unchanged.
In
`@platform-integrations/claw-code/plugins/evolve-lite/skills/recall/scripts/retrieve_entities.py`:
- Around line 35-38: The loop that logs environment hook values exposes secrets:
update the section that builds hook_keys and the for loop over sorted(hook_keys)
to redact values before logging (e.g., log only the key with a masked value like
"<redacted>" or a safe partial such as first/last N chars), so change the log(f"
{key}={os.environ[key]}") usage in this block to a version that does not emit
full os.environ[key] contents; keep hook_keys, sorting, and log() calls but pass
the sanitized/masked value instead.
In `@platform-integrations/claw-code/plugins/evolve-lite/skills/recall/SKILL.md`:
- Around line 3-21: The docs in SKILL.md describe automatic hook-driven
injection (PreToolUse) but the packaged Claw flow is manual; update the README
to either (A) document the registration point where the recall skill is wired
into the Claw flow (mention the PreToolUse hook and how to register/invoke the
skill) or (B) rephrase the "How It Works" steps to state that recall is
user-invoked in the packaged flow (change steps 1–5 to reflect manual invocation
and when the script should be run), and keep references to the entities path
`.evolve/entities/` and the PreToolUse hook so readers can locate the code.
In
`@platform-integrations/claw-code/plugins/evolve-lite/skills/save-trajectory/SKILL.md`:
- Around line 110-134: Remove the duplicated "Step 5: Save via Helper Script"
block and keep only the robust shell snippet that uses real_home and
CLAW_CONFIG_HOME (the version with real_home="$(python3 -c "import os,pwd;
print(pwd.getpwuid(os.getuid()).pw_dir")" and
config_home="${CLAW_CONFIG_HOME:-$real_home/.claw}"). Delete the earlier snippet
that hardcodes $HOME and the extra repeated "Important" paragraph so the file
contains a single clear Step 5 heading followed by the CLAW_CONFIG_HOME-aware
command and the existing warning about using the Write tool.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 372a0c68-865b-44df-8fc5-bdbc8f8c0fcf
📒 Files selected for processing (23)
platform-integrations/claw-code/plugins/evolve-lite/.claude-plugin/plugin.jsonplatform-integrations/claw-code/plugins/evolve-lite/README.mdplatform-integrations/claw-code/plugins/evolve-lite/hooks/retrieve_entities.shplatform-integrations/claw-code/plugins/evolve-lite/lib/__init__.pyplatform-integrations/claw-code/plugins/evolve-lite/lib/audit.pyplatform-integrations/claw-code/plugins/evolve-lite/lib/config.pyplatform-integrations/claw-code/plugins/evolve-lite/lib/entity_io.pyplatform-integrations/claw-code/plugins/evolve-lite/skills/learn/SKILL.mdplatform-integrations/claw-code/plugins/evolve-lite/skills/learn/scripts/save_entities.pyplatform-integrations/claw-code/plugins/evolve-lite/skills/publish/SKILL.mdplatform-integrations/claw-code/plugins/evolve-lite/skills/publish/scripts/publish.pyplatform-integrations/claw-code/plugins/evolve-lite/skills/recall/SKILL.mdplatform-integrations/claw-code/plugins/evolve-lite/skills/recall/scripts/retrieve_entities.pyplatform-integrations/claw-code/plugins/evolve-lite/skills/save-trajectory/SKILL.mdplatform-integrations/claw-code/plugins/evolve-lite/skills/save-trajectory/scripts/save_trajectory.pyplatform-integrations/claw-code/plugins/evolve-lite/skills/save/SKILL.mdplatform-integrations/claw-code/plugins/evolve-lite/skills/subscribe/SKILL.mdplatform-integrations/claw-code/plugins/evolve-lite/skills/subscribe/scripts/subscribe.pyplatform-integrations/claw-code/plugins/evolve-lite/skills/sync/SKILL.mdplatform-integrations/claw-code/plugins/evolve-lite/skills/sync/scripts/sync.pyplatform-integrations/claw-code/plugins/evolve-lite/skills/unsubscribe/SKILL.mdplatform-integrations/claw-code/plugins/evolve-lite/skills/unsubscribe/scripts/unsubscribe.pyplatform-integrations/install.sh
✅ Files skipped from review due to trivial changes (6)
- platform-integrations/claw-code/plugins/evolve-lite/.claude-plugin/plugin.json
- platform-integrations/claw-code/plugins/evolve-lite/skills/publish/SKILL.md
- platform-integrations/claw-code/plugins/evolve-lite/skills/subscribe/SKILL.md
- platform-integrations/claw-code/plugins/evolve-lite/skills/learn/SKILL.md
- platform-integrations/claw-code/plugins/evolve-lite/skills/unsubscribe/SKILL.md
- platform-integrations/install.sh
🚧 Files skipped from review as they are similar to previous changes (2)
- platform-integrations/claw-code/plugins/evolve-lite/skills/save-trajectory/scripts/save_trajectory.py
- platform-integrations/claw-code/plugins/evolve-lite/skills/learn/scripts/save_entities.py
| This plugin uses a few simple storage locations: | ||
|
|
||
| - `.evolve/entities/` for saved guidance entities | ||
| - `.evolve/trajectories/` for exported conversation trajectories | ||
| - `.claw/skills/` or `~/.claw/skills/` for installed/generated skills | ||
|
|
||
| If `EVOLVE_DIR` is set, entity and trajectory storage follows that override instead of the default `.evolve/` directory. |
There was a problem hiding this comment.
Clarify that EVOLVE_DIR does not redirect trajectories here.
save_trajectory.py derives .evolve/trajectories from CLAUDE_PROJECT_ROOT, not EVOLVE_DIR. As written, this note suggests both entities and trajectories follow the override, which is inaccurate.
📝 Suggested wording
-If `EVOLVE_DIR` is set, entity and trajectory storage follows that override instead of the default `.evolve/` directory.
+`EVOLVE_DIR` controls entity storage; trajectory export still follows `CLAUDE_PROJECT_ROOT` via the helper script.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@platform-integrations/claw-code/plugins/evolve-lite/README.md` around lines
202 - 208, The README incorrectly states EVOLVE_DIR overrides both entity and
trajectory storage; update the text to clarify that EVOLVE_DIR only overrides
entity storage and that trajectories are derived from CLAUDE_PROJECT_ROOT by
save_trajectory.py and stored under the project's .evolve/trajectories (i.e.,
mention CLAUDE_PROJECT_ROOT and save_trajectory.py explicitly), so readers know
trajectories are not redirected by EVOLVE_DIR.
- config._cast: quoted YAML scalars stay strings — only unquoted scalars coerce to bool/null/int/float/list (claude + claw-code) - config._coerce_repo: reject names that fail is_valid_repo_name so a hand-edited evolve.config.yaml can't smuggle path traversal into downstream clone paths (claude + claw-code) - claw-code recall retrieve_entities.py: guard input_data type before calling .keys(); non-dict JSON no longer aborts recall - subscribe clone: wrap subprocess.run with timeout + capture_output and clean up the partial dest directory on failure (claude + claw-code + codex + bob) - sync._head_hash: route through the existing _git helper so subprocess.TimeoutExpired no longer aborts the whole sync run (claude + claw-code) - sync --config: load_config takes project_root, not filepath — the prior call raised TypeError on every --config usage. Resolve the path to its parent and pass project_root (claude + claw-code + codex) - unsubscribe: add --force; refuse to delete a write-scope clone without it (the clone may hold unpushed publish commits). SKILL.md updated to surface the flag for the agent. (claude + claw-code + codex + bob) - claw-code sync/SKILL.md and claude sync/SKILL.md: collapse the two example blockquotes into one block (markdownlint MD028) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
ClawCodeInstallerclass toinstall.shwithinstall,uninstall, andstatusmethodsclaw-codeindetect_platforms(detects viaclawon PATH or.claw/directory)claw-codetoPLATFORM_CLASSES,--platformCLI choices, andallplatform listsplatform-integrations/claw-code/plugins/evolve-liteplugin directoryKey implementation notes
claw plugins install <path>(local path to the bundled plugin)claw plugins uninstall evolve-lite@external— the@externalsuffix is required; the bare name is rejected by the CLIclaw plugins listand checks forevolve-litein stdoutTest plan
bash platform-integrations/install.sh status— Claw Code section appearsbash platform-integrations/install.sh install --platform claw-code --dry-run— dry-run shows correct commandbash platform-integrations/install.sh install --platform claw-code— installs plugin viaclaw plugins installbash platform-integrations/install.sh uninstall --platform claw-code— uninstalls viaclaw plugins uninstall evolve-lite@external🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation
Chores