Skip to content

[feat]: Add setting to disable automatic hook config injection (.claude/settings.local.json, .codex/config.toml) #1944

@rasitakyol

Description

@rasitakyol

Description

Every time emdash spawns an agent session, HookConfigWriter.prepareHookConfig() writes
notification hook configs into the project/worktree cwd:

  • .claude/settings.local.json — adds Notification and Stop hook entries pointing at
    emdash's local POST endpoint (carries EMDASH_HOOK_PORT / EMDASH_HOOK_TOKEN markers).
  • .codex/config.toml — sets notify = [...] to the bundled notify script.
  • .opencode/plugins/emdash-notifications.js, .pi/extensions/emdash-hook.ts for those
    providers.

There is currently no setting that disables this injection. The two related toggles
do not gate it:

Setting Effect
notifications.enabled Only suppresses Notification.show() (OS toast). The hook file is still written.
localProject.writeAgentConfigToGitIgnore Only controls whether the path is added to .gitignore. The hook file is still written.

Why this is a problem

  • It silently mutates user-owned config files (.claude/settings.local.json is meant for
    user-specific permissions, not tool-managed hooks).
  • It runs on every fresh LocalConversationProvider instance — disabling per-task caching
    via preparedHookProviders is per-instance and resets across tasks/sessions.
  • Users who don't want their projects coupled to a running emdash daemon (e.g. they share
    the worktree with other agents, run agents directly, or audit their repo for unexpected
    files) have no opt-out short of patching the asar or making the files immutable
    (chmod 444 / chflags uchg), both of which produce silent write failures emdash logs
    as warnings.

Reproduction

  1. emdash 1.1.10, macOS.
  2. Open any project, start a Claude or Codex task.
  3. cat .claude/settings.local.json — the hooks block now contains an entry referencing
    EMDASH_HOOK_PORT. Same for .codex/config.toml (notify = ...).
  4. Toggle off notifications.enabled and writeAgentConfigToGitIgnore from Settings.
  5. Start a new task — the hook entries are re-written.

Source pointers (1.1.10, packed out/main/index.js)

  • class HookConfigWriterwriteClaudeHooks / writeCodexNotify / writeForProvider /
    writeAll.
  • Caller: LocalConversationProvider.prepareHookConfig invoked from startSession. The
    guard only checks writeAgentConfigToGitIgnore for .gitignore writes, never gates the
    config file write itself.

Proposed fix

Add a new setting (e.g. localProject.injectAgentNotificationHooks: boolean, default
true to preserve current behavior) and short-circuit prepareHookConfig when it's
false. Optionally per-provider granularity ({ claude: false, codex: true }) for users
who want notifications for one provider but not another.

A "clean up existing emdash hook entries from this project" action in Settings would also
be helpful, since users who toggle this off will have stale entries from previous runs.

emdash version

1.1.10

OS

macOS (Darwin 25.3.0)

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions