Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions packages/plugin/src/hooks/auto-update-checker/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,44 @@ describe("auto-update-checker/index", () => {
// Even after waiting longer than initDelayMs would be, no check fires
await new Promise((r) => setTimeout(r, 50));
expect(showToast).not.toHaveBeenCalled();
expect(checkerMocks.getLatestVersion).not.toHaveBeenCalled();
});

test("auto_update: false makes no npm request (#854)", async () => {
checkerMocks.findPluginEntry.mockImplementation(() => ({
entry: "@cortexkit/opencode-magic-context",
pinnedVersion: null,
isPinned: false,
configPath: "/config/opencode.jsonc",
}));
checkerMocks.getCachedVersion.mockImplementation(() => "0.15.5");
checkerMocks.getLatestVersion.mockImplementation(async () => "0.15.6");
const { autoUpdateCheckerOptionsFromConfig, createAutoUpdateCheckerHook } =
await freshIndexImport();
const { ctx, showToast } = createCtx();

createAutoUpdateCheckerHook(ctx as Parameters<typeof createAutoUpdateCheckerHook>[0], {
...autoUpdateCheckerOptionsFromConfig(false),
showStartupToast: false,
initDelayMs: 0,
storageDir: makeTempStorageDir(),
});

await new Promise((r) => setTimeout(r, 50));
expect(checkerMocks.getLatestVersion).not.toHaveBeenCalled();
expect(showToast).not.toHaveBeenCalled();
});

test("auto_update unset or true keeps the check enabled", async () => {
const { autoUpdateCheckerOptionsFromConfig } = await freshIndexImport();
expect(autoUpdateCheckerOptionsFromConfig(undefined)).toEqual({
enabled: true,
autoUpdate: true,
});
expect(autoUpdateCheckerOptionsFromConfig(true)).toEqual({
enabled: true,
autoUpdate: true,
});
});

test("on-disk timestamp dedupes concurrent plugin instances", async () => {
Expand Down
12 changes: 12 additions & 0 deletions packages/plugin/src/hooks/auto-update-checker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,18 @@ function warn(message: string): void {
log(`WARN: ${message}`);
}

/**
* Maps the plugin's `auto_update` setting to checker options. `false` turns
* the checker off entirely so no npm request is made, matching the host
* updater's disable behavior.
*/
export function autoUpdateCheckerOptionsFromConfig(
autoUpdateSetting: boolean | undefined,
): Pick<AutoUpdateCheckerOptions, "enabled" | "autoUpdate"> {
const enabled = autoUpdateSetting !== false;
return { enabled, autoUpdate: enabled };
}

/**
* Auto-update checker.
*
Expand Down
8 changes: 6 additions & 2 deletions packages/plugin/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@ import {
} from "./features/magic-context/storage-db";
import { recordToolDefinition } from "./features/magic-context/tool-definition-tokens";
import { runDeferredV22Backfill } from "./features/magic-context/v22-deferred-backfill";
import { createAutoUpdateCheckerHook } from "./hooks/auto-update-checker";
import {
autoUpdateCheckerOptionsFromConfig,
createAutoUpdateCheckerHook,
} from "./hooks/auto-update-checker";
import {
COMPARTMENT_AGENT_SYSTEM_PROMPT,
COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT,
Expand Down Expand Up @@ -881,7 +884,8 @@ const server: Plugin = async (ctx) => {
},
},
autoUpdateChecker: createAutoUpdateCheckerHook(ctx, {
autoUpdate: pluginConfig.auto_update !== false,
// auto_update: false skips the checker entirely: no npm request.
...autoUpdateCheckerOptionsFromConfig(pluginConfig.auto_update),
signal: autoUpdateAbort.signal,
// Multi-project plugin reloads coordinate via this on-disk
// timestamp so npm gets hit at most once per check window
Expand Down
Loading