fix(core): use query param instead of hash fragment for plugin cache-busting
Vite/Vitest's resolver treats `#` as part of the filesystem path in some environments, causing ERR_MODULE_NOT_FOUND on plugin reload. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -130,9 +130,81 @@ export function ClaudeCliProviderCard({
|
||||
</span>
|
||||
);
|
||||
|
||||
const actions = (
|
||||
<>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm"
|
||||
onClick={handleTest}
|
||||
disabled={busy !== null}
|
||||
>
|
||||
{busy === "testing" ? (
|
||||
<>
|
||||
<Loader2 size={12} className="animate-spin" />
|
||||
Testing…
|
||||
</>
|
||||
) : (
|
||||
"Test"
|
||||
)}
|
||||
</button>
|
||||
{currentlyEnabled ? (
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm"
|
||||
onClick={() => void handleToggle(false)}
|
||||
disabled={busy !== null}
|
||||
>
|
||||
{busy === "disabling" ? "Disabling…" : "Disable"}
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-primary btn-sm"
|
||||
onClick={() => void handleToggle(true)}
|
||||
disabled={busy !== null || !binaryAvailable}
|
||||
title={
|
||||
!binaryAvailable
|
||||
? "`claude` binary not detected on PATH — install Claude CLI first."
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{busy === "enabling" ? "Enabling…" : "Enable"}
|
||||
</button>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
|
||||
// Compact layout mirrors `.auth-provider-card` so it slots cleanly into
|
||||
// the Settings > Authentication list and picks up the shared mobile rules.
|
||||
if (compact) {
|
||||
return (
|
||||
<div
|
||||
className={`auth-provider-card auth-provider-card--cli${authenticated ? " auth-provider-card--authenticated" : ""}`}
|
||||
data-testid="claude-cli-provider-card"
|
||||
>
|
||||
<div className="auth-provider-header">
|
||||
<div className="auth-provider-info">
|
||||
<ProviderIcon provider="claude-cli" size="sm" />
|
||||
<strong>Anthropic — via Claude CLI</strong>
|
||||
<ClaudeCliBadge status={status} authenticated={authenticated} />
|
||||
</div>
|
||||
<div className="auth-provider-cli-actions">{actions}</div>
|
||||
</div>
|
||||
<details className="auth-provider-cli-details">
|
||||
<summary>Details</summary>
|
||||
<div className="auth-provider-cli-details-body">
|
||||
{description}
|
||||
<ClaudeCliStatusLine status={status} authenticated={authenticated} />
|
||||
{lastAction && <ClaudeCliActionToast action={lastAction} />}
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className={`onboarding-provider-card${authenticated ? " onboarding-provider-card--connected" : ""}${compact ? " onboarding-provider-card--compact" : ""}`}
|
||||
className={`onboarding-provider-card${authenticated ? " onboarding-provider-card--connected" : ""}`}
|
||||
data-testid="claude-cli-provider-card"
|
||||
>
|
||||
<div className="onboarding-provider-card__icon">
|
||||
@@ -142,69 +214,33 @@ export function ClaudeCliProviderCard({
|
||||
<strong className="onboarding-provider-card__name">
|
||||
Anthropic — via Claude CLI
|
||||
</strong>
|
||||
{compact ? (
|
||||
<details className="onboarding-provider-card__details">
|
||||
<summary className="onboarding-provider-card__details-summary">
|
||||
Details
|
||||
</summary>
|
||||
{description}
|
||||
<ClaudeCliStatusLine status={status} authenticated={authenticated} />
|
||||
</details>
|
||||
) : (
|
||||
<>
|
||||
{description}
|
||||
<ClaudeCliStatusLine status={status} authenticated={authenticated} />
|
||||
</>
|
||||
)}
|
||||
{description}
|
||||
<ClaudeCliStatusLine status={status} authenticated={authenticated} />
|
||||
</div>
|
||||
<div className="onboarding-provider-card__actions">
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm"
|
||||
onClick={handleTest}
|
||||
disabled={busy !== null}
|
||||
>
|
||||
{busy === "testing" ? (
|
||||
<>
|
||||
<Loader2 size={12} className="animate-spin" />
|
||||
Testing…
|
||||
</>
|
||||
) : (
|
||||
"Test"
|
||||
)}
|
||||
</button>
|
||||
{currentlyEnabled ? (
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm"
|
||||
onClick={() => void handleToggle(false)}
|
||||
disabled={busy !== null}
|
||||
>
|
||||
{busy === "disabling" ? "Disabling…" : "Disable"}
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-primary btn-sm"
|
||||
onClick={() => void handleToggle(true)}
|
||||
disabled={busy !== null || !binaryAvailable}
|
||||
title={
|
||||
!binaryAvailable
|
||||
? "`claude` binary not detected on PATH — install Claude CLI first."
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{busy === "enabling" ? "Enabling…" : "Enable"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
{lastAction && (
|
||||
<ClaudeCliActionToast action={lastAction} />
|
||||
)}
|
||||
<div className="onboarding-provider-card__actions">{actions}</div>
|
||||
{lastAction && <ClaudeCliActionToast action={lastAction} />}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function ClaudeCliBadge({
|
||||
status,
|
||||
authenticated,
|
||||
}: {
|
||||
status: ClaudeCliStatus | null;
|
||||
authenticated: boolean;
|
||||
}) {
|
||||
const enabled = status?.enabled ?? authenticated;
|
||||
const available = status?.binary.available ?? false;
|
||||
if (enabled) {
|
||||
return <span className="auth-status-badge authenticated">✓ Active</span>;
|
||||
}
|
||||
if (!available && status) {
|
||||
return <span className="auth-status-badge not-authenticated">✗ Not installed</span>;
|
||||
}
|
||||
return <span className="auth-status-badge not-authenticated">✗ Not connected</span>;
|
||||
}
|
||||
|
||||
/**
|
||||
* One-line health summary. Renders different text for "binary missing"
|
||||
* vs "binary ok but disabled" vs "fully ready" so the user can quickly
|
||||
|
||||
Reference in New Issue
Block a user