import { ANTIGRAVITY_DEFAULT_MODEL, ProviderDriverKind, type AntigravitySettings, type ProviderSetupError, type ServerProvider, type ServerProviderModel, type ServerProviderSlashCommand,} from "@t3tools/contracts";import { createModelCapabilities } from "@t3tools/shared/model";import * as DateTime from "effect/DateTime";import * as Effect from "effect/Effect";import * as Option from "effect/Option";import * as Predicate from "effect/Predicate";import * as Result from "effect/Result";import * as Stream from "effect/Stream";import * as SubscriptionRef from "effect/SubscriptionRef";import type * as EffectAcpErrors from "effect-acp/errors";import type * as EffectAcpSchema from "effect-acp/schema"; import type { AcpSessionRuntimeStartResult } from "../acp/AcpSessionRuntime.ts";import { makeManagedServerProvider } from "../makeManagedServerProvider.ts";import { makeManualOnlyProviderMaintenanceCapabilities, type ProviderMaintenanceCapabilities,} from "../providerMaintenance.ts";import { buildServerProvider, isCommandMissingCause, type ServerProviderDraft,} from "../providerSnapshot.ts"; const EMPTY_MODEL_CAPABILITIES = createModelCapabilities({ optionDescriptors: [] });const MAX_WORKSPACE_SNAPSHOTS = 32;const HEALTH_CHECK_TIMEOUT = "90 seconds";const SIGN_IN_MESSAGE = "Sign in with Google to use Antigravity.";const AUTH_UNCHECKED_MESSAGE = "Antigravity is installed. Google account access is not checked yet."; type SessionSetupResult = Pick< AcpSessionRuntimeStartResult["sessionSetupResult"], "configOptions" | "models">; /** Keep the native model IDs, including model-specific thinking levels. */export function buildAntigravityModelsFromSession( setup: SessionSetupResult,): ReadonlyArray<ServerProviderModel> { const config = setup.configOptions?.find( (option) => option.id === "model" || option.category === "model", ); const currentValue = config?.type === "select" ? config.currentValue : setup.models?.currentModelId; const entries = config?.type === "select" ? config.options.flatMap((entry) => ("value" in entry ? [entry] : entry.options)) : config === undefined ? (setup.models?.availableModels.map((model) => ({ value: model.modelId, name: model.name, })) ?? []) : []; const seen = new Set<string>(); return entries.flatMap((entry): ServerProviderModel[] => { if (!entry.value.trim() || seen.has(entry.value)) return []; seen.add(entry.value); return [ { slug: entry.value, name: entry.name.trim() ? entry.name : entry.value, isCustom: false, ...(entry.value === currentValue ? { isDefault: true, aliases: [ANTIGRAVITY_DEFAULT_MODEL] } : {}), capabilities: EMPTY_MODEL_CAPABILITIES, }, ]; });} function nativeCommands( commands: ReadonlyArray<EffectAcpSchema.AvailableCommand>,): ReadonlyArray<ServerProviderSlashCommand> { const seen = new Set<string>(); return commands.flatMap((command): ServerProviderSlashCommand[] => { if (!command.name.trim() || seen.has(command.name)) return []; seen.add(command.name); const description = command.description.trim(); const hint = command.input?.hint.trim(); return [ { name: command.name, ...(description ? { description } : {}), ...(hint ? { input: { hint } } : {}), }, ]; });} function isMissingInstallation(error: EffectAcpErrors.AcpError | ProviderSetupError): boolean { if (error._tag === "AcpSpawnError") { return ( isCommandMissingCause(error.cause) || (Predicate.isObject(error.cause) && error.cause.code === "ENOENT") ); } return ( error._tag === "ProviderSetupError" && error.operation === "resolve" && /not installed|missing|incomplete|does not publish/i.test(error.detail) );} interface AntigravityProviderState { readonly draft: ServerProviderDraft; readonly authRevision: number;} interface AntigravityProviderOptions { readonly stampIdentity: (snapshot: ServerProviderDraft) => Effect.Effect<ServerProvider>; readonly probe: Effect.Effect< EffectAcpSchema.InitializeResponse, EffectAcpErrors.AcpError | ProviderSetupError >; readonly supportsTextGeneration: Effect.Effect<boolean>; readonly maintenanceCapabilities?: ProviderMaintenanceCapabilities; /** Auth type and label published once a session authenticates. */ readonly auth?: { readonly type: string; readonly label: string };} /** Health uses initialize only. Session callbacks supply account-specific metadata. */export const makeAntigravityProvider = Effect.fn("makeAntigravityProvider")(function* ( settings: AntigravitySettings, options: AntigravityProviderOptions,) { const checkedAt = DateTime.formatIso(yield* DateTime.now); const initialDraft = { ...buildServerProvider({ presentation: { displayName: "Antigravity", showInteractionModeToggle: false }, enabled: settings.enabled, checkedAt, models: [], probe: { installed: false, version: null, status: "warning", // The configured method rides along so the registry can tell a saved // account for this method from one left by a previous configuration. auth: { status: "unknown", ...(options.auth ? { type: options.auth.type } : {}) }, message: settings.enabled ? "Checking Antigravity availability." : "Antigravity is disabled in T3 Code settings.", }, }), setup: { canAuthenticate: true, canInstall: true }, supportsConversationRollback: false, supportsTextGeneration: false, workspaceSnapshots: [], } satisfies ServerProviderDraft; const metadata = yield* SubscriptionRef.make<AntigravityProviderState>({ draft: initialDraft, authRevision: 0, }); // Skills the driver discovered on disk per workspace. Session callbacks // rewrite the workspace entry with native commands and must keep these, or // the registry drops the suggestions and never re-reads the workspace. const discoveredSkills = new Map<string, ServerProvider["skills"]>(); const getSnapshot = SubscriptionRef.get(metadata).pipe( Effect.flatMap((state) => options.stampIdentity(state.draft)), ); const checkProvider = Effect.fn("checkAntigravityProvider")(function* () { if (!settings.enabled) return yield* getSnapshot; const before = yield* SubscriptionRef.get(metadata); const result = yield* options.probe.pipe( Effect.timeoutOption(HEALTH_CHECK_TIMEOUT), Effect.result, ); const initialized = Result.isSuccess(result) && Option.isSome(result.success) ? result.success.value : undefined; const failure = Result.isFailure(result) ? result.failure : undefined; const missingInstallation = failure !== undefined && isMissingInstallation(failure); const errorMessage = initialized !== undefined ? undefined : failure?._tag === "ProviderSetupError" ? failure.detail.trim() || "Antigravity could not complete its local health check." : missingInstallation ? "Antigravity is not installed or its executable could not be found." : failure ? "Antigravity could not complete its local health check." : `Antigravity did not respond to its local health check within ${HEALTH_CHECK_TIMEOUT}.`; const supportsTextGeneration = initialized !== undefined ? yield* options.supportsTextGeneration : false; const updatedAt = DateTime.formatIso(yield* DateTime.now); const next = yield* SubscriptionRef.updateAndGet(metadata, (state) => { if (state.authRevision !== before.authRevision) return state; const { message: _previousMessage, ...draft } = state.draft; const authenticated = draft.auth.status === "authenticated"; const message = errorMessage ?? (authenticated ? undefined : draft.auth.status === "unauthenticated" ? SIGN_IN_MESSAGE : AUTH_UNCHECKED_MESSAGE); return { ...state, draft: { ...draft, installed: !missingInstallation, version: initialized?.agentInfo?.version || draft.version, status: errorMessage ? "error" : authenticated ? "ready" : "warning", checkedAt: updatedAt, ...(missingInstallation ? { models: [], slashCommands: [], skills: [], workspaceSnapshots: [], supportsTextGeneration: false, } : {}), ...(initialized !== undefined ? { supportsTextGeneration: supportsTextGeneration && draft.auth.status !== "unauthenticated", } : {}), ...(message ? { message } : {}), }, } satisfies AntigravityProviderState; }); return yield* options.stampIdentity(next.draft); }); const maintenanceCapabilities = options.maintenanceCapabilities ?? makeManualOnlyProviderMaintenanceCapabilities({ provider: ProviderDriverKind.make("antigravity"), packageName: null, }); const managed = yield* makeManagedServerProvider({ resolveMaintenance: () => Effect.succeed(maintenanceCapabilities), getSettings: Effect.succeed(settings), streamSettings: Stream.empty, haveSettingsChanged: () => false, initialSnapshot: () => getSnapshot, checkProvider: checkProvider(), enrichSnapshot: ({ publishSnapshot }) => SubscriptionRef.changes(metadata).pipe( Stream.runForEach((state) => options.stampIdentity(state.draft).pipe(Effect.flatMap(publishSnapshot)), ), ), }); const onSessionStarted = Effect.fn("AntigravityProvider.onSessionStarted")(function* ( started: AcpSessionRuntimeStartResult, cwd?: string, ) { const before = yield* SubscriptionRef.get(metadata); const supportsTextGeneration = yield* options.supportsTextGeneration; const updatedAt = DateTime.formatIso(yield* DateTime.now); yield* SubscriptionRef.update(metadata, (state) => { if ( state.authRevision !== before.authRevision && state.draft.auth.status === "unauthenticated" ) { return state; } const { message: _previousMessage, ...draft } = state.draft; const workspaces = draft.workspaceSnapshots ?? []; const workspace = cwd ? workspaces.find((entry) => entry.cwd === cwd) : undefined; return { authRevision: state.authRevision + 1, draft: { ...draft, installed: true, status: settings.enabled ? "ready" : "disabled", version: started.initializeResult.agentInfo?.version || draft.version, auth: { status: "authenticated", type: options.auth?.type ?? "oauth-personal", label: options.auth?.label ?? "Google account", }, checkedAt: updatedAt, models: buildAntigravityModelsFromSession(started.sessionSetupResult), supportsTextGeneration, ...(cwd ? { workspaceSnapshots: [ ...workspaces.filter((entry) => entry.cwd !== cwd), { cwd, checkedAt: updatedAt, slashCommands: workspace?.slashCommands ?? draft.slashCommands, skills: workspace?.skills ?? discoveredSkills.get(cwd) ?? [], }, ].slice(-MAX_WORKSPACE_SNAPSHOTS), } : {}), }, } satisfies AntigravityProviderState; }); }); const onConfigOptionsUpdated = Effect.fn("AntigravityProvider.onConfigOptionsUpdated")(function* ( configOptions: ReadonlyArray<EffectAcpSchema.SessionConfigOption>, ) { const models = buildAntigravityModelsFromSession({ configOptions }); yield* SubscriptionRef.update(metadata, (state) => { if (state.draft.auth.status !== "authenticated") return state; return { ...state, draft: { ...state.draft, models } }; }); }); const onAvailableCommands = Effect.fn("AntigravityProvider.onAvailableCommands")(function* ( commands: ReadonlyArray<EffectAcpSchema.AvailableCommand>, cwd?: string, ) { const slashCommands = nativeCommands(commands); const updatedAt = DateTime.formatIso(yield* DateTime.now); yield* SubscriptionRef.update(metadata, (state) => { if (state.draft.auth.status === "unauthenticated") return state; return { ...state, draft: { ...state.draft, slashCommands, ...(cwd ? { workspaceSnapshots: [ ...(state.draft.workspaceSnapshots ?? []).filter((entry) => entry.cwd !== cwd), { cwd, checkedAt: updatedAt, slashCommands, skills: state.draft.workspaceSnapshots?.find((entry) => entry.cwd === cwd)?.skills ?? discoveredSkills.get(cwd) ?? [], }, ].slice(-MAX_WORKSPACE_SNAPSHOTS), } : {}), }, }; }); }); const clearAccountMetadata = Effect.fn("AntigravityProvider.clearAccountMetadata")(function* () { const updatedAt = DateTime.formatIso(yield* DateTime.now); yield* SubscriptionRef.update( metadata, (state) => ({ authRevision: state.authRevision + 1, draft: { ...state.draft, auth: { status: "unauthenticated" }, status: settings.enabled ? "warning" : "disabled", message: SIGN_IN_MESSAGE, checkedAt: updatedAt, models: [], slashCommands: [], skills: [], workspaceSnapshots: [], supportsTextGeneration: false, }, }) satisfies AntigravityProviderState, ); discoveredSkills.clear(); }); const snapshotForCwd = Effect.fn("AntigravityProvider.snapshotForCwd")(function* ( cwd: string, skills?: ServerProvider["skills"], ) { if (skills) discoveredSkills.set(cwd, skills); const snapshot = yield* getSnapshot; const workspace = snapshot.workspaceSnapshots?.find((entry) => entry.cwd === cwd); const resolvedSkills = skills ?? workspace?.skills ?? discoveredSkills.get(cwd) ?? []; return workspace ? { ...snapshot, slashCommands: workspace.slashCommands, skills: resolvedSkills } : { ...snapshot, skills: resolvedSkills }; }); return { snapshot: { ...managed, getSnapshot }, onSessionStarted, onConfigOptionsUpdated, onAvailableCommands, onSignedOut: clearAccountMetadata(), onAuthRequired: clearAccountMetadata(), snapshotForCwd, };});
import {
ANTIGRAVITY_DEFAULT_MODEL,
ProviderDriverKind,
type AntigravitySettings,
type ProviderSetupError,
type ServerProvider,
type ServerProviderModel,
type ServerProviderSlashCommand,
} from "@t3tools/contracts";
import { createModelCapabilities } from "@t3tools/shared/model";
import * as DateTime from "effect/DateTime";
import * as Effect from "effect/Effect";
import * as Option from "effect/Option";
import * as Predicate from "effect/Predicate";
import * as Result from "effect/Result";
import * as Stream from "effect/Stream";
import * as SubscriptionRef from "effect/SubscriptionRef";
import type * as EffectAcpErrors from "effect-acp/errors";
import type * as EffectAcpSchema from "effect-acp/schema";
import type { AcpSessionRuntimeStartResult } from "../acp/AcpSessionRuntime.ts";
import { makeManagedServerProvider } from "../makeManagedServerProvider.ts";
import {
makeManualOnlyProviderMaintenanceCapabilities,
type ProviderMaintenanceCapabilities,
} from "../providerMaintenance.ts";
import {
buildServerProvider,
isCommandMissingCause,
type ServerProviderDraft,
} from "../providerSnapshot.ts";
const EMPTY_MODEL_CAPABILITIES = createModelCapabilities({ optionDescriptors: [] });
const MAX_WORKSPACE_SNAPSHOTS = 32;
const HEALTH_CHECK_TIMEOUT = "90 seconds";
const SIGN_IN_MESSAGE = "Sign in with Google to use Antigravity.";
const AUTH_UNCHECKED_MESSAGE =
"Antigravity is installed. Google account access is not checked yet.";
type SessionSetupResult = Pick<
AcpSessionRuntimeStartResult["sessionSetupResult"],
"configOptions" | "models"
>;
/** Keep the native model IDs, including model-specific thinking levels. */
export function buildAntigravityModelsFromSession(
setup: SessionSetupResult,
): ReadonlyArray<ServerProviderModel> {
const config = setup.configOptions?.find(
(option) => option.id === "model" || option.category === "model",
);
const currentValue =
config?.type === "select" ? config.currentValue : setup.models?.currentModelId;
const entries =
config?.type === "select"
? config.options.flatMap((entry) => ("value" in entry ? [entry] : entry.options))
: config === undefined
? (setup.models?.availableModels.map((model) => ({
value: model.modelId,
name: model.name,
})) ?? [])
: [];
const seen = new Set<string>();
return entries.flatMap((entry): ServerProviderModel[] => {
if (!entry.value.trim() || seen.has(entry.value)) return [];
seen.add(entry.value);
return [
{
slug: entry.value,
name: entry.name.trim() ? entry.name : entry.value,
isCustom: false,
...(entry.value === currentValue
? { isDefault: true, aliases: [ANTIGRAVITY_DEFAULT_MODEL] }
: {}),
capabilities: EMPTY_MODEL_CAPABILITIES,
},
];
});
}
function nativeCommands(
commands: ReadonlyArray<EffectAcpSchema.AvailableCommand>,
): ReadonlyArray<ServerProviderSlashCommand> {
const seen = new Set<string>();
return commands.flatMap((command): ServerProviderSlashCommand[] => {
if (!command.name.trim() || seen.has(command.name)) return [];
seen.add(command.name);
const description = command.description.trim();
const hint = command.input?.hint.trim();
return [
{
name: command.name,
...(description ? { description } : {}),
...(hint ? { input: { hint } } : {}),
},
];
});
}
function isMissingInstallation(error: EffectAcpErrors.AcpError | ProviderSetupError): boolean {
if (error._tag === "AcpSpawnError") {
return (
isCommandMissingCause(error.cause) ||
(Predicate.isObject(error.cause) && error.cause.code === "ENOENT")
);
}
return (
error._tag === "ProviderSetupError" &&
error.operation === "resolve" &&
/not installed|missing|incomplete|does not publish/i.test(error.detail)
);
}
interface AntigravityProviderState {
readonly draft: ServerProviderDraft;
readonly authRevision: number;
}
interface AntigravityProviderOptions {
readonly stampIdentity: (snapshot: ServerProviderDraft) => Effect.Effect<ServerProvider>;
readonly probe: Effect.Effect<
EffectAcpSchema.InitializeResponse,
EffectAcpErrors.AcpError | ProviderSetupError
>;
readonly supportsTextGeneration: Effect.Effect<boolean>;
readonly maintenanceCapabilities?: ProviderMaintenanceCapabilities;
/** Auth type and label published once a session authenticates. */
readonly auth?: { readonly type: string; readonly label: string };
}
/** Health uses initialize only. Session callbacks supply account-specific metadata. */
export const makeAntigravityProvider = Effect.fn("makeAntigravityProvider")(function* (
settings: AntigravitySettings,
options: AntigravityProviderOptions,
) {
const checkedAt = DateTime.formatIso(yield* DateTime.now);
const initialDraft = {
...buildServerProvider({
presentation: { displayName: "Antigravity", showInteractionModeToggle: false },
enabled: settings.enabled,
checkedAt,
models: [],
probe: {
installed: false,
version: null,
status: "warning",
// The configured method rides along so the registry can tell a saved
// account for this method from one left by a previous configuration.
auth: { status: "unknown", ...(options.auth ? { type: options.auth.type } : {}) },
message: settings.enabled
? "Checking Antigravity availability."
: "Antigravity is disabled in T3 Code settings.",
},
}),
setup: { canAuthenticate: true, canInstall: true },
supportsConversationRollback: false,
supportsTextGeneration: false,
workspaceSnapshots: [],
} satisfies ServerProviderDraft;
const metadata = yield* SubscriptionRef.make<AntigravityProviderState>({
draft: initialDraft,
authRevision: 0,
});
// Skills the driver discovered on disk per workspace. Session callbacks
// rewrite the workspace entry with native commands and must keep these, or
// the registry drops the suggestions and never re-reads the workspace.
const discoveredSkills = new Map<string, ServerProvider["skills"]>();
const getSnapshot = SubscriptionRef.get(metadata).pipe(
Effect.flatMap((state) => options.stampIdentity(state.draft)),
);
const checkProvider = Effect.fn("checkAntigravityProvider")(function* () {
if (!settings.enabled) return yield* getSnapshot;
const before = yield* SubscriptionRef.get(metadata);
const result = yield* options.probe.pipe(
Effect.timeoutOption(HEALTH_CHECK_TIMEOUT),
Effect.result,
);
const initialized =
Result.isSuccess(result) && Option.isSome(result.success) ? result.success.value : undefined;
const failure = Result.isFailure(result) ? result.failure : undefined;
const missingInstallation = failure !== undefined && isMissingInstallation(failure);
const errorMessage =
initialized !== undefined
? undefined
: failure?._tag === "ProviderSetupError"
? failure.detail.trim() || "Antigravity could not complete its local health check."
: missingInstallation
? "Antigravity is not installed or its executable could not be found."
: failure
? "Antigravity could not complete its local health check."
: `Antigravity did not respond to its local health check within ${HEALTH_CHECK_TIMEOUT}.`;
const supportsTextGeneration =
initialized !== undefined ? yield* options.supportsTextGeneration : false;
const updatedAt = DateTime.formatIso(yield* DateTime.now);
const next = yield* SubscriptionRef.updateAndGet(metadata, (state) => {
if (state.authRevision !== before.authRevision) return state;
const { message: _previousMessage, ...draft } = state.draft;
const authenticated = draft.auth.status === "authenticated";
const message =
errorMessage ??
(authenticated
? undefined
: draft.auth.status === "unauthenticated"
? SIGN_IN_MESSAGE
: AUTH_UNCHECKED_MESSAGE);
return {
...state,
draft: {
...draft,
installed: !missingInstallation,
version: initialized?.agentInfo?.version || draft.version,
status: errorMessage ? "error" : authenticated ? "ready" : "warning",
checkedAt: updatedAt,
...(missingInstallation
? {
models: [],
slashCommands: [],
skills: [],
workspaceSnapshots: [],
supportsTextGeneration: false,
}
: {}),
...(initialized !== undefined
? {
supportsTextGeneration:
supportsTextGeneration && draft.auth.status !== "unauthenticated",
}
: {}),
...(message ? { message } : {}),
},
} satisfies AntigravityProviderState;
});
return yield* options.stampIdentity(next.draft);
});
const maintenanceCapabilities =
options.maintenanceCapabilities ??
makeManualOnlyProviderMaintenanceCapabilities({
provider: ProviderDriverKind.make("antigravity"),
packageName: null,
});
const managed = yield* makeManagedServerProvider({
resolveMaintenance: () => Effect.succeed(maintenanceCapabilities),
getSettings: Effect.succeed(settings),
streamSettings: Stream.empty,
haveSettingsChanged: () => false,
initialSnapshot: () => getSnapshot,
checkProvider: checkProvider(),
enrichSnapshot: ({ publishSnapshot }) =>
SubscriptionRef.changes(metadata).pipe(
Stream.runForEach((state) =>
options.stampIdentity(state.draft).pipe(Effect.flatMap(publishSnapshot)),
),
),
});
const onSessionStarted = Effect.fn("AntigravityProvider.onSessionStarted")(function* (
started: AcpSessionRuntimeStartResult,
cwd?: string,
) {
const before = yield* SubscriptionRef.get(metadata);
const supportsTextGeneration = yield* options.supportsTextGeneration;
const updatedAt = DateTime.formatIso(yield* DateTime.now);
yield* SubscriptionRef.update(metadata, (state) => {
if (
state.authRevision !== before.authRevision &&
state.draft.auth.status === "unauthenticated"
) {
return state;
}
const { message: _previousMessage, ...draft } = state.draft;
const workspaces = draft.workspaceSnapshots ?? [];
const workspace = cwd ? workspaces.find((entry) => entry.cwd === cwd) : undefined;
return {
authRevision: state.authRevision + 1,
draft: {
...draft,
installed: true,
status: settings.enabled ? "ready" : "disabled",
version: started.initializeResult.agentInfo?.version || draft.version,
auth: {
status: "authenticated",
type: options.auth?.type ?? "oauth-personal",
label: options.auth?.label ?? "Google account",
},
checkedAt: updatedAt,
models: buildAntigravityModelsFromSession(started.sessionSetupResult),
supportsTextGeneration,
...(cwd
? {
workspaceSnapshots: [
...workspaces.filter((entry) => entry.cwd !== cwd),
{
cwd,
checkedAt: updatedAt,
slashCommands: workspace?.slashCommands ?? draft.slashCommands,
skills: workspace?.skills ?? discoveredSkills.get(cwd) ?? [],
},
].slice(-MAX_WORKSPACE_SNAPSHOTS),
}
: {}),
},
} satisfies AntigravityProviderState;
});
});
const onConfigOptionsUpdated = Effect.fn("AntigravityProvider.onConfigOptionsUpdated")(function* (
configOptions: ReadonlyArray<EffectAcpSchema.SessionConfigOption>,
) {
const models = buildAntigravityModelsFromSession({ configOptions });
yield* SubscriptionRef.update(metadata, (state) => {
if (state.draft.auth.status !== "authenticated") return state;
return { ...state, draft: { ...state.draft, models } };
});
});
const onAvailableCommands = Effect.fn("AntigravityProvider.onAvailableCommands")(function* (
commands: ReadonlyArray<EffectAcpSchema.AvailableCommand>,
cwd?: string,
) {
const slashCommands = nativeCommands(commands);
const updatedAt = DateTime.formatIso(yield* DateTime.now);
yield* SubscriptionRef.update(metadata, (state) => {
if (state.draft.auth.status === "unauthenticated") return state;
return {
...state,
draft: {
...state.draft,
slashCommands,
...(cwd
? {
workspaceSnapshots: [
...(state.draft.workspaceSnapshots ?? []).filter((entry) => entry.cwd !== cwd),
{
cwd,
checkedAt: updatedAt,
slashCommands,
skills:
state.draft.workspaceSnapshots?.find((entry) => entry.cwd === cwd)?.skills ??
discoveredSkills.get(cwd) ??
[],
},
].slice(-MAX_WORKSPACE_SNAPSHOTS),
}
: {}),
},
};
});
});
const clearAccountMetadata = Effect.fn("AntigravityProvider.clearAccountMetadata")(function* () {
const updatedAt = DateTime.formatIso(yield* DateTime.now);
yield* SubscriptionRef.update(
metadata,
(state) =>
({
authRevision: state.authRevision + 1,
draft: {
...state.draft,
auth: { status: "unauthenticated" },
status: settings.enabled ? "warning" : "disabled",
message: SIGN_IN_MESSAGE,
checkedAt: updatedAt,
models: [],
slashCommands: [],
skills: [],
workspaceSnapshots: [],
supportsTextGeneration: false,
},
}) satisfies AntigravityProviderState,
);
discoveredSkills.clear();
});
const snapshotForCwd = Effect.fn("AntigravityProvider.snapshotForCwd")(function* (
cwd: string,
skills?: ServerProvider["skills"],
) {
if (skills) discoveredSkills.set(cwd, skills);
const snapshot = yield* getSnapshot;
const workspace = snapshot.workspaceSnapshots?.find((entry) => entry.cwd === cwd);
const resolvedSkills = skills ?? workspace?.skills ?? discoveredSkills.get(cwd) ?? [];
return workspace
? { ...snapshot, slashCommands: workspace.slashCommands, skills: resolvedSkills }
: { ...snapshot, skills: resolvedSkills };
});
return {
snapshot: { ...managed, getSnapshot },
onSessionStarted,
onConfigOptionsUpdated,
onAvailableCommands,
onSignedOut: clearAccountMetadata(),
onAuthRequired: clearAccountMetadata(),
snapshotForCwd,
};
});