mirror of
https://fastgit.cc/github.com/Yeachan-Heo/oh-my-claudecode
synced 2026-04-21 05:12:30 +08:00
Several code paths hardcoded ~/.claude instead of resolving the active config directory. Introduce
getClaudeConfigDir() as a shared helper (with ESM/CJS/shell mirrors in scripts/lib/) and update
all call sites:
- transcript validation: allow paths under the active config directory
- transcript fallback resolution: build projects/ lookups from the active config directory instead
of inline env-var fallback
- rules discovery: use getClaudeConfigDir() instead of hardcoded path
- rules injector: remove dead homeDir parameter from findRuleFiles and USER_RULE_DIR export;
breaking change to the public surface (no npm dependents)
- uninstall: preserve existing CLAUDE_CONFIG_DIR env var
- CLI: use getClaudeConfigDir() for runtime paths and config directory descriptions
(default: ~/.claude/)
- orchestrator: allow absolute paths under the active config directory while preserving
project-root and relative-path checks
- skills tools: reference the active config directory in runtime output and help text
- shared memory: read .omc-config.json from the active config directory
- session history search: resolve transcript roots from the active config directory
- auto-slash-command executor: replace hardcoded ~/.claude in error message output
- factcheck guard: add ${CLAUDE_CONFIG_DIR} token to forbidden_path_prefixes defaults and token
expander, replacing the hardcoded ${HOME}/.claude prefix
- config-dir helper: implement full getClaudeConfigDir() in config-dir.ts with tilde expansion
and trailing-slash normalization, replacing the trivial getConfigDir() wrapper and the re-export
from paths.ts
- runtime Node scripts: use shared config-dir helpers (ESM and CJS) instead of repeating
~/.claude fallbacks
- standalone hook templates: add templates/hooks/lib/config-dir.mjs shared helper (mirrors
scripts/lib/config-dir.mjs) so template scripts resolve the config directory consistently
- HUD wrapper: import the shared lib/config-dir helper instead of embedding duplicate
config-directory resolution logic
- persistent-mode scripts: resolve native tasks/todos from [$CLAUDE_CONFIG_DIR|~/.claude]
- shell scripts: use a shared config-dir.sh helper with ~ expansion and trailing-slash
normalization
- installer: copy config-dir helpers alongside standalone hooks and the HUD find-node.sh helper
- plugin setup: move nodeBin to module scope so both settings.json and hooks.json patching blocks
can access it (pre-existing const scoping bug where hooks.json patch always failed silently)
- skill snippets: replace $HOME/.claude with ${CLAUDE_CONFIG_DIR:-$HOME/.claude} in executable
shell snippets across 8 skill files
- skill prose instructions: replace hardcoded ~/.claude in LLM-actionable directives (Read/Write
tool targets, bash code blocks, path references in step instructions) across 9 skill files so
an LLM executing the skill resolves the active config directory
- HUD usage API: document and test that Keychain service names hash the exact CLAUDE_CONFIG_DIR
string, preserving distinct service-name mapping for ~-prefixed vs expanded inputs
- test files: align mock paths from paths.js to config-dir.js; fix vi.mock hoisting in
doctor-conflicts.test.ts; resolve macOS /var symlink mismatch in bridge-integration,
team-status, and edge-cases tests; update string-pattern assertions in hud-windows.test.ts
and mingw-escape.test.ts
- test script: source lib/config-dir.sh in scripts/test-pr25.sh for post-install path
verification
Adds focused regression coverage in:
- src/__tests__/auto-update.test.ts
- src/__tests__/cli-config-stop-callback.test.ts
- src/__tests__/config-dir.test.ts
- src/__tests__/delegation-enforcement-levels.test.ts
- src/__tests__/doctor-conflicts.test.ts
- src/__tests__/hud-api-key-source.test.ts
- src/__tests__/hud-marketplace-resolution.test.ts
- src/__tests__/hud-windows.test.ts
- src/__tests__/hud/cli-diagnostic.test.ts
- src/__tests__/hud/usage-api-lock.test.ts
- src/__tests__/hud/usage-api-stale.test.ts
- src/__tests__/hud/usage-api.test.ts
- src/__tests__/installer.test.ts
- src/__tests__/purge-stale-cache.test.ts
- src/__tests__/session-history-search.test.ts
- src/__tests__/setup-claude-md-script.test.ts
- src/__tests__/shared-memory.test.ts
- src/hooks/factcheck/__tests__/factcheck.test.ts
- src/installer/__tests__/standalone-hook-reconcile.test.ts
- src/notifications/__tests__/config-merge.test.ts
- src/notifications/__tests__/profiles.test.ts
- src/openclaw/__tests__/config.test.ts
- src/skills/__tests__/mingw-escape.test.ts
- src/team/__tests__/bridge-integration.test.ts
- src/team/__tests__/edge-cases.test.ts
- src/team/__tests__/inbox-outbox.test.ts
- src/team/__tests__/message-router.test.ts
- src/team/__tests__/outbox-reader.test.ts
- src/team/__tests__/team-registration.test.ts
- src/team/__tests__/team-status.test.ts
103 lines
3.5 KiB
Bash
Executable File
103 lines
3.5 KiB
Bash
Executable File
#!/bin/sh
|
|
# OMC Node.js Finder (find-node.sh)
|
|
#
|
|
# Locates the Node.js binary and executes it with the provided arguments.
|
|
# Designed for nvm/fnm users where `node` is not on PATH in non-interactive
|
|
# shells (e.g. Claude Code hook invocations). Fixes issue #892.
|
|
#
|
|
# Priority:
|
|
# 1. nodeBinary stored in ~/.claude/.omc-config.json (set at setup time)
|
|
# 2. `which node` (node is on PATH)
|
|
# 3. nvm versioned paths (~/.nvm/versions/node/*/bin/node)
|
|
# 4. fnm versioned paths (~/.fnm/node-versions/*/installation/bin/node)
|
|
# 5. Homebrew / system paths (/opt/homebrew/bin/node, /usr/local/bin/node)
|
|
#
|
|
# Exits 0 on failure so it never blocks Claude Code hook processing.
|
|
|
|
NODE_BIN=""
|
|
|
|
case "$0" in
|
|
*/*)
|
|
SCRIPT_DIR="${0%/*}"
|
|
;;
|
|
*)
|
|
SCRIPT_DIR='.'
|
|
;;
|
|
esac
|
|
|
|
SCRIPT_DIR="$(cd "$SCRIPT_DIR" && pwd)"
|
|
. "$SCRIPT_DIR/lib/config-dir.sh"
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 1. Read stored node path from OMC config
|
|
# ---------------------------------------------------------------------------
|
|
CLAUDE_DIR="$(resolve_claude_config_dir)"
|
|
CONFIG_FILE="$CLAUDE_DIR/.omc-config.json"
|
|
if [ -f "$CONFIG_FILE" ]; then
|
|
# POSIX-safe extraction without requiring jq
|
|
_stored=$(grep -o '"nodeBinary" *: *"[^"]*"' "$CONFIG_FILE" 2>/dev/null \
|
|
| head -1 \
|
|
| sed 's/.*"nodeBinary" *: *"//;s/".*//')
|
|
if [ -n "$_stored" ] && [ -x "$_stored" ]; then
|
|
NODE_BIN="$_stored"
|
|
fi
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 2. which node
|
|
# ---------------------------------------------------------------------------
|
|
if [ -z "$NODE_BIN" ] && command -v node >/dev/null 2>&1; then
|
|
NODE_BIN="node"
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 3. nvm versioned paths: iterate to find the latest installed version
|
|
# ---------------------------------------------------------------------------
|
|
if [ -z "$NODE_BIN" ] && [ -d "$HOME/.nvm/versions/node" ]; then
|
|
# shellcheck disable=SC2231
|
|
for _path in "$HOME/.nvm/versions/node/"*/bin/node; do
|
|
[ -x "$_path" ] && NODE_BIN="$_path"
|
|
# Keep iterating — later entries tend to be newer (lexicographic order)
|
|
done
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 4. fnm versioned paths (Linux and macOS default locations)
|
|
# ---------------------------------------------------------------------------
|
|
if [ -z "$NODE_BIN" ]; then
|
|
for _fnm_base in \
|
|
"$HOME/.fnm/node-versions" \
|
|
"$HOME/Library/Application Support/fnm/node-versions" \
|
|
"$HOME/.local/share/fnm/node-versions"; do
|
|
if [ -d "$_fnm_base" ]; then
|
|
# shellcheck disable=SC2231
|
|
for _path in "$_fnm_base/"*/installation/bin/node; do
|
|
[ -x "$_path" ] && NODE_BIN="$_path"
|
|
done
|
|
[ -n "$NODE_BIN" ] && break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# 5. Common Homebrew / system paths
|
|
# ---------------------------------------------------------------------------
|
|
if [ -z "$NODE_BIN" ]; then
|
|
for _path in /opt/homebrew/bin/node /usr/local/bin/node /usr/bin/node; do
|
|
if [ -x "$_path" ]; then
|
|
NODE_BIN="$_path"
|
|
break
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Invoke node with all provided arguments
|
|
# ---------------------------------------------------------------------------
|
|
if [ -z "$NODE_BIN" ]; then
|
|
printf '[OMC] Error: Could not find node binary. Run /oh-my-claudecode:omc-setup to fix.\n' >&2
|
|
exit 0 # exit 0 so this hook does not block Claude Code
|
|
fi
|
|
|
|
exec "$NODE_BIN" "$@"
|