fix(openclaw): shell safety, HTTP dual-mode, lazy reinit, per-user banks#388
Merged
nicoloboschi merged 1 commit intovectorize-io:mainfrom Feb 18, 2026
Merged
Conversation
e5d615c to
073773b
Compare
nicoloboschi
requested changes
Feb 17, 2026
Collaborator
nicoloboschi
left a comment
There was a problem hiding this comment.
the execFile switch is a great improvement for shell safety, but it doesn't fix E2BIG — execFile still calls execve() internally, so ARG_MAX still applies to large content passed as argv. We need to write the content to a temp file and use retain-files for retain(). The index.ts changes (lazy reinit, senderId) look good.
can you rebase?
a197aa4 to
b8cdabb
Compare
1551e2e to
17275a2
Compare
- exec→execFile: bypass shell entirely, preventing injection via
special characters in chat history
- HTTP dual-mode: client can now talk directly to the Hindsight API
via HTTP (setBankMission, retain, recall) when apiUrl is configured,
bypassing the subprocess/CLI entirely for production deployments
- HindsightClientOptions: replace 5 positional constructor args with
a typed options object for clarity and extensibility
- sanitize(): strip null bytes from strings — Node 22 rejects them
in execFile() args
- recall timeout: accept optional timeoutMs parameter for both HTTP
and subprocess modes; subprocess gets a longer 30s default
- In-flight recall dedup: concurrent recalls for the same bank reuse
one promise instead of firing duplicate requests
- Timeout/abort handling: graceful warn-level logging instead of
error spam when recall times out
- Error cause chaining: wrap errors with { cause } for better
debugging stack traces
- lazyReinit: recover from startup health check failure with 30s
cooldown and concurrency guard
- Per-user banks: derive bank ID from senderId (not channelId) for
proper memory isolation per user across channels
- buildClientOptions(): centralized helper replaces 7 duplicated
constructor call sites
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
17275a2 to
dfb98d9
Compare
nicoloboschi
approved these changes
Feb 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Comprehensive hardening and feature additions for the OpenClaw Hindsight plugin:
Shell safety
exec→execFile: Bypass the shell entirely, preventing injection via special characters (quotes, backticks,$()) in chat history. All CLI invocations now use array args.escapeShellArgremoved: No longer needed —execFiledoesn't interpret shell metacharacters.sanitize(): Strip null bytes from strings — Node 22 rejects them inexecFile()args.HTTP dual-mode
apiUrlis configured, the client talks directly to the Hindsight API via HTTP (fetch), bypassing the subprocess/CLI entirely. Useful for production deployments where the API is already running.HindsightClientOptions: Replace 5 positional constructor args with a typed options object for clarity and extensibility (apiUrl,apiTokenfields).buildClientOptions(): Centralized helper replaces 7 duplicated constructor call sites acrossindex.ts.Reliability
timeoutMsparameter for both HTTP and subprocess modes. HTTP defaults to 15s, subprocess to 30s.warn-level logging instead of error spam when recall times out (TimeoutError,AbortError).{ cause }for better debugging stack traces.lazyReinit(): Recover from startup health check failure with 30s cooldown and concurrency guard. Only triggers in external API mode.Per-user memory isolation
senderIdinstead ofchannelId: Derive bank ID from{messageProvider}-{senderId}for proper memory isolation per user, even across channels.dynamicBankId(default: enabled) andbankIdPrefixin plugin config.Test plan
npx vitest run— 12/12 tests pass