Skip to content

fix(agents): codemie-claude hook command-not-found and unsupported effort param (EPMCDME-14035) - #484

Open
SleepySML wants to merge 12 commits into
codemie-ai:mainfrom
SleepySML:EPMCDME-14035
Open

fix(agents): codemie-claude hook command-not-found and unsupported effort param (EPMCDME-14035)#484
SleepySML wants to merge 12 commits into
codemie-ai:mainfrom
SleepySML:EPMCDME-14035

Conversation

@SleepySML

Copy link
Copy Markdown
Contributor

Summary

Fixes two independent codemie-claude failures reported in EPMCDME-14035:

  1. Claude Code hooks failing with /usr/bin/bash: line 1: codemie: command not found.
  2. Requests to claude-4-5-sonnet failing with API Error: 400 "This model does not support the effort parameter".

Both were reproduced before fixing.

Root causes

  • Bug 1 (hooks): Installed hook configs invoked the bare codemie command. Claude Code runs hooks in a fresh bash -c "codemie hook" shell; when that shell's PATH doesn't include the codemie bin dir (a user-prefix install without admin rights), every hook fails with command-not-found.
  • Bug 2 (effort): The SSO proxy claude-request-normalizer only ever added output_config.effort for adaptive-thinking models and never stripped it for models that don't support it. Newer Claude Code emits effort from its --effort flag, so a claude-4-5-sonnet request carried effort through untouched → upstream 400.

Changes

Bug 1 — absolute, PATH-independent hook commands

  • src/utils/hook-command.ts (new) — shared resolver: resolveCodemieBinary() (getCommandPath('codemie')process.argv[1] fallback; quotes paths with spaces; prefixes node for a Windows .js fallback), resolveHookCommand() (rewrites the leading codemie token), rewriteHooksCommandTree() (walks a hooks config). Resolution never throws.
  • src/agents/core/extension/BaseExtensionInstaller.ts — post-copy localizeInstalledHooks() rewrites the installed hooks.json to an absolute path (covers Claude and Gemini via the shared base class). Non-fatal.
  • src/agents/plugins/codemie-code.plugin.ts — inline OPENCODE_HOOKS default hooks (buildDefaultHooks) use the resolved absolute path.
  • src/migrations/006-resolve-hook-command-paths.migration.ts (new) — one-time repair of already-installed Claude/Gemini hooks for users whose plugin version didn't bump. Idempotent; returns failure on a write error so the runner retries.

Bug 2 — strip unsupported effort

  • src/providers/plugins/sso/proxy/plugins/claude-request-normalizer.plugin.ts — new handleUnsupportedEffort() strips output_config.effort and any top-level effort for models not matching the adaptive-thinking patterns; runs regardless of whether thinking is present. Adaptive models (opus-4-7+, sonnet-5) keep effort.

Testing

  • 20 new unit tests; full unit suite 3037 passing.
  • lint, typecheck, build, commitlint, and the gitleaks secrets scan all green.
  • license-check and the integration/agent suites were skipped locally for environmental reasons (npm-cache perms / live-SSO / env-heavy) — all enforced by CI.

Code review

A three-lens review (blind / edge-case / acceptance) ran on the diff and this PR fixes what it found:

  • 🔴 critical — migration marked itself permanently applied on a write failure (never retried) → now returns failure so it retries next launch.
  • 🟠 major — Windows .js argv[1] fallback wasn't directly invocable as a hook command → now node-prefixed.

Acceptance criteria

  • codemie available to hook execution after codemie-claude setup
  • SessionStart hooks no longer fail with command-not-found
  • UserPromptSubmit hooks no longer fail with command-not-found
  • claude-4-5-sonnet requests no longer include unsupported effort
  • Unsupported params omitted safely before send
  • Works without admin rights to downgrade CodeMie

Notes

  • Squash-and-Merge per project default.
  • Hook rewriting and migration 006 are idempotent and non-fatal — they never break install or startup.

@SleepySML SleepySML changed the title fix(agents): resolve codemie-claude hook command-not-found and unsupported effort param (EPMCDME-14035) fix(agents): codemie-claude hook command-not-found and unsupported effort param (EPMCDME-14035) Aug 13, 2026
@8nevil8

8nevil8 commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Automated review — critical finding

Focused on architecture, patterns, correctness, DRY, YAGNI. Minor issues intentionally omitted.

1. Migration hardcodes ~/.codemie instead of using getCodemiePath()

src/migrations/006-resolve-hook-command-paths.migration.ts:34

hookFiles() hard-codes path.join(homedir(), '.codemie', ...) instead of calling getCodemiePath() from src/utils/paths.ts.

AGENTS.md Common Pitfalls explicitly forbids this. Users with a custom codemie home directory (via env var or non-default install prefix) will have the migration silently skip their hook files — leaving the command-not-found bug unrepaired for exactly the users most likely affected (non-admin, user-prefix installs).

Fix direction: Replace path.join(homedir(), '.codemie', 'claude-plugin', 'hooks', 'hooks.json') with path.join(getCodemiePath(), 'claude-plugin', 'hooks', 'hooks.json') to honour the project's path abstraction.


Both fixes are otherwise architecturally sound and correctly layered — the hook-path resolver lands in src/utils/, migration 006 follows the established runner pattern, and effort stripping lands in the correct proxy-plugin chain. Only the hardcoded path violates a documented project guardrail.

@SleepySML

Copy link
Copy Markdown
Contributor Author

Done — addressed in 9d92a73. hookFiles() now uses getCodemiePath('claude-plugin', 'hooks', 'hooks.json') (which honours CODEMIE_HOME) instead of the hardcoded homedir()/.codemie, so custom/user-prefix codemie homes are repaired too. The .gemini extensions path is left on homedir() since it targets a different tool's home that getCodemiePath() does not cover. Migration 006 unit tests still green (4/4).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants