Skip to content

Commit a3d51c4

Browse files
lenghuangnang-dev
authored andcommitted
Wait for VSCode Settings Import to finish before proceeding to next step (#250)
* copy over what i have from other branch but without less formatting changes * temp * undo some formatting changes * undo some more formatting * only show skip button after 3 seconds * move idemessenger helper back and tweak skip timer not showing up * check is done on local storage * remove comments * remove prettier ignore changes
1 parent 8afb409 commit a3d51c4

File tree

10 files changed

+167
-130
lines changed

10 files changed

+167
-130
lines changed

core/protocol/ide.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import type {
77
IdeSettings,
88
IndexTag,
99
Location,
10+
PearAuth,
1011
Problem,
1112
Range,
1213
RangeInFile,
1314
Thread,
14-
PearAuth,
1515
} from "../index.js";
1616

1717
export type ToIdeFromWebviewOrCoreProtocol = {
@@ -91,7 +91,7 @@ export type ToIdeFromWebviewOrCoreProtocol = {
9191

9292
// new welcome page
9393
markNewOnboardingComplete: [undefined, void];
94-
importUserSettingsFromVSCode: [undefined, void];
94+
importUserSettingsFromVSCode: [undefined, boolean];
9595
pearWelcomeOpenFolder: [undefined, void];
9696
pearInstallCommandLine: [undefined, void];
9797
installVscodeExtension: [{ extensionId: string }, void];

core/protocol/ideWebview.ts

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
import { AiderState } from "../../extensions/vscode/src/integrations/aider/types/aiderTypes.js";
2-
import { ToolType, Memory, MemoryChange } from "../../extensions/vscode/src/util/integrationUtils.js";
2+
import {
3+
Memory,
4+
MemoryChange,
5+
ToolType,
6+
} from "../../extensions/vscode/src/util/integrationUtils.js";
37
import type { RangeInFileWithContents } from "../commands/util.js";
48
import type { ContextSubmenuItem } from "../index.js";
59
import { ToIdeFromWebviewOrCoreProtocol } from "./ide.js";
@@ -19,17 +23,17 @@ export type ToIdeFromWebviewProtocol = ToIdeFromWebviewOrCoreProtocol & {
1923
openUrl: [string, void];
2024
applyToCurrentFile: [{ text: string }, void];
2125
applyWithRelaceHorizontal: [{ contentToApply: string }, void];
22-
acceptRelaceDiff: [{ originalFileUri: string, diffFileUri: string }, void];
23-
rejectRelaceDiff: [{ originalFileUri: string, diffFileUri: string }, void];
24-
createFile: [{ path: string}, void];
26+
acceptRelaceDiff: [{ originalFileUri: string; diffFileUri: string }, void];
27+
rejectRelaceDiff: [{ originalFileUri: string; diffFileUri: string }, void];
28+
createFile: [{ path: string }, void];
2529
showTutorial: [undefined, void];
2630
showFile: [{ filepath: string }, void];
2731
openConfigJson: [undefined, void];
28-
highlightElement: [{elementSelectors: string[]}, void];
29-
unhighlightElement: [{elementSelectors: string[]}, void];
32+
highlightElement: [{ elementSelectors: string[] }, void];
33+
unhighlightElement: [{ elementSelectors: string[] }, void];
3034
perplexityMode: [undefined, void];
31-
addPerplexityContext: [{text: string, language: string}, void]
32-
addPerplexityContextinChat: [{ text: string, language: string }, void];
35+
addPerplexityContext: [{ text: string; language: string }, void];
36+
addPerplexityContextinChat: [{ text: string; language: string }, void];
3337
aiderMode: [undefined, void];
3438
aiderCtrlC: [undefined, void];
3539
sendAiderProcessStateToGUI: [undefined, void];
@@ -60,7 +64,8 @@ export type ToIdeFromWebviewProtocol = ToIdeFromWebviewOrCoreProtocol & {
6064
completeWelcome: [undefined, void];
6165
openInventoryHome: [undefined, void];
6266
getUrlTitle: [string, string];
63-
pearAIinstallation: [{tools: ToolType[], installExtensions: boolean}, void];
67+
pearAIinstallation: [{ tools: ToolType[] }, void];
68+
importUserSettingsFromVSCode: [undefined, boolean];
6469
"mem0/getMemories": [undefined, Memory[]];
6570
"mem0/updateMemories": [{ changes: MemoryChange[] }, boolean];
6671
};
@@ -93,7 +98,7 @@ export type ToWebviewFromIdeProtocol = ToWebviewFromIdeOrCoreProtocol & {
9398
viewHistory: [undefined, void];
9499
newSession: [undefined, void];
95100
quickEdit: [undefined, void];
96-
acceptedOrRejectedDiff: [undefined, void]
101+
acceptedOrRejectedDiff: [undefined, void];
97102
setTheme: [{ theme: any }, void];
98103
setThemeType: [{ themeType: string }, void];
99104
setColors: [{ [key: string]: string }, void];
@@ -102,8 +107,8 @@ export type ToWebviewFromIdeProtocol = ToWebviewFromIdeOrCoreProtocol & {
102107
setupLocalModel: [undefined, void];
103108
incrementFtc: [undefined, void];
104109
openOnboarding: [undefined, void];
105-
addPerplexityContext: [{text: string, language: string}, void]
106-
addPerplexityContextinChat: [{ text: string, language: string }, void];
110+
addPerplexityContext: [{ text: string; language: string }, void];
111+
addPerplexityContextinChat: [{ text: string; language: string }, void];
107112
navigateToCreator: [undefined, void];
108113
navigateToSearch: [undefined, void];
109114
navigateToMem0: [undefined, void];
@@ -112,5 +117,5 @@ export type ToWebviewFromIdeProtocol = ToWebviewFromIdeOrCoreProtocol & {
112117
navigateToInventoryHome: [undefined, void];
113118
getCurrentTab: [undefined, string];
114119
setAiderProcessStateInGUI: [AiderState, void];
115-
setRelaceDiffState: [{diffVisible: boolean}, void];
120+
setRelaceDiffState: [{ diffVisible: boolean }, void];
116121
};

extensions/vscode/package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,12 @@
182182
"title": "Toggle PearAI Inventory",
183183
"group": "PearAI"
184184
},
185+
{
186+
"command": "pearai.startOnboarding",
187+
"category": "PearAI Developer",
188+
"title": "Start PearAI Onboarding",
189+
"group": "PearAI"
190+
},
185191
{
186192
"command": "pearai.developer.restFirstLaunch",
187193
"category": "PearAI Developer",

extensions/vscode/src/commands.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,17 @@ import {
2222
quickPickStatusText,
2323
setupStatusBar,
2424
} from "./autocomplete/statusBar";
25-
import { ContinueGUIWebviewViewProvider, PEAR_OVERLAY_VIEW_ID } from "./ContinueGUIWebviewViewProvider";
25+
import { ContinueGUIWebviewViewProvider, PEAR_CONTINUE_VIEW_ID, PEAR_OVERLAY_VIEW_ID } from "./ContinueGUIWebviewViewProvider";
26+
import { FIRST_LAUNCH_KEY, importUserSettingsFromVSCode, isFirstLaunch } from "./copySettings";
2627
import { DiffManager } from "./diff/horizontal";
2728
import { VerticalPerLineDiffManager } from "./diff/verticalPerLine/manager";
29+
import { aiderCtrlC, aiderResetSession, installAider, sendAiderProcessStateToGUI, uninstallAider } from './integrations/aider/aiderUtil';
30+
import { AiderState } from "./integrations/aider/types/aiderTypes";
2831
import { QuickEdit, QuickEditShowParams } from "./quickEdit/QuickEditQuickPick";
2932
import { Battery } from "./util/battery";
30-
import type { VsCodeWebviewProtocol } from "./webviewProtocol";
31-
import { getExtensionUri } from "./util/vscode";
32-
import { aiderCtrlC, aiderResetSession, openAiderPanel, sendAiderProcessStateToGUI, installAider, uninstallAider } from './integrations/aider/aiderUtil';
33-
import { handlePerplexityMode } from "./integrations/perplexity/perplexity";
34-
import { PEAR_CONTINUE_VIEW_ID } from "./ContinueGUIWebviewViewProvider";
3533
import { handleIntegrationShortcutKey } from "./util/integrationUtils";
36-
import { FIRST_LAUNCH_KEY, importUserSettingsFromVSCode, isFirstLaunch } from "./copySettings";
37-
import { attemptInstallExtension } from "./activation/activate";
38-
import { AiderState } from "./integrations/aider/types/aiderTypes";
34+
import { getExtensionUri } from "./util/vscode";
35+
import type { VsCodeWebviewProtocol } from "./webviewProtocol";
3936

4037

4138
let fullScreenPanel: vscode.WebviewPanel | undefined;
@@ -260,9 +257,9 @@ const commandsMap: (
260257
if (!isFirstLaunch(extensionContext)) {
261258
vscode.window.showInformationMessage("Welcome back! User settings import is skipped as this is not the first launch.");
262259
console.dir("Extension launch detected as a subsequent launch. Skipping user settings import.");
263-
return;
260+
return true;
264261
}
265-
await importUserSettingsFromVSCode();
262+
return await importUserSettingsFromVSCode();
266263
},
267264
"pearai.welcome.markNewOnboardingComplete": async () => {
268265
await extensionContext.globalState.update(FIRST_LAUNCH_KEY, true);

extensions/vscode/src/copySettings.ts

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import * as vscode from "vscode";
21
import * as fs from 'fs';
3-
import * as path from 'path';
42
import * as os from 'os';
3+
import * as path from 'path';
4+
import * as vscode from "vscode";
55

66
export const FIRST_LAUNCH_KEY = 'pearai.firstLaunch';
77
const pearAISettingsDir = path.join(os.homedir(), '.pearai');
@@ -46,11 +46,11 @@ async function copyVSCodeSettingsToPearAIDir() {
4646
await fs.promises.mkdir(pearAIDevExtensionsDir, { recursive: true });
4747

4848
const itemsToCopy = ['settings.json', 'keybindings.json', 'snippets', 'sync', 'globalStorage/state.vscdb', 'globalStorage/state.vscdb.backup'];
49-
49+
5050
for (const item of itemsToCopy) {
5151
const source = path.join(vscodeSettingsDir, item);
5252
const destination = path.join(pearAIDevSettingsDir, item);
53-
53+
5454
try {
5555
if (await fs.promises.access(source).then(() => true).catch(() => false)) {
5656
const stats = await fs.promises.lstat(source);
@@ -67,7 +67,7 @@ async function copyVSCodeSettingsToPearAIDir() {
6767

6868
const baseExclusions = new Set([
6969
'pearai.pearai',
70-
'ms-python.vscode-pylance',
70+
'ms-python.vscode-pylance',
7171
'ms-python.python',
7272
'codeium',
7373
'github.copilot',
@@ -81,7 +81,7 @@ async function copyVSCodeSettingsToPearAIDir() {
8181
baseExclusions.add('ms-vscode-remote.remote-ssh');
8282
baseExclusions.add('ms-vscode-remote.remote-ssh-edit');
8383
}
84-
84+
8585
// Add platform specific exclusions
8686
if (process.platform === 'darwin' && process.arch === 'x64') {
8787
baseExclusions.add('ms-python.vscode-pylance');
@@ -96,7 +96,7 @@ async function copyVSCodeSettingsToPearAIDir() {
9696
// Add Linux specific exclusions
9797
// if (process.platform === 'linux') {
9898
// }
99-
99+
100100
await copyDirectoryRecursiveSync(vscodeExtensionsDir, pearAIDevExtensionsDir, Array.from(baseExclusions));
101101
}
102102

@@ -113,15 +113,15 @@ function getVSCodeSettingsDir() {
113113

114114
async function copyDirectoryRecursiveSync(source: string, destination: string, exclusions: string[] = []) {
115115
await fs.promises.mkdir(destination, { recursive: true });
116-
116+
117117
const items = await fs.promises.readdir(source);
118118
for (const item of items) {
119119
const sourcePath = path.join(source, item);
120120
const destinationPath = path.join(destination, item);
121121

122122
const shouldExclude = exclusions.some(exclusion =>
123123
sourcePath.toLowerCase().includes(exclusion.toLowerCase())
124-
124+
125125
);
126126

127127
if (!shouldExclude) {
@@ -138,27 +138,24 @@ async function copyDirectoryRecursiveSync(source: string, destination: string, e
138138

139139
export async function importUserSettingsFromVSCode() {
140140
try {
141-
await new Promise(resolve => setTimeout(resolve, 3000));
142-
143-
vscode.window.showInformationMessage('Copying your current VSCode settings and extensions over to PearAI!');
144-
await copyVSCodeSettingsToPearAIDir();
145-
146-
vscode.window.showInformationMessage(
147-
'Your VSCode settings and extensions have been transferred over to PearAI! You may need to restart your editor for the changes to take effect.',
148-
'Ok'
149-
);
150-
} catch (error) {
141+
await Promise.all([
142+
new Promise((resolve) => setTimeout(resolve, 1000)), // Take at least one second
143+
copyVSCodeSettingsToPearAIDir(),
144+
]);
145+
return true;
146+
} catch (error) {
151147
vscode.window.showErrorMessage(`Failed to copy settings: ${error}`);
148+
return false;
149+
}
152150
}
153-
}
154151

155152
export async function markCreatorOnboardingCompleteFileBased() {
156153
try {
157154
await new Promise(resolve => setTimeout(resolve, 3000));
158-
155+
159156
const flagFile = firstPearAICreatorLaunchFlag;
160157
const productName = 'PearAI Creator';
161-
158+
162159
const exists = await fs.promises.access(flagFile).then(() => true).catch(() => false);
163160
if (!exists) {
164161
await fs.promises.writeFile(flagFile, `This is the first launch flag file for ${productName}`);

extensions/vscode/src/extension/VsCodeMessenger.ts

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Note: This file has been modified significantly from its original contents. New commands have been added, and there has been renaming from Continue to PearAI. pearai-submodule is a fork of Continue (https://github.com/continuedev/continue).
22

33
import { ConfigHandler } from "core/config/ConfigHandler";
4+
import PearAIServer from "core/llm/llms/PearAIServer";
45
import {
56
FromCoreProtocol,
67
FromWebviewProtocol,
@@ -18,22 +19,19 @@ import { getConfigJsonPath } from "core/util/paths";
1819
import * as fs from "node:fs";
1920
import * as path from "node:path";
2021
import * as vscode from "vscode";
22+
import { attemptInstallExtension, attemptUninstallExtension, isVSCodeExtensionInstalled } from "../activation/activate";
2123
import { VerticalPerLineDiffManager } from "../diff/verticalPerLine/manager";
2224
import { VsCodeIde } from "../ideProtocol";
25+
import { checkAiderInstallation } from "../integrations/aider/aiderUtil";
26+
import { getMem0Memories, updateMem0Memories } from "../integrations/mem0/mem0Service";
27+
import { getFastApplyChangesWithRelace } from "../integrations/relace/relace";
2328
import {
2429
getControlPlaneSessionInfo,
2530
WorkOsAuthProvider,
2631
} from "../stubs/WorkOsAuthProvider";
32+
import { extractCodeFromMarkdown, TOOL_COMMANDS, ToolType } from "../util/integrationUtils";
2733
import { getExtensionUri } from "../util/vscode";
2834
import { VsCodeWebviewProtocol } from "../webviewProtocol";
29-
import { attemptInstallExtension, attemptUninstallExtension, isVSCodeExtensionInstalled } from "../activation/activate";
30-
import { checkAiderInstallation } from "../integrations/aider/aiderUtil";
31-
import { getMem0Memories, updateMem0Memories } from "../integrations/mem0/mem0Service";
32-
import { TOOL_COMMANDS, ToolType, extractCodeFromMarkdown } from "../util/integrationUtils";
33-
import PearAIServer from "core/llm/llms/PearAIServer";
34-
import { getFastApplyChangesWithRelace } from "../integrations/relace/relace";
35-
import { RelaceDiffManager } from "../integrations/relace/relaceDiffManager";
36-
import { getMarkdownLanguageTagForFile } from "core/util";
3735

3836
/**
3937
* A shared messenger class between Core and Webview
@@ -106,8 +104,15 @@ export class VsCodeMessenger {
106104
this.onWebview("unlockOverlay", (msg) => {
107105
vscode.commands.executeCommand("pearai.unlockOverlay");
108106
});
109-
this.onWebview("importUserSettingsFromVSCode", (msg) => {
110-
vscode.commands.executeCommand("pearai.welcome.importUserSettingsFromVSCode");
107+
this.onWebview("importUserSettingsFromVSCode", async (msg) => {
108+
try {
109+
return await vscode.commands.executeCommand(
110+
"pearai.welcome.importUserSettingsFromVSCode",
111+
);
112+
} catch (error) {
113+
console.log("importUserSettingsFromVSCode rejectionReason", error);
114+
return false;
115+
}
111116
});
112117
this.onWebview("installVscodeExtension", (msg) => {
113118
attemptInstallExtension(msg.data.extensionId);
@@ -131,7 +136,7 @@ export class VsCodeMessenger {
131136

132137
const memories = await getMem0Memories(PearAIServer._getRepoId());
133138
return memories;
134-
});
139+
});
135140
this.onWebview("mem0/updateMemories", async (msg) => {
136141
const response = await updateMem0Memories(PearAIServer._getRepoId(), msg.data.changes);
137142
return response;
@@ -183,10 +188,7 @@ export class VsCodeMessenger {
183188
vscode.commands.executeCommand("pearai.toggleInventoryHome");
184189
});
185190
this.onWebview("pearAIinstallation", (msg) => {
186-
const { tools, installExtensions } = msg.data;
187-
if (installExtensions) {
188-
vscode.commands.executeCommand("pearai.welcome.importUserSettingsFromVSCode");
189-
}
191+
const { tools } = msg.data;
190192
if (tools) {
191193
tools.forEach((tool: ToolType) => {
192194
const toolCommand = TOOL_COMMANDS[tool];

gui/src/pages/gui.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ function GUI() {
300300
useWebviewListener("restFirstLaunchInGUI", async () => {
301301
setLocalStorage("showTutorialCard", true);
302302
localStorage.removeItem("onboardingSelectedTools");
303-
localStorage.removeItem("importUserSettingsFromVSCode");
304303
dispatch(setShowInteractiveContinueTutorial(true));
305304
});
306305

gui/src/pages/welcome/FinalStep.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
"use client";
22

33
import { Button } from "@/components/ui/button";
4-
import { useContext, useEffect } from "react";
54
import { IdeMessengerContext } from "@/context/IdeMessenger";
65
import { FolderOpen } from "lucide-react";
7-
import { useNavigate } from "react-router-dom";
6+
import { useContext, useEffect } from "react";
87

98
export default function FinalStep({ onNext }: { onNext: () => void }) {
109

11-
const navigate = useNavigate();
1210
const selectedTools = JSON.parse(localStorage.getItem('onboardingSelectedTools'));
13-
const installExtensions = localStorage.getItem('importUserSettingsFromVSCode') === 'true';
1411

1512
const initiateInstallations = () => {
16-
ideMessenger.post("pearAIinstallation", {tools: selectedTools, installExtensions: installExtensions})
13+
ideMessenger.post("pearAIinstallation", {tools: selectedTools});
1714
ideMessenger.post("markNewOnboardingComplete", undefined);
1815
};
1916

0 commit comments

Comments
 (0)