Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

SessionStart hook leaks $CLAUDE_PLUGIN_DATA into global session env, breaking per-plugin scoping for every other plugin #338

Open

Description

Summary

scripts/session-lifecycle-hook.mjs:78 writes the codex plugin's own CLAUDE_PLUGIN_DATA value into CLAUDE_ENV_FILE, which Claude Code sources into the global session environment. After codex's SessionStart hook fires, every subsequent plugin and every Claude Code surface in the session inherits CLAUDE_PLUGIN_DATA=<codex's data dir>, regardless of which plugin's hook or skill is actually running.

This breaks the per-plugin scoping contract documented in Anthropic's plugin docs: $CLAUDE_PLUGIN_DATA is supposed to resolve to the invoking plugin's data directory.

Prior art

Offending code

scripts/session-lifecycle-hook.mjs:

function handleSessionStart(input) {
 appendEnvVar(SESSION_ID_ENV, input.session_id);
 appendEnvVar(PLUGIN_DATA_ENV, process.env[PLUGIN_DATA_ENV]); // ← line 78
}

appendEnvVar writes export CLAUDE_PLUGIN_DATA=<value> to $CLAUDE_ENV_FILE. Claude Code sources that file into the session-wide environment, so the value persists across every subsequent hook and skill invocation — not just codex's.

Reproduction

  1. Install codex-plugin-cc v1.0.4 alongside any second plugin that uses $CLAUDE_PLUGIN_DATA for its own state (or simply reads it expecting per-plugin scoping).
  2. Start a Claude Code session — codex's SessionStart hook fires.
  3. Invoke any surface in the second plugin (a skill, a slash command, a hook).
  4. Inside that surface, inspect $CLAUDE_PLUGIN_DATA — it points at codex's data dir, not the invoking plugin's.

Concrete observation from a glitchwerks/claude-wayfinder setup:

Warning: $CLAUDE_PLUGIN_DATA points at 'codex-openai-codex',
expected 'claude-wayfinder-glitchwerks'. Falling back to computed path.

Wayfinder's /setup-wayfinder skill (link: https://github.com/glitchwerks/claude-wayfinder/blob/main/skills/setup-wayfinder/SKILL.md) had to add slug-validation specifically as a defense against this — checking basename($CLAUDE_PLUGIN_DATA) against the expected plugin slug and falling back to the computed path when it mismatches.

Impact

Any plugin that reads $CLAUDE_PLUGIN_DATA after a codex SessionStart sees the wrong path. Concrete failure modes:

  • Wrong venv path — plugin installs Python deps into the codex data dir instead of its own.
  • Wrong state files — plugin reads/writes its persistence files in codex's namespace.
  • Wrong cache invalidation — plugin's mtime-keyed cache logic compares files in the wrong tree.
  • Silent — none of these throws; behavior just goes subtly wrong.

The bug forces every other plugin author to add a defensive guard against codex specifically. That's a load-bearing harness contract being broken by one plugin.

Proposed fix

Don't re-export CLAUDE_PLUGIN_DATA to the global session env. If codex needs its data dir to survive across its own hooks within a session, persist it under a codex-namespaced variable:

 function handleSessionStart(input) {
 appendEnvVar(SESSION_ID_ENV, input.session_id);
- appendEnvVar(PLUGIN_DATA_ENV, process.env[PLUGIN_DATA_ENV]);
+ // Persist codex's plugin-data path under a namespaced var so codex's
+ // own hooks can read it without overwriting the harness-managed
+ // $CLAUDE_PLUGIN_DATA, which other plugins rely on for per-plugin
+ // scoping.
+ appendEnvVar("CODEX_PLUGIN_DATA", process.env[PLUGIN_DATA_ENV]);
 }

Any later codex code that reads process.env.CLAUDE_PLUGIN_DATA would need to fall back to process.env.CODEX_PLUGIN_DATA if the former mismatches the codex slug. Alternative: have codex always recompute its data dir from $HOME + the deterministic slug rather than reading the env var at all (mirrors what Anthropic's docs prescribe as the fallback).

Happy to open a PR if the approach above looks right; let me know if you'd prefer a different shape.

Environment

  • Plugin version: 1.0.4
  • Claude Code: latest
  • OS: Windows (the symptom is platform-agnostic — env-file sourcing works the same on Linux/macOS).

🤖 Generated by Claude Code on behalf of @cbeaulieu-gt

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

        AltStyle によって変換されたページ (->オリジナル) /