Skip to content

fix(cli): a project the CLI set up loads none of its plugins headless, and says nothing #703

Description

@blafourcade

A project set up by the CLI, with plugins installed and reported installed, loads none of them under claude -p. The session runs, answers, and every skill it was supposed to use is silently absent.

What was measured

A throwaway project, set up entirely through the CLI — aidd setup, aidd marketplace add, aidd plugin install — each reporting success. A headless session was then asked to run three named skills in sequence. It ran, it answered, and it produced zero run files: no skill resolved. The Skill tool answered "Unknown skill" for all three, and the session hand-rolled the procedures by reading them off disk instead, which looks like success from the outside.

claude --debug-file names the cause in one line:

Skipping orphaned enabledPlugins entry ...: marketplace not registered

The project's .claude/settings.json carries the enabledPlugins entry the CLI wrote. Headless claude -p does not register the marketplace that entry points at, so the entry is orphaned and dropped — quietly, on stderr, behind a debug flag nobody passes.

Passing --plugin-dir <path> per plugin loads them and the same session resolves all three skills. So nothing is wrong with the plugins; what is wrong is that the installation the CLI performs is not the installation the headless runtime reads.

That failed session cost $1.27 and produced nothing.

Why it is worth a ticket of its own

This is the installation-path twin of the failure mode the measurement work exists to remove. Every visible signal says healthy: setup succeeded, plugin install reported success, the session ran and answered. The only tell is an absence — no skill resolved, and nothing said so.

It also lands hardest where nobody is watching. A person working interactively sees their skills missing and investigates. Anything headless — CI, an agent, a scheduled run — produces plausible output built without the skills it was meant to use, and no telemetry, and reports success.

Done when

  • A project set up by the CLI loads its plugins under claude -p, without a caller passing --plugin-dir.
  • Or, if the runtime genuinely cannot register a marketplace headlessly, the CLI says so at install time and writes whatever the headless path does read.
  • A session that resolved no skill from an installed plugin is distinguishable from one that needed none.
  • A test fails when the two install surfaces disagree about which plugins load.

Bounds

Observed on one machine, on claude -p with a project-scope marketplace registered by the CLI. Whether an interactive session in the same project loads them was not tested — it is the obvious next probe and it separates "headless only" from "this project is broken".

Where it was found

Running the first real multi-step flow for the telemetry milestone (#694). The measurement layer was never the problem; it correctly reported nothing, because nothing happened.

Activity

  1. moved this from Ideation to In Progress in AIDD Roadmapon Sep 2, 2026
  2. blafourcade commented on Sep 2, 2026

    @blafourcade
    ContributorAuthor

    Re-read against next at 627408fb, and the scope changes in three ways.

    The Bounds question is answered, and the answer is "headless only." No probe needed —
    cli/src/infrastructure/adapters/claude-cli-adapter.ts:5-13 records the measurement:
    the runtime loads a plugin only once it is in the user-global registry
    (~/.claude/plugins/known_marketplaces.json, installed_plugins.json), which only
    claude plugin marketplace add / claude plugin install populate. Interactive Claude Code
    performs that registration itself once a person accepts the workspace trust dialog;
    claude -p skips the dialog and never registers.

    The fix shipped in #706. ClaudeCliAdapter landed 2026-08-24, three days after this
    issue was filed, and activateNativeTools now runs from all seven call sites this ticket
    names: commands/marketplace.ts ×3, commands/plugin.ts ×3, commands/setup.ts. So the
    first "Done when" is met by the second branch it offered — the CLI drives what the headless
    path actually reads.

    The third box moves to #694. Claude Code is translationMode: "marketplace", so when
    this failure happens the telemetry plugin does not load either, journal.cjs never runs,
    and there is no run file at all — which is exactly what this ticket measured ("it produced
    zero run files"). With no run file there is no session record to tell from another, so
    "a session that resolved no skill is distinguishable from one that needed none" can only be
    answered by the diagnostic, and #694 owns the diagnostic's shape. It is that ticket's first
    row, seen from the install side.

    What is left here, and it needs no session at all

    aidd telemetry check reads the declaration — enabledPlugins in the project's own
    settings, resolved exactly the way the write resolves it
    (telemetry-evidence-adapter.ts:71-83). It never reads the registry the runtime uses.
    known_marketplaces.json and installed_plugins.json appear three times in this codebase
    and all three are prose in comments; nothing opens them.

    So today the CLI can say "the plugin is declared". It cannot say "the host registered it,
    so it will load" — and that gap is this ticket's fourth box, checkable by reading two files
    and comparing them.

    marketplace-sync-settings-use-case.ts, the file that triggers the activation, has no test
    file: find cli/tests -name "*sync-settings*" returns nothing.

    Rescoped Done when

    • The host's own registry is read, not only the declaration the CLI wrote.
    • aidd telemetry check states whether the two agree, and names which side is missing
      when they do not — never a bare pass.
    • A test fails when the two install surfaces disagree about which plugins load, driven
      through marketplace-sync-settings-use-case.ts rather than around it.
    • The comparison needs no AI session, no network and no money to run.
  3. blafourcade commented on Sep 3, 2026

    @blafourcade
    ContributorAuthor

    Delivered by #748, squash-merged into next as 919aee3.

  4. moved this from In Progress to Done in AIDD Roadmapon Sep 3, 2026
  5. added theissue type on Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    Priority

    High

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions