Skip to content

fix(desktop): skip uninstalled agents when provisioning hooks - #9233

Open
Kitenite wants to merge 1 commit into
fix/desktop-first-launch-quietfrom
fix/desktop-skip-uninstalled-agents
Open

Kitenite wants to merge 1 commit into
fix/desktop-first-launch-quietfrom
fix/desktop-skip-uninstalled-agents

Conversation

@Kitenite

@Kitenite Kitenite commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

What

Follow-up to #9219 for SUPER-3089. Desktop provisioning no longer writes hooks, settings or plugins into config dirs of agents the user has not installed (~/.codex, ~/.cursor, ~/.gemini, ...).

How

  • New isAgentInstalled in packages/agent-setup: an agent counts as installed when its binary is on PATH or in a usual install dir (~/.local/bin, ~/.bun/bin, Homebrew, ...), or its home config dir exists. Superset's own wrapper dir is ignored.
  • setupAgentIntegrations / setupAgentCapabilities take skipUninstalledAgents. Only desktop passes it; headless/CLI/cloud hosts keep provisioning every agent, so their behavior is unchanged.
  • Re-provision trigger: desktop re-runs provisioning on window focus (at most once a minute, only after post-onboarding setup ran). Installing Claude Code after Paradev picks up hooks without a restart.

Not changed

  • Managed skills (~/.agents/skills) and the zsh/bash wrappers still write after onboarding.
  • Disabled agents still get teardown, whether installed or not.

Verification

  • bun test in packages/agent-setup: new installed-agents.test.ts passes. Two shell-wrappers fallback tests fail in this sandbox, and they fail the same way on fix(desktop): keep first launch quiet until the user is onboarded #9219's branch.
  • biome check clean; tsc --noEmit clean for agent-setup.
  • Not run in the real app. Focus re-provision is untested outside unit logic.

Stacked on #9219; retarget to main after it merges.


Summary by cubic

Follow-up to #9219: desktop provisioning no longer writes hooks, settings, or plugins into the config dirs of agents the user hasn't installed (~/.codex, ~/.cursor, ~/.gemini, ...). Headless/CLI/cloud hosts still provision all agents, so their behavior is unchanged.

  • Skips agents with no binary on PATH, in a usual install dir (Homebrew, ~/.local/bin, ~/.bun/bin, ...), or no home config dir, and ignores Superset's own wrapper dir when searching.
  • Desktop re-runs provisioning on window focus, at most once a minute and only after onboarding, so installing an agent after Paradev picks up its hooks without a restart.
  • Managed skills (~/.agents/skills) and the zsh/bash wrappers still write after onboarding; disabled agents still get torn down whether installed or not.

This PR is stacked on #9219; retarget to main after it merges.

Written for commit 2c6bcf5. Summary will update on new commits.

View guided diff Turn on auto-fix

Desktop boot no longer writes hooks into config dirs of agents that are
not installed (binary on PATH or usual install dir, or config dir present).
Re-provision on window focus (at most once a minute) so installing an
agent after Paradev still gets its hooks without a restart.

Stacked on #9219.
@coderabbitai

coderabbitai Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 7cd4d739-5669-42f2-b0d0-696397f45409

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • Trigger review
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@greptile-apps

greptile-apps Bot commented Nov 1, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The changes affect desktop setup of local agent integrations.

Fix Claude provisioning before merging; users without Claude still get its config directory and settings.

Findings

  1. P1 Uninstalled Claude still gets configured ▶
  2. P2 Custom agent homes get missed ▶
Fix with agent prompt
### Issue 1
packages/agent-setup/src/agent-setup.ts:252-253
`skipUninstalledAgents` still creates `~/.claude` on a machine without Claude. Before this check, `createManagedSkills()` copies the bundled plugin into `~/.claude/skills/superset`. The check then treats that newly created directory as proof that Claude is installed and writes its settings and wrapper too.

Pass the installation filter into Claude plugin provisioning while keeping the shared `~/.agents` skills unchanged.

### Issue 2
packages/agent-setup/src/installed-agents.ts:84-86
The config-directory fallback ignores supported custom locations. If `KIMI_CODE_HOME` points to an existing profile and the Kimi binary is outside the desktop's search directories, this checks only `~/.kimi-code` and skips Kimi's hook setup. The existing writer correctly uses `KIMI_CODE_HOME`.

Resolve the same effective config paths here. The same mismatch affects `OMP_CODING_AGENT_DIR` and the `XDG_CONFIG_HOME` paths for Devin and Muse.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Summary

Desktop setup now skips agents that installation detection cannot find. Window focus retries setup after onboarding, at most once per minute. Other callers keep the existing default.

  • Desktop setup skips enabled agents it cannot find installed.
  • Desktop setup checks for newly installed agents when a window gets focus.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[Post-onboarding setup or throttled focus] --> B[Desktop requests installed agents only]
  B --> C[Provision shared skills]
  C --> D[Create Claude plugin directory]
  D --> E[Check agent installation]
  E --> F[Claude directory now exists]
  F --> G[Write Claude settings and wrapper]
  E --> H[Skip other undetected agents]
Loading

Reviews (1) · Last reviewed commit: "fix(desktop): skip uninstalled agents wh..." · Reviewed by Greptile

@github-actions

github-actions Bot commented Nov 1, 2026

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

🔗 Preview Links

Service Status Link
Neon Database (Neon) ✅ View Branch
Vercel API (Vercel) ✅ Open Preview
Vercel Web (Vercel) ✅ Open Preview
Vercel Marketing (Vercel) ✅ Open Preview
Vercel Docs (Vercel) ✅ Open Preview

Preview updates automatically with new commits

Comment on lines +252 to +253
if (skipUninstalledAgents && !isDisabled && !isInstalled(target.id)) {
continue;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Uninstalled Claude still gets configured

skipUninstalledAgents still creates ~/.claude on a machine without Claude. Before this check, createManagedSkills() copies the bundled plugin into ~/.claude/skills/superset. The check then treats that newly created directory as proof that Claude is installed and writes its settings and wrapper too.

Pass the installation filter into Claude plugin provisioning while keeping the shared ~/.agents skills unchanged.

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/agent-setup/src/agent-setup.ts
Line: 252-253

Comment:
**Uninstalled Claude still gets configured**

`skipUninstalledAgents` still creates `~/.claude` on a machine without Claude. Before this check, `createManagedSkills()` copies the bundled plugin into `~/.claude/skills/superset`. The check then treats that newly created directory as proof that Claude is installed and writes its settings and wrapper too.

Pass the installation filter into Claude plugin provisioning while keeping the shared `~/.agents` skills unchanged.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Comment on lines +84 to +86
if (footprint.homeDirs.some((dir) => fs.existsSync(path.join(home, dir)))) {
return true;
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Custom agent homes get missed

The config-directory fallback ignores supported custom locations. If KIMI_CODE_HOME points to an existing profile and the Kimi binary is outside the desktop's search directories, this checks only ~/.kimi-code and skips Kimi's hook setup. The existing writer correctly uses KIMI_CODE_HOME.

Resolve the same effective config paths here. The same mismatch affects OMP_CODING_AGENT_DIR and the XDG_CONFIG_HOME paths for Devin and Muse.

Prompt To Fix With AI
This is a comment left during a code review.
Path: packages/agent-setup/src/installed-agents.ts
Line: 84-86

Comment:
**Custom agent homes get missed**

The config-directory fallback ignores supported custom locations. If `KIMI_CODE_HOME` points to an existing profile and the Kimi binary is outside the desktop's search directories, this checks only `~/.kimi-code` and skips Kimi's hook setup. The existing writer correctly uses `KIMI_CODE_HOME`.

Resolve the same effective config paths here. The same mismatch affects `OMP_CODING_AGENT_DIR` and the `XDG_CONFIG_HOME` paths for Devin and Muse.

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

9 issues found across 6 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/agent-setup/src/installed-agents.test.ts">

<violation number="1" location="packages/agent-setup/src/installed-agents.test.ts:66">
P2: This test does not verify the “only installed agent” claim for most configured agents. Expand the negative assertions to cover every agent-specific config footprint, otherwise provisioning regressions for Amp, OpenCode, OMP, Pi, MastraCode, Kimi, Vibe, Devin, or Muse can pass unnoticed.</violation>
</file>

<file name="apps/desktop/src/main/index.ts">

<violation number="1" location="apps/desktop/src/main/index.ts:260">
P2: `lastRunAt` starts at app initialization, so it consumes the one-minute cooldown before onboarding has run. If onboarding completes during that minute, the first focus afterward is skipped and a newly installed agent is not picked up until a later focus; initialize the cooldown after an actual provisioning run instead.</violation>
</file>

<file name="packages/agent-setup/src/installed-agents.ts">

<violation number="1" location="packages/agent-setup/src/installed-agents.ts:23">
P2: The shared `.gemini` directory is not Gemini-specific: Antigravity writes its hooks under `~/.gemini/config`, so an Antigravity-only install makes this check provision Gemini anyway. Use an agent-specific config marker or require a Gemini binary before treating that directory as Gemini's footprint.</violation>

<violation number="2" location="packages/agent-setup/src/installed-agents.ts:25">
P2: Resolve Kimi’s effective config home, including `KIMI_CODE_HOME`, instead of checking only `~/.kimi-code`; otherwise an existing custom profile is missed when the binary is outside the searched directories.</violation>

<violation number="3" location="packages/agent-setup/src/installed-agents.ts:29">
P2: The installation fallback ignores `XDG_CONFIG_HOME` for OpenCode, Devin, and Muse, so desktop provisioning skips installed agents whose existing config is under a custom XDG root. Resolve these footprints with the same XDG-aware paths used by their writers.</violation>

<violation number="4" location="packages/agent-setup/src/installed-agents.ts:54">
P2: This filter still treats other Superset workspace wrappers such as `~/.superset-foo/bin/claude` as real installations. The desktop gate will then provision that agent’s global config even though only Superset’s wrapper exists; exclude all Superset wrapper directory variants, not just the current `getBinDir()`.</violation>

<violation number="5" location="packages/agent-setup/src/installed-agents.ts:54">
P2: The wrapper-directory filter compares Windows paths as case-sensitive strings, so a differently cased PATH entry can expose Superset's own wrappers and mark every wrapped agent installed. Compare normalized Windows paths case-insensitively before probing binaries.</violation>

<violation number="6" location="packages/agent-setup/src/installed-agents.ts:63">
P2: `hasBinary` accepts an accessible directory named after the agent as an installed binary. Check `statSync(candidate).isFile()` before `accessSync` so a directory collision does not cause provisioning for an uninstalled agent.</violation>
</file>

<file name="packages/agent-setup/src/agent-setup.ts">

<violation number="1" location="packages/agent-setup/src/agent-setup.ts:252">
P2: Apply the installation filter to Claude plugin provisioning too; `createManagedSkills()` creates `~/.claude` before this per-target check, making the uninstalled agent appear installed and allowing its settings and wrapper to be written.</violation>
</file>
Architecture diagram
sequenceDiagram
    participant DESKTOP as Desktop Main Process
    participant POB as PostOnboardingSetup
    participant API as agent-setup API
    participant CAP as setupAgentCapabilities
    participant CHECK as isAgentInstalled
    participant FS as File System / PATH
    participant AGENTS as Agent Config Dirs

    Note over DESKTOP,AGENTS: Desktop Provisioning Flow (with skipUninstalledAgents)

    DESKTOP->>DESKTOP: window focus event
    DESKTOP->>POB: hasRun()
    alt Not onboarded yet
        POB-->>DESKTOP: false - skip reprovisioning
    else Onboarded
        POB-->>DESKTOP: true
        DESKTOP->>DESKTOP: Check 60s throttle
        DESKTOP->>API: setupAgentIntegrations({skipUninstalledAgents: true})
        API->>API: Create dirs (skills, wrappers, plugins)
        API->>CAP: setupAgentCapabilities(disabled, skipUninstalledAgents)
        
        loop For each agent target
            CAP->>CHECK: isAgentInstalled(agentId)
            CHECK->>FS: Check HOME config dir
            FS-->>CHECK: exists?
            alt Config dir exists
                CHECK-->>CAP: true (installed)
            else No config dir
                CHECK->>FS: Check PATH and binary dirs
                FS-->>CHECK: binary found?
                alt Binary found (not wrapper dir)
                    CHECK-->>CAP: true (installed)
                else No binary found
                    CHECK-->>CAP: false (not installed)
                end
            end

            alt Agent disabled
                CAP->>AGENTS: Run teardown (even if not installed)
            else Agent installed AND not skipped
                CAP->>AGENTS: Run setup (write hooks/settings/plugins)
            else Agent not installed AND skipUninstalledAgents
                CAP->>CAP: Skip - no config dir created
            end
        end

        API->>API: Write zsh/bash wrappers
        API-->>DESKTOP: Provisioning complete
        
        Note over DESKTOP: Managed skills (~/.agents/skills)<br/>always written after onboarding
    end
Loading

Reply with feedback, questions, or to request a fix.

View guided diff | Turn on auto-fix | Re-trigger cubic

expect(fs.existsSync(path.join(home, ".claude", "settings.json"))).toBe(
true,
);
for (const dir of [".codex", ".cursor", ".gemini", ".grok", ".factory"]) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This test does not verify the “only installed agent” claim for most configured agents. Expand the negative assertions to cover every agent-specific config footprint, otherwise provisioning regressions for Amp, OpenCode, OMP, Pi, MastraCode, Kimi, Vibe, Devin, or Muse can pass unnoticed.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At packages/agent-setup/src/installed-agents.test.ts, line 66:

<comment>This test does not verify the “only installed agent” claim for most configured agents. Expand the negative assertions to cover every agent-specific config footprint, otherwise provisioning regressions for Amp, OpenCode, OMP, Pi, MastraCode, Kimi, Vibe, Devin, or Muse can pass unnoticed.</comment>

<file context>
@@ -0,0 +1,70 @@
+		expect(fs.existsSync(path.join(home, ".claude", "settings.json"))).toBe(
+			true,
+		);
+		for (const dir of [".codex", ".cursor", ".gemini", ".grok", ".factory"]) {
+			expect(fs.existsSync(path.join(home, dir))).toBe(false);
+		}
</file context>

const AGENT_REPROVISION_MIN_INTERVAL_MS = 60_000;

function reprovisionAgentIntegrationsOnFocus() {
let lastRunAt = Date.now();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: lastRunAt starts at app initialization, so it consumes the one-minute cooldown before onboarding has run. If onboarding completes during that minute, the first focus afterward is skipped and a newly installed agent is not picked up until a later focus; initialize the cooldown after an actual provisioning run instead.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At apps/desktop/src/main/index.ts, line 260:

<comment>`lastRunAt` starts at app initialization, so it consumes the one-minute cooldown before onboarding has run. If onboarding completes during that minute, the first focus afterward is skipped and a newly installed agent is not picked up until a later focus; initialize the cooldown after an actual provisioning run instead.</comment>

<file context>
@@ -250,6 +250,24 @@ function setupAgentIntegrationsFromSettings() {
+const AGENT_REPROVISION_MIN_INTERVAL_MS = 60_000;
+
+function reprovisionAgentIntegrationsOnFocus() {
+	let lastRunAt = Date.now();
+	app.on("browser-window-focus", () => {
+		if (!postOnboardingSetup.hasRun()) return;
</file context>
Suggested change
let lastRunAt = Date.now();
let lastRunAt = 0;

...fromPath,
...EXTRA_BINARY_DIRS.map((dir) => path.join(home, dir)),
...SYSTEM_BINARY_DIRS,
].filter((dir) => dir && path.resolve(dir) !== wrapperDir);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This filter still treats other Superset workspace wrappers such as ~/.superset-foo/bin/claude as real installations. The desktop gate will then provision that agent’s global config even though only Superset’s wrapper exists; exclude all Superset wrapper directory variants, not just the current getBinDir().

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At packages/agent-setup/src/installed-agents.ts, line 54:

<comment>This filter still treats other Superset workspace wrappers such as `~/.superset-foo/bin/claude` as real installations. The desktop gate will then provision that agent’s global config even though only Superset’s wrapper exists; exclude all Superset wrapper directory variants, not just the current `getBinDir()`.</comment>

<file context>
@@ -0,0 +1,88 @@
+		...fromPath,
+		...EXTRA_BINARY_DIRS.map((dir) => path.join(home, dir)),
+		...SYSTEM_BINARY_DIRS,
+	].filter((dir) => dir && path.resolve(dir) !== wrapperDir);
+}
+
</file context>
Suggested change
].filter((dir) => dir && path.resolve(dir) !== wrapperDir);
]
.filter((dir) => {
const resolved = path.resolve(dir);
const relative = path.relative(home, resolved);
return (
dir &&
resolved !== wrapperDir &&
!/^\\.superset(?:-[^/\\\\]+)?[\\/\\\\]+bin$/.test(relative)
);
});

dirs.some((dir) =>
extensions.some((extension) => {
try {
fs.accessSync(path.join(dir, name + extension), fs.constants.X_OK);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: hasBinary accepts an accessible directory named after the agent as an installed binary. Check statSync(candidate).isFile() before accessSync so a directory collision does not cause provisioning for an uninstalled agent.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At packages/agent-setup/src/installed-agents.ts, line 63:

<comment>`hasBinary` accepts an accessible directory named after the agent as an installed binary. Check `statSync(candidate).isFile()` before `accessSync` so a directory collision does not cause provisioning for an uninstalled agent.</comment>

<file context>
@@ -0,0 +1,88 @@
+		dirs.some((dir) =>
+			extensions.some((extension) => {
+				try {
+					fs.accessSync(path.join(dir, name + extension), fs.constants.X_OK);
+					return true;
+				} catch {
</file context>
Suggested change
fs.accessSync(path.join(dir, name + extension), fs.constants.X_OK);
const candidate = path.join(dir, name + extension);
if (!fs.statSync(candidate).isFile()) return false;
fs.accessSync(candidate, fs.constants.X_OK);

...fromPath,
...EXTRA_BINARY_DIRS.map((dir) => path.join(home, dir)),
...SYSTEM_BINARY_DIRS,
].filter((dir) => dir && path.resolve(dir) !== wrapperDir);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The wrapper-directory filter compares Windows paths as case-sensitive strings, so a differently cased PATH entry can expose Superset's own wrappers and mark every wrapped agent installed. Compare normalized Windows paths case-insensitively before probing binaries.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At packages/agent-setup/src/installed-agents.ts, line 54:

<comment>The wrapper-directory filter compares Windows paths as case-sensitive strings, so a differently cased PATH entry can expose Superset's own wrappers and mark every wrapped agent installed. Compare normalized Windows paths case-insensitively before probing binaries.</comment>

<file context>
@@ -0,0 +1,88 @@
+		...fromPath,
+		...EXTRA_BINARY_DIRS.map((dir) => path.join(home, dir)),
+		...SYSTEM_BINARY_DIRS,
+	].filter((dir) => dir && path.resolve(dir) !== wrapperDir);
+}
+
</file context>

grok: { binaries: ["grok"], homeDirs: [".grok"] },
copilot: { binaries: ["copilot"], homeDirs: [".copilot"] },
vibe: { binaries: ["vibe"], homeDirs: [".vibe"] },
devin: { binaries: ["devin"], homeDirs: [".config/devin"] },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The installation fallback ignores XDG_CONFIG_HOME for OpenCode, Devin, and Muse, so desktop provisioning skips installed agents whose existing config is under a custom XDG root. Resolve these footprints with the same XDG-aware paths used by their writers.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At packages/agent-setup/src/installed-agents.ts, line 29:

<comment>The installation fallback ignores `XDG_CONFIG_HOME` for OpenCode, Devin, and Muse, so desktop provisioning skips installed agents whose existing config is under a custom XDG root. Resolve these footprints with the same XDG-aware paths used by their writers.</comment>

<file context>
@@ -0,0 +1,88 @@
+	grok: { binaries: ["grok"], homeDirs: [".grok"] },
+	copilot: { binaries: ["copilot"], homeDirs: [".copilot"] },
+	vibe: { binaries: ["vibe"], homeDirs: [".vibe"] },
+	devin: { binaries: ["devin"], homeDirs: [".config/devin"] },
+	muse: { binaries: ["muse"], homeDirs: [".config/muse"] },
+	ufo: { binaries: ["ufo"], homeDirs: [] },
</file context>

binaries: ["cursor-agent"],
homeDirs: [".cursor"],
},
gemini: { binaries: ["gemini"], homeDirs: [".gemini"] },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: The shared .gemini directory is not Gemini-specific: Antigravity writes its hooks under ~/.gemini/config, so an Antigravity-only install makes this check provision Gemini anyway. Use an agent-specific config marker or require a Gemini binary before treating that directory as Gemini's footprint.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At packages/agent-setup/src/installed-agents.ts, line 23:

<comment>The shared `.gemini` directory is not Gemini-specific: Antigravity writes its hooks under `~/.gemini/config`, so an Antigravity-only install makes this check provision Gemini anyway. Use an agent-specific config marker or require a Gemini binary before treating that directory as Gemini's footprint.</comment>

<file context>
@@ -0,0 +1,88 @@
+		binaries: ["cursor-agent"],
+		homeDirs: [".cursor"],
+	},
+	gemini: { binaries: ["gemini"], homeDirs: [".gemini"] },
+	mastracode: { binaries: ["mastracode"], homeDirs: [".mastracode"] },
+	kimi: { binaries: ["kimi"], homeDirs: [".kimi-code"] },
</file context>

for (const target of AGENT_SETUP_TARGETS) {
const definition = AGENT_SETUP_DEFINITIONS[target.id];
const isDisabled = disabled.has(target.id);
if (skipUninstalledAgents && !isDisabled && !isInstalled(target.id)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Apply the installation filter to Claude plugin provisioning too; createManagedSkills() creates ~/.claude before this per-target check, making the uninstalled agent appear installed and allowing its settings and wrapper to be written.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At packages/agent-setup/src/agent-setup.ts, line 252:

<comment>Apply the installation filter to Claude plugin provisioning too; `createManagedSkills()` creates `~/.claude` before this per-target check, making the uninstalled agent appear installed and allowing its settings and wrapper to be written.</comment>

<file context>
@@ -239,9 +248,13 @@ export function setupAgentCapabilities({
 	for (const target of AGENT_SETUP_TARGETS) {
 		const definition = AGENT_SETUP_DEFINITIONS[target.id];
+		const isDisabled = disabled.has(target.id);
+		if (skipUninstalledAgents && !isDisabled && !isInstalled(target.id)) {
+			continue;
+		}
</file context>

},
gemini: { binaries: ["gemini"], homeDirs: [".gemini"] },
mastracode: { binaries: ["mastracode"], homeDirs: [".mastracode"] },
kimi: { binaries: ["kimi"], homeDirs: [".kimi-code"] },

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: Resolve Kimi’s effective config home, including KIMI_CODE_HOME, instead of checking only ~/.kimi-code; otherwise an existing custom profile is missed when the binary is outside the searched directories.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At packages/agent-setup/src/installed-agents.ts, line 25:

<comment>Resolve Kimi’s effective config home, including `KIMI_CODE_HOME`, instead of checking only `~/.kimi-code`; otherwise an existing custom profile is missed when the binary is outside the searched directories.</comment>

<file context>
@@ -0,0 +1,88 @@
+	},
+	gemini: { binaries: ["gemini"], homeDirs: [".gemini"] },
+	mastracode: { binaries: ["mastracode"], homeDirs: [".mastracode"] },
+	kimi: { binaries: ["kimi"], homeDirs: [".kimi-code"] },
+	grok: { binaries: ["grok"], homeDirs: [".grok"] },
+	copilot: { binaries: ["copilot"], homeDirs: [".copilot"] },
</file context>

This branch was successfully deployed

1 active deployment
preview — 2c6bcf57 Deployed Nov 1, 2026 by Kitenite via Deploy Database (Neon) #13511
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.

1 participant