Skip to content

Commit 09c2bec

Browse files
Merge pull request #307 from olasunkanmi-SE/feature_enhancement
Feature enhancement
2 parents dc6f116 + f44d543 commit 09c2bec

File tree

22 files changed

+1337
-286
lines changed

22 files changed

+1337
-286
lines changed

package.json

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,57 @@
479479
"default": 16,
480480
"description": "Enter your preferred font size (default is 16)"
481481
},
482+
"codebuddy.enableStreaming": {
483+
"type": "boolean",
484+
"default": true,
485+
"description": "Enable streaming responses from AI models"
486+
},
487+
"codebuddy.nickname": {
488+
"type": "string",
489+
"default": "",
490+
"description": "Your display name shown in chat conversations"
491+
},
492+
"codebuddy.autoApprove": {
493+
"type": "boolean",
494+
"default": false,
495+
"description": "Automatically approve agent actions without confirmation"
496+
},
497+
"codebuddy.allowFileEdits": {
498+
"type": "boolean",
499+
"default": true,
500+
"description": "Allow the agent to create, modify, and delete files"
501+
},
502+
"codebuddy.allowTerminal": {
503+
"type": "boolean",
504+
"default": true,
505+
"description": "Allow the agent to execute terminal commands"
506+
},
507+
"codebuddy.verboseLogging": {
508+
"type": "boolean",
509+
"default": false,
510+
"description": "Show detailed agent activity logs for debugging"
511+
},
512+
"codebuddy.indexCodebase": {
513+
"type": "boolean",
514+
"default": false,
515+
"description": "Enable vector database indexing for semantic code search"
516+
},
517+
"codebuddy.contextWindow": {
518+
"type": "string",
519+
"enum": ["4k", "8k", "16k", "32k", "128k"],
520+
"default": "16k",
521+
"description": "Maximum context window size for AI requests"
522+
},
523+
"codebuddy.includeHidden": {
524+
"type": "boolean",
525+
"default": false,
526+
"description": "Include hidden files (starting with .) in context gathering"
527+
},
528+
"codebuddy.maxFileSize": {
529+
"type": "string",
530+
"default": "1",
531+
"description": "Maximum file size in MB for context gathering"
532+
},
482533
"codebuddy.completion.enabled": {
483534
"type": "boolean",
484535
"default": true,

src/extension.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import { DeveloperAgent } from "./agents/developer/agent";
5656
import { AgentRunningGuardService } from "./services/agent-running-guard.service";
5757

5858
import { DiffReviewService } from "./services/diff-review.service";
59+
import { SecretStorageService } from "./services/secret-storage";
5960

6061
const logger = Logger.initialize("extension-main", {
6162
minLevel: LogLevel.DEBUG,
@@ -219,6 +220,10 @@ export async function activate(context: vscode.ExtensionContext) {
219220
// Start Scheduler Service
220221
SchedulerService.getInstance().start();
221222

223+
// Initialize Secret Storage Service for user preferences
224+
const secretStorageService = new SecretStorageService(context);
225+
context.subscriptions.push(secretStorageService);
226+
222227
// Initialize ContextRetriever for semantic search
223228
const contextRetriever = ContextRetriever.initialize(context);
224229

src/services/news.service.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,4 +103,22 @@ export class NewsService {
103103
ids,
104104
);
105105
}
106+
107+
public async cleanupOldNews(retentionDays: number): Promise<void> {
108+
await this.ensureInitialized();
109+
const cutoffDate = new Date();
110+
cutoffDate.setDate(cutoffDate.getDate() - retentionDays);
111+
const cutoffISO = cutoffDate.toISOString();
112+
113+
this.logger.info(
114+
`Cleaning up news older than ${retentionDays} days (before ${cutoffISO})...`,
115+
);
116+
117+
const result = this.dbService.executeSqlCommand(
118+
`DELETE FROM news_items WHERE fetched_at < ?`,
119+
[cutoffISO],
120+
);
121+
122+
this.logger.info(`Deleted ${result.changes} old news items.`);
123+
}
106124
}

src/services/scheduler.service.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,30 +60,40 @@ export class SchedulerService {
6060
// First time running, create the task entry
6161
this.dbService.executeSqlCommand(
6262
`INSERT INTO scheduled_tasks (name, cron_expression, command, status)
63-
VALUES ('daily_news', '0 9 * * *', 'news:fetch', 'active')`,
63+
VALUES ('daily_news', '0 10 * * *', 'news:fetch', 'active')`,
6464
);
65-
shouldRun = true;
65+
// Only run if it's past 10 AM
66+
if (now.getHours() >= 10) {
67+
shouldRun = true;
68+
}
6669
} else {
6770
const lastRun = lastRunResults[0].last_run
6871
? new Date(lastRunResults[0].last_run)
6972
: null;
7073
if (!lastRun) {
71-
shouldRun = true;
74+
if (now.getHours() >= 10) {
75+
shouldRun = true;
76+
}
7277
} else {
7378
// Check if last run was on a previous day
7479
if (
7580
lastRun.getDate() !== now.getDate() ||
7681
lastRun.getMonth() !== now.getMonth() ||
7782
lastRun.getFullYear() !== now.getFullYear()
7883
) {
79-
shouldRun = true;
84+
// Only run if it's past 10 AM
85+
if (now.getHours() >= 10) {
86+
shouldRun = true;
87+
}
8088
}
8189
}
8290
}
8391

8492
if (shouldRun) {
8593
this.logger.info("Executing scheduled task: daily_news");
86-
await NewsService.getInstance().fetchAndStoreNews();
94+
const newsService = NewsService.getInstance();
95+
await newsService.fetchAndStoreNews();
96+
await newsService.cleanupOldNews(7);
8797

8898
// Update last_run
8999
this.dbService.executeSqlCommand(

src/services/secret-storage.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,40 @@ export class SecretStorageService implements vscode.Disposable {
6868
async publishPreferences() {
6969
const username = await this.get("codebuddy-username");
7070
const theme = await this.get("codebuddy-theme");
71+
const config = vscode.workspace.getConfiguration();
72+
const fontFamily = config.get<string>("font.family") || "JetBrains Mono";
73+
const fontSize = config.get<number>("chatview.font.size") || 16;
74+
const enableStreaming =
75+
config.get<boolean>("codebuddy.enableStreaming") ?? true;
76+
const nickname = config.get<string>("codebuddy.nickname") || username || "";
77+
const autoApprove = config.get<boolean>("codebuddy.autoApprove") ?? false;
78+
const allowFileEdits =
79+
config.get<boolean>("codebuddy.allowFileEdits") ?? true;
80+
const allowTerminal =
81+
config.get<boolean>("codebuddy.allowTerminal") ?? true;
82+
const verboseLogging =
83+
config.get<boolean>("codebuddy.verboseLogging") ?? false;
84+
const indexCodebase =
85+
config.get<boolean>("codebuddy.indexCodebase") ?? false;
86+
const contextWindow =
87+
config.get<string>("codebuddy.contextWindow") || "16k";
88+
const includeHidden =
89+
config.get<boolean>("codebuddy.includeHidden") ?? false;
90+
const maxFileSize = config.get<string>("codebuddy.maxFileSize") || "1";
7191
const preferences = {
72-
username,
92+
username: nickname || username,
7393
theme: theme || "tokyo night", // default theme
94+
fontFamily,
95+
fontSize,
96+
enableStreaming,
97+
autoApprove,
98+
allowFileEdits,
99+
allowTerminal,
100+
verboseLogging,
101+
indexCodebase,
102+
contextWindow,
103+
includeHidden,
104+
maxFileSize,
74105
};
75106
this.orchestrator.publish(
76107
"onGetUserPreferences",

src/webview-providers/base.ts

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -745,12 +745,21 @@ export abstract class BaseWebViewProvider implements vscode.Disposable {
745745
const { ids } = message;
746746
if (ids && Array.isArray(ids)) {
747747
await NewsService.getInstance().markAsRead(ids);
748+
await this.synchronizeNews();
748749
}
749750
break;
750751
}
752+
case "news-refresh":
753+
await this.synchronizeNews();
754+
break;
751755
case "upload-file":
752756
await this.fileManager.uploadFileHandler();
753757
break;
758+
case "openExternal":
759+
if (message.text) {
760+
vscode.env.openExternal(vscode.Uri.parse(message.text));
761+
}
762+
break;
754763
case "update-model-event":
755764
await this.orchestrator.publish("onModelChange", message);
756765
break;
@@ -761,6 +770,11 @@ export abstract class BaseWebViewProvider implements vscode.Disposable {
761770
case "clear-history":
762771
await this.chatHistoryManager.clearHistory("agentId");
763772
this.orchestrator.publish("onClearHistory", message);
773+
// Notify webview that history has been cleared
774+
this.currentWebView?.webview.postMessage({
775+
command: "history-cleared",
776+
});
777+
this.logger.info("Chat history cleared");
764778
break;
765779
case "update-user-info":
766780
// In the future update to updateUserPreferences
@@ -778,6 +792,162 @@ export abstract class BaseWebViewProvider implements vscode.Disposable {
778792
);
779793
break;
780794

795+
case "font-family-change-event":
796+
// Handle font family change and update VS Code settings
797+
this.logger.info(`Font family changed to: ${message.message}`);
798+
await vscode.workspace
799+
.getConfiguration()
800+
.update(
801+
"font.family",
802+
message.message,
803+
vscode.ConfigurationTarget.Global,
804+
);
805+
break;
806+
807+
case "font-size-change-event":
808+
// Handle font size change and update VS Code settings
809+
this.logger.info(`Font size changed to: ${message.message}`);
810+
await vscode.workspace
811+
.getConfiguration()
812+
.update(
813+
"chatview.font.size",
814+
message.message,
815+
vscode.ConfigurationTarget.Global,
816+
);
817+
break;
818+
819+
case "nickname-change-event":
820+
// Handle nickname change and store in secret storage
821+
this.logger.info(`Nickname changed to: ${message.message}`);
822+
this.orchestrator.publish("onUpdateUserPreferences", {
823+
message: JSON.stringify({ username: message.message }),
824+
});
825+
break;
826+
827+
case "streaming-change-event":
828+
// Handle streaming preference change
829+
this.logger.info(
830+
`Streaming preference changed to: ${message.message}`,
831+
);
832+
await vscode.workspace
833+
.getConfiguration()
834+
.update(
835+
"codebuddy.enableStreaming",
836+
message.message,
837+
vscode.ConfigurationTarget.Global,
838+
);
839+
break;
840+
841+
case "auto-approve-change-event":
842+
this.logger.info(
843+
`Auto-approve preference changed to: ${message.message}`,
844+
);
845+
await vscode.workspace
846+
.getConfiguration()
847+
.update(
848+
"codebuddy.autoApprove",
849+
message.message,
850+
vscode.ConfigurationTarget.Global,
851+
);
852+
break;
853+
854+
case "allow-file-edits-change-event":
855+
this.logger.info(
856+
`Allow file edits preference changed to: ${message.message}`,
857+
);
858+
await vscode.workspace
859+
.getConfiguration()
860+
.update(
861+
"codebuddy.allowFileEdits",
862+
message.message,
863+
vscode.ConfigurationTarget.Global,
864+
);
865+
break;
866+
867+
case "allow-terminal-change-event":
868+
this.logger.info(
869+
`Allow terminal preference changed to: ${message.message}`,
870+
);
871+
await vscode.workspace
872+
.getConfiguration()
873+
.update(
874+
"codebuddy.allowTerminal",
875+
message.message,
876+
vscode.ConfigurationTarget.Global,
877+
);
878+
break;
879+
880+
case "verbose-logging-change-event":
881+
this.logger.info(
882+
`Verbose logging preference changed to: ${message.message}`,
883+
);
884+
await vscode.workspace
885+
.getConfiguration()
886+
.update(
887+
"codebuddy.verboseLogging",
888+
message.message,
889+
vscode.ConfigurationTarget.Global,
890+
);
891+
break;
892+
893+
case "index-codebase-change-event":
894+
this.logger.info(
895+
`Index codebase preference changed to: ${message.message}`,
896+
);
897+
await vscode.workspace
898+
.getConfiguration()
899+
.update(
900+
"codebuddy.indexCodebase",
901+
message.message,
902+
vscode.ConfigurationTarget.Global,
903+
);
904+
break;
905+
906+
case "context-window-change-event":
907+
this.logger.info(
908+
`Context window preference changed to: ${message.message}`,
909+
);
910+
await vscode.workspace
911+
.getConfiguration()
912+
.update(
913+
"codebuddy.contextWindow",
914+
message.message,
915+
vscode.ConfigurationTarget.Global,
916+
);
917+
break;
918+
919+
case "include-hidden-change-event":
920+
this.logger.info(
921+
`Include hidden preference changed to: ${message.message}`,
922+
);
923+
await vscode.workspace
924+
.getConfiguration()
925+
.update(
926+
"codebuddy.includeHidden",
927+
message.message,
928+
vscode.ConfigurationTarget.Global,
929+
);
930+
break;
931+
932+
case "max-file-size-change-event":
933+
this.logger.info(
934+
`Max file size preference changed to: ${message.message}`,
935+
);
936+
await vscode.workspace
937+
.getConfiguration()
938+
.update(
939+
"codebuddy.maxFileSize",
940+
message.message,
941+
vscode.ConfigurationTarget.Global,
942+
);
943+
break;
944+
945+
case "reindex-workspace-event":
946+
this.logger.info("Reindexing workspace...");
947+
// Trigger workspace reindexing
948+
vscode.commands.executeCommand("codebuddy.indexWorkspace");
949+
break;
950+
781951
case "open-codebuddy-settings":
782952
// Open VS Code settings filtered to CodeBuddy settings
783953
this.logger.info("Opening CodeBuddy settings...");

src/webview/chat_html.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ export const chartComponent = (webview: Webview, extensionUri: Uri) => {
4141
font-src 'self' ${webview.cspSource} https://fonts.gstatic.com data:;
4242
connect-src https:;
4343
img-src 'self' ${webview.cspSource} vscode-resource: https: data:;">
44+
<link rel="preconnect" href="https://fonts.googleapis.com" />
45+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
46+
<link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@300..700&family=Space+Mono:wght@400;700&family=Fira+Code:wght@300..700&family=Source+Code+Pro:wght@300..700&family=JetBrains+Mono:wght@300..700&family=Roboto+Mono:wght@300..700&family=Ubuntu+Mono:wght@400;700&family=IBM+Plex+Mono:wght@300..700&family=Inconsolata:wght@300..700&display=swap" rel="stylesheet" />
4447
<link rel="stylesheet" type="text/css" href="${stylesUri}">
4548
</head>
4649

0 commit comments

Comments
 (0)