You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A developer with access to multiple aictrl orgs (e.g. celliq and talentrix) can install the plugin for each org and both installs technically coexist — but every Claude Code session in every project loads both MCP servers and both skill sets, regardless of which repo the developer is actually in. The current design has no per-repo routing for MCP or skill activation, even though every other layer (credentials, project config, telemetry) is already org-aware.
What works today
Multi-org is a first-class concept in the data layer:
Each repo's .aictrl.json records its home org ({ orgSlug: "celliq" }).
The telemetry hook (src/hooks/resolve-credentials.sh.ts) walks CWD upward to find .aictrl.json, reads orgSlug, then picks the matching key from credentials. Telemetry attribution is correct per repo.
Running npx @aictrl/plugin twice (one per org) coexists cleanly: marketplace manifest carries both plugin entries, two plugin dirs sit side by side under ~/.claude/plugins/marketplaces/aictrl/plugins/, and both rows land in installed_plugins.json.
What breaks the "based on the repo folder" expectation
The installer enables plugins at user scope (~/.claude/settings.jsonenabledPlugins), not project scope. Consequences:
Both MCP servers connect in every session. Each plugin's .mcp.json hardcodes its org's URL and bearer token, so opening Claude Code in celliq/ also opens an HTTP connection to https://aictrl.dev/talentrix/mcp (and vice versa). This is wasted connection capacity, an unnecessary auth surface, and confusing in tool listings.
Both skill catalogues load in every project. Slash commands need the aictrl-<org>:<skill> qualifier to disambiguate, and the auto-loaded-skill ordering for same-named skills across orgs is undefined.
No project-local enablement. Disabling an org for a specific repo requires hand-editing ~/.claude/settings.json — which then disables it everywhere, defeating the point.
Proposed fix
Write enabledPlugins["aictrl-<org>@aictrl"] = true to project-scope settings instead of user-scope. Two ways to do it:
Option A (preferred): <projectDir>/.claude/settings.local.json
Per-developer, per-project enablement.
Should be gitignored (similar shape to existing .claude/settings.local.json conventions across Anthropic projects).
The installer already runs from the project dir, so it has the right CWD.
Option B: <projectDir>/.claude/settings.json
Per-project but team-shared (committed).
Probably wrong because enablement is a developer preference, not a project requirement.
Keep marketplace registration + plugin files + installed_plugins.json global (those are tied to the install itself, not enablement). Only the enablement toggle moves.
After this change:
cd ~/code/celliq && claude → only aictrl-celliq MCP + skills load.
cd ~/code/talentrix && claude → only aictrl-talentrix MCP + skills load.
Telemetry, credentials, project config all continue to work unchanged (they already key off .aictrl.json).
Implementation notes
src/writers/claude.tsmergeSettings currently takes settingsFile from CLAUDE_SETTINGS_FILE (user). It would need to take a project-scope path instead, derived from the project dir already passed to the CLI.
The installer should ensure .claude/settings.local.json is gitignored (add to ensureGitignore step alongside existing .opencode/ / .cursor/ entries).
Re-running the installer in a new repo would now be a one-off per repo (already the documented mental model — fits npx @aictrl/plugin naturally).
Summary
A developer with access to multiple aictrl orgs (e.g.
celliqandtalentrix) can install the plugin for each org and both installs technically coexist — but every Claude Code session in every project loads both MCP servers and both skill sets, regardless of which repo the developer is actually in. The current design has no per-repo routing for MCP or skill activation, even though every other layer (credentials, project config, telemetry) is already org-aware.What works today
Multi-org is a first-class concept in the data layer:
~/.aictrl/credentials.jsonstores per-org API keys:{ orgs: { celliq: { apiKey }, talentrix: { apiKey } } }..aictrl.jsonrecords its home org ({ orgSlug: "celliq" }).src/hooks/resolve-credentials.sh.ts) walks CWD upward to find.aictrl.json, readsorgSlug, then picks the matching key from credentials. Telemetry attribution is correct per repo.npx @aictrl/plugintwice (one per org) coexists cleanly: marketplace manifest carries both plugin entries, two plugin dirs sit side by side under~/.claude/plugins/marketplaces/aictrl/plugins/, and both rows land ininstalled_plugins.json.What breaks the "based on the repo folder" expectation
The installer enables plugins at user scope (
~/.claude/settings.jsonenabledPlugins), not project scope. Consequences:.mcp.jsonhardcodes its org's URL and bearer token, so opening Claude Code incelliq/also opens an HTTP connection tohttps://aictrl.dev/talentrix/mcp(and vice versa). This is wasted connection capacity, an unnecessary auth surface, and confusing in tool listings.aictrl-<org>:<skill>qualifier to disambiguate, and the auto-loaded-skill ordering for same-named skills across orgs is undefined.~/.claude/settings.json— which then disables it everywhere, defeating the point.Proposed fix
Write
enabledPlugins["aictrl-<org>@aictrl"] = trueto project-scope settings instead of user-scope. Two ways to do it:Option A (preferred):
<projectDir>/.claude/settings.local.json.claude/settings.local.jsonconventions across Anthropic projects).Option B:
<projectDir>/.claude/settings.jsonKeep marketplace registration + plugin files +
installed_plugins.jsonglobal (those are tied to the install itself, not enablement). Only the enablement toggle moves.After this change:
cd ~/code/celliq && claude→ onlyaictrl-celliqMCP + skills load.cd ~/code/talentrix && claude→ onlyaictrl-talentrixMCP + skills load..aictrl.json).Implementation notes
src/writers/claude.tsmergeSettingscurrently takessettingsFilefromCLAUDE_SETTINGS_FILE(user). It would need to take a project-scope path instead, derived from the project dir already passed to the CLI..claude/settings.local.jsonis gitignored (add toensureGitignorestep alongside existing.opencode//.cursor/entries).npx @aictrl/pluginnaturally).~/.claude/settings.jsonfrom prior installs should probably be cleaned up on next run so they don't double-enable. Equivalent to the legacy-cleanup pattern added in fix: register aictrl marketplace so Claude Code can resolve plugin enablement (#18) #19.Out of scope
code-reviewavailable everywhere regardless of org).Repro
npx @aictrl/plugin --org celliq --api-key ...in~/code/celliq.npx @aictrl/plugin --org talentrix --api-key ...in~/code/talentrix.cd ~/code/celliq && claude— observe bothaictrl-celliqandaictrl-talentrixMCP servers connecting, both skill sets listed.Acceptance
.aictrl.json).