Summary
setup-helper/wrapper.sh in both examples/codex-memory-plugin/ and examples/claude-code-memory-plugin/ defines a public wrapper (codex() / claude()) that calls private helpers named with a single leading underscore (_openviking_codex_exec, _openviking_run, _openviking_dispatch, _openviking_define_wrappers, _openviking_codex_plugin_dir). When invoked from Claude Code's own Bash tool, this fails with zsh: command not found: _openviking_codex_exec (exit 127) — it works fine from a normal interactive terminal.
Root cause
Claude Code doesn't re-source .zshrc on every Bash tool call. At session start it snapshots the interactive shell's function definitions to a static file and replays that snapshot for every subsequent call (avoids re-running slow interactive init on each command). That snapshot step silently drops every function whose name starts with exactly one leading underscore — almost certainly to avoid dumping zsh's large completion-function namespace (_git, _npm, etc., which follow the same single-underscore convention). Double-underscore names (__foo) are preserved.
Since the public wrapper itself (codex/claude) has no leading underscore, it survives the snapshot and gets invoked — then immediately fails calling a helper that was silently dropped from the replayed shell state.
This isn't an edge case: an AI coding agent invoking codex/claude non-interactively via a Bash tool is a core usage path this plugin exists to support (injecting OPENVIKING_* credentials at launch).
Verified fix
Renaming every _openviking_* helper to __openviking_* (double leading underscore) makes them survive Claude Code's snapshot filter, with no other behavior change. Confirmed locally:
- repo-wide
grep shows no other file references these helper names by string (safe rename, no other call sites)
zsh -n is syntax-clean on both wrapper.sh files after the rename
- a fresh
zsh -c 'source wrapper.sh; codex --version' resolves the full renamed call chain and runs correctly
Happy to open a PR with the rename applied to both wrapper.sh files if that's useful — flagging as an issue first in case there's a preferred approach (e.g. avoiding shell-function state entirely for this kind of snapshot-replay environment).
Summary
setup-helper/wrapper.shin bothexamples/codex-memory-plugin/andexamples/claude-code-memory-plugin/defines a public wrapper (codex()/claude()) that calls private helpers named with a single leading underscore (_openviking_codex_exec,_openviking_run,_openviking_dispatch,_openviking_define_wrappers,_openviking_codex_plugin_dir). When invoked from Claude Code's own Bash tool, this fails withzsh: command not found: _openviking_codex_exec(exit 127) — it works fine from a normal interactive terminal.Root cause
Claude Code doesn't re-source
.zshrcon every Bash tool call. At session start it snapshots the interactive shell's function definitions to a static file and replays that snapshot for every subsequent call (avoids re-running slow interactive init on each command). That snapshot step silently drops every function whose name starts with exactly one leading underscore — almost certainly to avoid dumping zsh's large completion-function namespace (_git,_npm, etc., which follow the same single-underscore convention). Double-underscore names (__foo) are preserved.Since the public wrapper itself (
codex/claude) has no leading underscore, it survives the snapshot and gets invoked — then immediately fails calling a helper that was silently dropped from the replayed shell state.This isn't an edge case: an AI coding agent invoking
codex/claudenon-interactively via a Bash tool is a core usage path this plugin exists to support (injectingOPENVIKING_*credentials at launch).Verified fix
Renaming every
_openviking_*helper to__openviking_*(double leading underscore) makes them survive Claude Code's snapshot filter, with no other behavior change. Confirmed locally:grepshows no other file references these helper names by string (safe rename, no other call sites)zsh -nis syntax-clean on bothwrapper.shfiles after the renamezsh -c 'source wrapper.sh; codex --version'resolves the full renamed call chain and runs correctlyHappy to open a PR with the rename applied to both
wrapper.shfiles if that's useful — flagging as an issue first in case there's a preferred approach (e.g. avoiding shell-function state entirely for this kind of snapshot-replay environment).