Skip to content

Commit d36d029

Browse files
author
James Mtendamema
committed
feat: add global auto-enable default for backward-compatible workspace indexing
1 parent d3719b4 commit d36d029

23 files changed

Lines changed: 114 additions & 25 deletions

File tree

packages/types/src/vscode-extension-host.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -512,6 +512,7 @@ export interface WebviewMessage {
512512
| "indexingStatusUpdate"
513513
| "indexCleared"
514514
| "toggleWorkspaceIndexing"
515+
| "setAutoEnableDefault"
515516
| "focusPanelRequest"
516517
| "openExternal"
517518
| "filterMarketplaceItems"
@@ -741,6 +742,7 @@ export interface IndexingStatus {
741742
currentItemUnit?: string
742743
workspacePath?: string
743744
workspaceEnabled?: boolean
745+
autoEnableDefault?: boolean
744746
}
745747

746748
export interface IndexingStatusUpdateMessage {

src/core/webview/webviewMessageHandler.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2691,6 +2691,25 @@ export const webviewMessageHandler = async (
26912691
}
26922692
break
26932693
}
2694+
case "setAutoEnableDefault": {
2695+
try {
2696+
const manager = provider.getCurrentWorkspaceCodeIndexManager()
2697+
if (!manager) {
2698+
provider.log("Cannot set auto-enable default: No workspace folder open")
2699+
return
2700+
}
2701+
await manager.setAutoEnableDefault(message.bool ?? true)
2702+
provider.postMessageToWebview({
2703+
type: "indexingStatusUpdate",
2704+
values: manager.getCurrentStatus(),
2705+
})
2706+
} catch (error) {
2707+
provider.log(
2708+
`Error setting auto-enable default: ${error instanceof Error ? error.message : String(error)}`,
2709+
)
2710+
}
2711+
break
2712+
}
26942713
case "clearIndexData": {
26952714
try {
26962715
const manager = provider.getCurrentWorkspaceCodeIndexManager()

src/services/code-index/__tests__/manager.spec.ts

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ describe("CodeIndexManager - handleSettingsChange regression", () => {
9696
CodeIndexManager.disposeAll()
9797

9898
const workspaceStateStore: Record<string, any> = {}
99+
const globalStateStore: Record<string, any> = {}
99100
mockContext = {
100101
subscriptions: [],
101102
workspaceState: {
@@ -104,7 +105,12 @@ describe("CodeIndexManager - handleSettingsChange regression", () => {
104105
workspaceStateStore[key] = value
105106
}),
106107
} as any,
107-
globalState: {} as any,
108+
globalState: {
109+
get: vi.fn((key: string, defaultValue?: any) => globalStateStore[key] ?? defaultValue),
110+
update: vi.fn(async (key: string, value: any) => {
111+
globalStateStore[key] = value
112+
}),
113+
} as any,
108114
extensionUri: {} as any,
109115
extensionPath: testExtensionPath,
110116
asAbsolutePath: vi.fn(),
@@ -228,7 +234,7 @@ describe("CodeIndexManager - handleSettingsChange regression", () => {
228234
;(manager as any)._cacheManager = mockCacheManager
229235

230236
// Simulate an initialized manager by setting the required properties
231-
;(manager as any)._orchestrator = { stopWatcher: vi.fn() }
237+
;(manager as any)._orchestrator = { stopWatcher: vi.fn(), stopIndexing: vi.fn() }
232238
;(manager as any)._searchService = {}
233239

234240
// Verify manager is considered initialized
@@ -462,7 +468,7 @@ describe("CodeIndexManager - handleSettingsChange regression", () => {
462468
})
463469

464470
// Mock orchestrator and search service to simulate initialized state
465-
;(manager as any)._orchestrator = { stopWatcher: vi.fn(), state: "Error" }
471+
;(manager as any)._orchestrator = { stopWatcher: vi.fn(), stopIndexing: vi.fn(), state: "Error" }
466472
;(manager as any)._searchService = {}
467473
;(manager as any)._serviceFactory = {}
468474
})
@@ -592,7 +598,7 @@ describe("CodeIndexManager - handleSettingsChange regression", () => {
592598
// Setup manager with service instances
593599
;(manager as any)._configManager = mockConfigManager
594600
;(manager as any)._serviceFactory = {}
595-
;(manager as any)._orchestrator = { stopWatcher: vi.fn() }
601+
;(manager as any)._orchestrator = { stopWatcher: vi.fn(), stopIndexing: vi.fn() }
596602
;(manager as any)._searchService = {}
597603

598604
// Spy on console.error
@@ -620,6 +626,8 @@ describe("CodeIndexManager - handleSettingsChange regression", () => {
620626

621627
describe("workspace-enabled gating", () => {
622628
it("should not start indexing when workspace is not enabled", async () => {
629+
await manager.setAutoEnableDefault(false)
630+
623631
const mockStateManager = (manager as any)._stateManager
624632
mockStateManager.setSystemState = vi.fn()
625633
mockStateManager.getCurrentStatus = vi.fn().mockReturnValue({
@@ -637,7 +645,9 @@ describe("CodeIndexManager - handleSettingsChange regression", () => {
637645
expect(mockStateManager.setSystemState).not.toHaveBeenCalledWith("Indexing", expect.any(String))
638646
})
639647

640-
it("should include workspaceEnabled in getCurrentStatus", () => {
648+
it("should include workspaceEnabled in getCurrentStatus", async () => {
649+
await manager.setAutoEnableDefault(false)
650+
641651
const mockStateManager = (manager as any)._stateManager
642652
mockStateManager.getCurrentStatus = vi.fn().mockReturnValue({
643653
systemStatus: "Standby",
@@ -652,6 +662,7 @@ describe("CodeIndexManager - handleSettingsChange regression", () => {
652662
})
653663

654664
it("should persist workspace enabled state", async () => {
665+
await manager.setAutoEnableDefault(false)
655666
expect(manager.isWorkspaceEnabled).toBe(false)
656667

657668
await manager.setWorkspaceEnabled(true)
@@ -662,6 +673,8 @@ describe("CodeIndexManager - handleSettingsChange regression", () => {
662673
})
663674

664675
it("should store enablement per folder, not per window", async () => {
676+
await manager.setAutoEnableDefault(false)
677+
665678
// Enable indexing for the current manager's folder
666679
await manager.setWorkspaceEnabled(true)
667680
expect(manager.isWorkspaceEnabled).toBe(true)

src/services/code-index/manager.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,13 +76,26 @@ export class CodeIndexManager {
7676
// --- Public API ---
7777

7878
public get isWorkspaceEnabled(): boolean {
79-
return this.context.workspaceState.get(`codeIndexWorkspaceEnabled:${this.workspacePath}`, false)
79+
const explicit = this.context.workspaceState.get<boolean | undefined>(
80+
`codeIndexWorkspaceEnabled:${this.workspacePath}`,
81+
undefined,
82+
)
83+
if (explicit !== undefined) return explicit
84+
return this.autoEnableDefault
8085
}
8186

8287
public async setWorkspaceEnabled(enabled: boolean): Promise<void> {
8388
await this.context.workspaceState.update(`codeIndexWorkspaceEnabled:${this.workspacePath}`, enabled)
8489
}
8590

91+
public get autoEnableDefault(): boolean {
92+
return this.context.globalState.get("codeIndexAutoEnableDefault", true)
93+
}
94+
95+
public async setAutoEnableDefault(enabled: boolean): Promise<void> {
96+
await this.context.globalState.update("codeIndexAutoEnableDefault", enabled)
97+
}
98+
8699
public get onProgressUpdate() {
87100
return this._stateManager.onProgressUpdate
88101
}
@@ -293,6 +306,7 @@ export class CodeIndexManager {
293306
...status,
294307
workspacePath: this.workspacePath,
295308
workspaceEnabled: this.isWorkspaceEnabled,
309+
autoEnableDefault: this.autoEnableDefault,
296310
}
297311
}
298312

webview-ui/src/components/chat/CodeIndexPopover.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1590,9 +1590,32 @@ export const CodeIndexPopover: React.FC<CodeIndexPopoverProps> = ({
15901590
)}
15911591
</div>
15921592

1593+
{/* Auto-enable default */}
1594+
{currentSettings.codebaseIndexEnabled && (
1595+
<div className="flex items-center gap-2 pt-4 pb-1">
1596+
<input
1597+
type="checkbox"
1598+
id="auto-enable-default-toggle"
1599+
checked={indexingStatus.autoEnableDefault ?? true}
1600+
onChange={(e) =>
1601+
vscode.postMessage({
1602+
type: "setAutoEnableDefault",
1603+
bool: e.target.checked,
1604+
})
1605+
}
1606+
className="accent-vscode-focusBorder"
1607+
/>
1608+
<label
1609+
htmlFor="auto-enable-default-toggle"
1610+
className="text-xs text-vscode-foreground cursor-pointer">
1611+
{t("settings:codeIndex.autoEnableDefaultLabel")}
1612+
</label>
1613+
</div>
1614+
)}
1615+
15931616
{/* Workspace Toggle */}
15941617
{currentSettings.codebaseIndexEnabled && (
1595-
<div className="flex items-center gap-2 pt-4 pb-2">
1618+
<div className="flex items-center gap-2 pt-1 pb-2">
15961619
<input
15971620
type="checkbox"
15981621
id="workspace-indexing-toggle"

webview-ui/src/i18n/locales/ca/settings.json

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/de/settings.json

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/en/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,8 @@
278278
"stopIndexingButton": "Stop Indexing",
279279
"stoppingButton": "Stopping...",
280280
"workspaceToggleLabel": "Enable indexing for this workspace",
281-
"workspaceDisabledMessage": "Indexing is configured but not enabled for this workspace."
281+
"workspaceDisabledMessage": "Indexing is configured but not enabled for this workspace.",
282+
"autoEnableDefaultLabel": "Auto-enable indexing for new workspaces"
282283
},
283284
"autoApprove": {
284285
"description": "Run these actions without asking for permission. Only enable for actions you fully trust and if you understand the security risks.",

webview-ui/src/i18n/locales/es/settings.json

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

webview-ui/src/i18n/locales/fr/settings.json

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)