mirror of
https://github.com/codeflash-ai/codeflash-internal.git
synced 2026-05-04 18:25:18 +00:00
saga4 misc fixes (#2018)
- **misc fixes [VSC]** - **misc lefthook** # Pull Request Checklist ## Description - [ ] **Description of PR**: Clear and concise description of what this PR accomplishes - [ ] **Breaking Changes**: Document any breaking changes (if applicable) - [ ] **Related Issues**: Link to any related issues or tickets ## Testing - [ ] **Test cases Attached**: All relevant test cases have been added/updated - [ ] **Manual Testing**: Manual testing completed for the changes ## Monitoring & Debugging - [ ] **Logging in place**: Appropriate logging has been added for debugging user issues - [ ] **Sentry will be able to catch errors**: Error handling ensures Sentry can capture and report errors - [ ] **Avoid Dev based/Prisma logging**: No development-only or Prisma-specific logging in production code ## Configuration - [ ] **Env variables newly added**: Any new environment variables are documented in .env.example file or mentioned in description --- ## Additional Notes <!-- Add any additional context, screenshots, or notes for reviewers here -->
This commit is contained in:
parent
2b25fb51ec
commit
761903c2a9
5 changed files with 128 additions and 14 deletions
|
|
@ -63,6 +63,13 @@ const InitForm = ({ suggestions, errorDetails, pyprojectPath }: Props) => {
|
||||||
});
|
});
|
||||||
const renderedOnPurpose = !errorDetails;
|
const renderedOnPurpose = !errorDetails;
|
||||||
|
|
||||||
|
// Helper to get directory name from path
|
||||||
|
const getConfigDirectory = () => {
|
||||||
|
if (!pyprojectPath) return "workspace root";
|
||||||
|
const parts = pyprojectPath.split("/");
|
||||||
|
return parts.length > 1 ? parts.slice(0, -1).join("/") : ".";
|
||||||
|
};
|
||||||
|
|
||||||
const setActiveTab = renderedOnPurpose
|
const setActiveTab = renderedOnPurpose
|
||||||
? useStore((state) => state.setActiveTab)
|
? useStore((state) => state.setActiveTab)
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
@ -315,6 +322,20 @@ const InitForm = ({ suggestions, errorDetails, pyprojectPath }: Props) => {
|
||||||
className={styles.form}
|
className={styles.form}
|
||||||
>
|
>
|
||||||
<h2 className={styles.title}>Project Configuration</h2>
|
<h2 className={styles.title}>Project Configuration</h2>
|
||||||
|
|
||||||
|
{/* Context info section */}
|
||||||
|
<div className={styles.contextInfo}>
|
||||||
|
<div className={styles.contextItem}>
|
||||||
|
<span className="codicon codicon-file"></span>
|
||||||
|
<span>
|
||||||
|
Config file: <code>{pyprojectPath || "pyproject.toml (will be created)"}</code>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div className={styles.helpText}>
|
||||||
|
💡 All paths below are relative to <code>{getConfigDirectory()}</code>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{errorDetails && (
|
{errorDetails && (
|
||||||
<p
|
<p
|
||||||
className={styles.bannerError}
|
className={styles.bannerError}
|
||||||
|
|
@ -332,13 +353,15 @@ style="color: var(--vscode-editorWarning-foreground);"></span>` + errorDetails,
|
||||||
"Module Root",
|
"Module Root",
|
||||||
"Path relative to pyproject.toml where your source code is located.",
|
"Path relative to pyproject.toml where your source code is located.",
|
||||||
true,
|
true,
|
||||||
|
"e.g., src, lib, app, or . for current directory"
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{renderField(
|
{renderField(
|
||||||
"tests_root",
|
"tests_root",
|
||||||
"Tests Root",
|
"Tests Root",
|
||||||
"Path relative to pyproject.toml where your test files are located",
|
"Path relative to pyproject.toml where your test files are located (common: tests, test, __tests__)",
|
||||||
true,
|
true,
|
||||||
|
"e.g., tests, test, or . for current directory"
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{renderField(
|
{renderField(
|
||||||
|
|
@ -374,12 +397,23 @@ style="color: var(--vscode-editorWarning-foreground);"></span>` + errorDetails,
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
>
|
>
|
||||||
{isLoading ? (
|
{isLoading ? (
|
||||||
<span className="codicon codicon-loading spin"></span>
|
<>
|
||||||
|
<span className="codicon codicon-loading spin"></span>
|
||||||
|
{" Saving..."}
|
||||||
|
</>
|
||||||
) : (
|
) : (
|
||||||
"Save Configurations"
|
<>
|
||||||
|
<span className="codicon codicon-save"></span>
|
||||||
|
{" Save & Apply Configuration"}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
{!isLoading && (
|
||||||
|
<div className={styles.actionHelp}>
|
||||||
|
{pyprojectPath ? "This will update" : "This will create"} your pyproject.toml and reload the extension
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -33,6 +33,57 @@
|
||||||
color: var(--vscode-foreground);
|
color: var(--vscode-foreground);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.contextInfo {
|
||||||
|
background: var(--vscode-input-background);
|
||||||
|
border: 1px solid var(--vscode-input-border);
|
||||||
|
border-radius: 4px;
|
||||||
|
padding: 12px;
|
||||||
|
margin: 8px 0 16px 0;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextItem {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--vscode-descriptionForeground);
|
||||||
|
}
|
||||||
|
|
||||||
|
.contextItem code {
|
||||||
|
background: var(--vscode-textCodeBlock-background);
|
||||||
|
padding: 2px 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-family: var(--vscode-editor-font-family);
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--vscode-textPreformat-foreground);
|
||||||
|
}
|
||||||
|
|
||||||
|
.helpText {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--vscode-descriptionForeground);
|
||||||
|
font-style: italic;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.helpText code {
|
||||||
|
background: var(--vscode-textCodeBlock-background);
|
||||||
|
padding: 2px 4px;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-family: var(--vscode-editor-font-family);
|
||||||
|
font-size: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actionHelp {
|
||||||
|
font-size: 11px;
|
||||||
|
color: var(--vscode-descriptionForeground);
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 4px;
|
||||||
|
font-style: italic;
|
||||||
|
}
|
||||||
|
|
||||||
.bannerError {
|
.bannerError {
|
||||||
padding: 1rem 0.5rem;
|
padding: 1rem 0.5rem;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
|
|
|
||||||
|
|
@ -177,17 +177,38 @@ export class BootCodeflashServerStep extends BaseStep {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**When
|
||||||
|
* Safely register a VS Code command with error handling.
|
||||||
|
* If a command already exists (e.g., during extension reload), log a warning
|
||||||
|
* and return a no-op disposable to prevent crashes.
|
||||||
|
*/
|
||||||
|
private safeRegisterCommand = (
|
||||||
|
commandId: string,
|
||||||
|
callback: (...args: any[]) => any,
|
||||||
|
): vscode.Disposable => {
|
||||||
|
try {
|
||||||
|
return vscode.commands.registerCommand(commandId, callback);
|
||||||
|
} catch (error) {
|
||||||
|
// Command already exists - this can happen during extension reload/retry
|
||||||
|
this.logger.warn(
|
||||||
|
`Command '${commandId}' already registered. This is expected during extension reload. Error: ${error}`,
|
||||||
|
);
|
||||||
|
// Return a no-op disposable to maintain the disposal chain
|
||||||
|
return { dispose: () => {} };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
private provideCommands = (
|
private provideCommands = (
|
||||||
sidebarProvider: SidebarProvider,
|
sidebarProvider: SidebarProvider,
|
||||||
commentThreadProvider: CommentThreadProvider,
|
commentThreadProvider: CommentThreadProvider,
|
||||||
) => {
|
) => {
|
||||||
const optimizeFunctionCommand = vscode.commands.registerCommand(
|
const optimizeFunctionCommand = this.safeRegisterCommand(
|
||||||
"codeflash.optimizeFunction",
|
"codeflash.optimizeFunction",
|
||||||
(uri: vscode.Uri, functionName: string) => {
|
(uri: vscode.Uri, functionName: string) => {
|
||||||
sidebarProvider.addFunctionToQueue(functionName, uri, true);
|
sidebarProvider.addFunctionToQueue(functionName, uri, true);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const clearAllTasksCommand = vscode.commands.registerCommand(
|
const clearAllTasksCommand = this.safeRegisterCommand(
|
||||||
"codeflash.clearAllTasks",
|
"codeflash.clearAllTasks",
|
||||||
() => {
|
() => {
|
||||||
const allTasksIds = this.globalState
|
const allTasksIds = this.globalState
|
||||||
|
|
@ -199,7 +220,7 @@ export class BootCodeflashServerStep extends BaseStep {
|
||||||
commentThreadProvider.scheduleRefresh();
|
commentThreadProvider.scheduleRefresh();
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
const optimizeAllCommand = vscode.commands.registerCommand(
|
const optimizeAllCommand = this.safeRegisterCommand(
|
||||||
"codeflash.optimizeAll",
|
"codeflash.optimizeAll",
|
||||||
async () => {
|
async () => {
|
||||||
this.logger.info("Optimizing all functions from command");
|
this.logger.info("Optimizing all functions from command");
|
||||||
|
|
@ -207,7 +228,7 @@ export class BootCodeflashServerStep extends BaseStep {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const viewOptimization = vscode.commands.registerCommand(
|
const viewOptimization = this.safeRegisterCommand(
|
||||||
"codeflash.viewPatch",
|
"codeflash.viewPatch",
|
||||||
async (
|
async (
|
||||||
threadOrPayload:
|
threadOrPayload:
|
||||||
|
|
@ -229,7 +250,7 @@ export class BootCodeflashServerStep extends BaseStep {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const acceptInlineCommentOptimizationCmd = vscode.commands.registerCommand(
|
const acceptInlineCommentOptimizationCmd = this.safeRegisterCommand(
|
||||||
"codeflash.acceptInlineRefactor",
|
"codeflash.acceptInlineRefactor",
|
||||||
async (
|
async (
|
||||||
thread: vscode.CommentThread & {
|
thread: vscode.CommentThread & {
|
||||||
|
|
@ -242,7 +263,7 @@ export class BootCodeflashServerStep extends BaseStep {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const sendMessage = vscode.commands.registerCommand(
|
const sendMessage = this.safeRegisterCommand(
|
||||||
"codeflash.sendMessage",
|
"codeflash.sendMessage",
|
||||||
(message: OutgoingWebviewMessage) => {
|
(message: OutgoingWebviewMessage) => {
|
||||||
sidebarProvider.sendMessage(message);
|
sidebarProvider.sendMessage(message);
|
||||||
|
|
|
||||||
|
|
@ -109,13 +109,22 @@ export class InitService extends Disposable {
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (maxRetries > 0) {
|
if (maxRetries > 0) {
|
||||||
this.logger.error(
|
this.logger.error(
|
||||||
`InitService init error: ${error} (${maxRetries} retries left`,
|
`InitService init error: ${error} (${maxRetries} retries left)`,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Dispose all resources including LSP clients and command registrations
|
||||||
this.dispose();
|
this.dispose();
|
||||||
this._disposables = [];
|
this._disposables = [];
|
||||||
// wait for half a second before retrying
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
// Wait longer (1 second) to ensure VS Code fully unregisters commands and disposes resources
|
||||||
|
// This prevents "command already exists" errors during retry
|
||||||
|
// The delay accounts for:
|
||||||
|
// 1. Async disposal of LSP clients
|
||||||
|
// 2. VS Code's internal command registry cleanup
|
||||||
|
// 3. Event listener teardown
|
||||||
|
this.logger.info("Waiting for cleanup to complete before retry...");
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||||
|
|
||||||
return await this.initWithRetries(maxRetries - 1);
|
return await this.initWithRetries(maxRetries - 1);
|
||||||
} else {
|
} else {
|
||||||
this.logger.error(`InitService init failed: ${error}`);
|
this.logger.error(`InitService init failed: ${error}`);
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,9 @@ pre-commit:
|
||||||
parallel: true
|
parallel: true
|
||||||
commands:
|
commands:
|
||||||
secret-scan:
|
secret-scan:
|
||||||
runner: "node"
|
|
||||||
glob: "*"
|
glob: "*"
|
||||||
exclude: "node_modules/**|venv/**|.venv/**|__pycache__/**|dist/**|build/**"
|
exclude: "node_modules/**|venv/**|.venv/**|__pycache__/**|dist/**|build/**"
|
||||||
command: "./node_modules/.bin/secretlint {staged_files} --maskSecrets --config ./secretlint.config.js"
|
run: "./node_modules/.bin/secretlint {staged_files} --maskSecrets --secretlintrc ./secretlint.config.js"
|
||||||
|
|
||||||
# js-lint:
|
# js-lint:
|
||||||
# runner: "node"
|
# runner: "node"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue