Skip to content

Commit 59dc9dd

Browse files
Promotes AI features from experimental to preview status (#4369)
* Remove experimental configuration settings for AI features * Update AI feature labels from 'Experimental' to 'Preview' * Remove experimental feature gates from command and menu conditions * Add confirmation dialogs and storage for AI generate features * Enhance generate rebase function with commits mode support * Remove experimental AI settings from home webview state management
1 parent 683d247 commit 59dc9dd

File tree

10 files changed

+84
-80
lines changed

10 files changed

+84
-80
lines changed

contributions.json

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -233,70 +233,70 @@
233233
}
234234
},
235235
"gitlens.ai.generateCommits": {
236-
"label": "Generate Commits with AI (Experimental)...",
236+
"label": "Generate Commits with AI (Preview)...",
237237
"icon": "$(sparkle)",
238-
"commandPalette": "gitlens:enabled && !gitlens:untrusted && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateCommits.enabled"
238+
"commandPalette": "gitlens:enabled && !gitlens:untrusted && gitlens:gk:organization:ai:enabled"
239239
},
240240
"gitlens.ai.generateCommits:graph": {
241-
"label": "Generate Commits with AI (Experimental)",
241+
"label": "Generate Commits with AI (Preview)",
242242
"icon": "$(sparkle)",
243243
"menus": {
244244
"webview/context": [
245245
{
246-
"when": "webviewItem == gitlens:wip && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateCommits.enabled",
246+
"when": "webviewItem == gitlens:wip && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && gitlens:gk:organization:ai:enabled",
247247
"group": "1_gitlens",
248248
"order": 2
249249
}
250250
]
251251
}
252252
},
253253
"gitlens.ai.generateCommits:views": {
254-
"label": "Generate Commits with AI (Experimental)",
254+
"label": "Generate Commits with AI (Preview)",
255255
"icon": "$(sparkle)",
256256
"menus": {
257257
"view/item/context": [
258258
{
259-
"when": "viewItem =~ /gitlens:(worktree\\b(?=.*?\\b\\+working\\b)|uncommitted)\\b/ && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateCommits.enabled",
259+
"when": "viewItem =~ /gitlens:(worktree\\b(?=.*?\\b\\+working\\b)|uncommitted)\\b/ && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && gitlens:gk:organization:ai:enabled",
260260
"group": "3_gitlens_ai",
261261
"order": 1
262262
}
263263
]
264264
}
265265
},
266266
"gitlens.ai.generateRebase": {
267-
"label": "Rebase with AI (Experimental)...",
267+
"label": "Rebase with AI (Preview)...",
268268
"icon": "$(sparkle)",
269-
"commandPalette": "gitlens:enabled && !gitlens:untrusted && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateRebase.enabled"
269+
"commandPalette": "gitlens:enabled && !gitlens:untrusted && gitlens:gk:organization:ai:enabled"
270270
},
271271
"gitlens.ai.rebaseOntoCommit:graph": {
272-
"label": "AI Rebase Current Branch onto Commit...",
272+
"label": "AI Rebase Current Branch onto Commit (Preview)...",
273273
"icon": "$(sparkle)",
274274
"enablement": "!operationInProgress",
275275
"menus": {
276276
"webview/context": [
277277
{
278-
"when": "webviewItem =~ /gitlens:commit\\b/ && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateRebase.enabled",
278+
"when": "webviewItem =~ /gitlens:commit\\b/ && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && gitlens:gk:organization:ai:enabled",
279279
"group": "1_gitlens_actions",
280280
"order": 6
281281
}
282282
]
283283
}
284284
},
285285
"gitlens.ai.rebaseOntoCommit:views": {
286-
"label": "AI Rebase Current Branch onto Commit...",
286+
"label": "AI Rebase Current Branch onto Commit (Preview)...",
287287
"icon": "$(sparkle)",
288288
"enablement": "!operationInProgress",
289289
"menus": {
290290
"gitlens/commit/file/commit": [
291291
{
292-
"when": "viewItem =~ /gitlens:file\\b(?=.*?\\b\\+committed\\b)(?=.*?\\b\\+current\\b)/ && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateRebase.enabled",
292+
"when": "viewItem =~ /gitlens:file\\b(?=.*?\\b\\+committed\\b)(?=.*?\\b\\+current\\b)/ && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && gitlens:gk:organization:ai:enabled",
293293
"group": "1_gitlens_actions",
294294
"order": 6
295295
}
296296
],
297297
"view/item/context": [
298298
{
299-
"when": "viewItem =~ /gitlens:commit\\b(?!.*?\\b\\+rebase\\b)/ && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateRebase.enabled",
299+
"when": "viewItem =~ /gitlens:commit\\b(?!.*?\\b\\+rebase\\b)/ && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && gitlens:gk:organization:ai:enabled",
300300
"group": "1_gitlens_actions",
301301
"order": 6
302302
}

package.json

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4261,26 +4261,6 @@
42614261
"preview"
42624262
]
42634263
},
4264-
"gitlens.ai.experimental.generateCommits.enabled": {
4265-
"type": "boolean",
4266-
"default": false,
4267-
"markdownDescription": "Specifies whether to enable GitLens' experimental AI Commit Generation features",
4268-
"scope": "window",
4269-
"order": 1,
4270-
"tags": [
4271-
"experimental"
4272-
]
4273-
},
4274-
"gitlens.ai.experimental.generateRebase.enabled": {
4275-
"type": "boolean",
4276-
"default": false,
4277-
"markdownDescription": "Specifies whether to enable GitLens' experimental AI Rebase features",
4278-
"scope": "window",
4279-
"order": 1,
4280-
"tags": [
4281-
"experimental"
4282-
]
4283-
},
42844264
"gitlens.ai.generateStashMessage.customInstructions": {
42854265
"type": "string",
42864266
"default": null,
@@ -6247,35 +6227,35 @@
62476227
},
62486228
{
62496229
"command": "gitlens.ai.generateCommits",
6250-
"title": "Generate Commits with AI (Experimental)...",
6230+
"title": "Generate Commits with AI (Preview)...",
62516231
"category": "GitLens",
62526232
"icon": "$(sparkle)"
62536233
},
62546234
{
62556235
"command": "gitlens.ai.generateCommits:graph",
6256-
"title": "Generate Commits with AI (Experimental)",
6236+
"title": "Generate Commits with AI (Preview)",
62576237
"icon": "$(sparkle)"
62586238
},
62596239
{
62606240
"command": "gitlens.ai.generateCommits:views",
6261-
"title": "Generate Commits with AI (Experimental)",
6241+
"title": "Generate Commits with AI (Preview)",
62626242
"icon": "$(sparkle)"
62636243
},
62646244
{
62656245
"command": "gitlens.ai.generateRebase",
6266-
"title": "Rebase with AI (Experimental)...",
6246+
"title": "Rebase with AI (Preview)...",
62676247
"category": "GitLens",
62686248
"icon": "$(sparkle)"
62696249
},
62706250
{
62716251
"command": "gitlens.ai.rebaseOntoCommit:graph",
6272-
"title": "AI Rebase Current Branch onto Commit...",
6252+
"title": "AI Rebase Current Branch onto Commit (Preview)...",
62736253
"icon": "$(sparkle)",
62746254
"enablement": "!operationInProgress"
62756255
},
62766256
{
62776257
"command": "gitlens.ai.rebaseOntoCommit:views",
6278-
"title": "AI Rebase Current Branch onto Commit...",
6258+
"title": "AI Rebase Current Branch onto Commit (Preview)...",
62796259
"icon": "$(sparkle)",
62806260
"enablement": "!operationInProgress"
62816261
},
@@ -10766,7 +10746,7 @@
1076610746
},
1076710747
{
1076810748
"command": "gitlens.ai.generateCommits",
10769-
"when": "gitlens:enabled && !gitlens:untrusted && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateCommits.enabled"
10749+
"when": "gitlens:enabled && !gitlens:untrusted && gitlens:gk:organization:ai:enabled"
1077010750
},
1077110751
{
1077210752
"command": "gitlens.ai.generateCommits:graph",
@@ -10778,7 +10758,7 @@
1077810758
},
1077910759
{
1078010760
"command": "gitlens.ai.generateRebase",
10781-
"when": "gitlens:enabled && !gitlens:untrusted && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateRebase.enabled"
10761+
"when": "gitlens:enabled && !gitlens:untrusted && gitlens:gk:organization:ai:enabled"
1078210762
},
1078310763
{
1078410764
"command": "gitlens.ai.rebaseOntoCommit:graph",
@@ -14403,7 +14383,7 @@
1440314383
},
1440414384
{
1440514385
"command": "gitlens.ai.rebaseOntoCommit:views",
14406-
"when": "viewItem =~ /gitlens:file\\b(?=.*?\\b\\+committed\\b)(?=.*?\\b\\+current\\b)/ && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateRebase.enabled",
14386+
"when": "viewItem =~ /gitlens:file\\b(?=.*?\\b\\+committed\\b)(?=.*?\\b\\+current\\b)/ && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && gitlens:gk:organization:ai:enabled",
1440714387
"group": "1_gitlens_actions@6"
1440814388
},
1440914389
{
@@ -17097,7 +17077,7 @@
1709717077
},
1709817078
{
1709917079
"command": "gitlens.ai.rebaseOntoCommit:views",
17100-
"when": "viewItem =~ /gitlens:commit\\b(?!.*?\\b\\+rebase\\b)/ && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateRebase.enabled",
17080+
"when": "viewItem =~ /gitlens:commit\\b(?!.*?\\b\\+rebase\\b)/ && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && gitlens:gk:organization:ai:enabled",
1710117081
"group": "1_gitlens_actions@6"
1710217082
},
1710317083
{
@@ -18380,7 +18360,7 @@
1838018360
},
1838118361
{
1838218362
"command": "gitlens.ai.generateCommits:views",
18383-
"when": "viewItem =~ /gitlens:(worktree\\b(?=.*?\\b\\+working\\b)|uncommitted)\\b/ && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateCommits.enabled",
18363+
"when": "viewItem =~ /gitlens:(worktree\\b(?=.*?\\b\\+working\\b)|uncommitted)\\b/ && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && gitlens:gk:organization:ai:enabled",
1838418364
"group": "3_gitlens_ai@1"
1838518365
},
1838618366
{
@@ -22728,7 +22708,7 @@
2272822708
},
2272922709
{
2273022710
"command": "gitlens.ai.rebaseOntoCommit:graph",
22731-
"when": "webviewItem =~ /gitlens:commit\\b/ && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateRebase.enabled",
22711+
"when": "webviewItem =~ /gitlens:commit\\b/ && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && !gitlens:hasVirtualFolders && gitlens:gk:organization:ai:enabled",
2273222712
"group": "1_gitlens_actions@6"
2273322713
},
2273422714
{
@@ -22988,7 +22968,7 @@
2298822968
},
2298922969
{
2299022970
"command": "gitlens.ai.generateCommits:graph",
22991-
"when": "webviewItem == gitlens:wip && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && gitlens:gk:organization:ai:enabled && config.gitlens.ai.experimental.generateCommits.enabled",
22971+
"when": "webviewItem == gitlens:wip && !listMultiSelection && !gitlens:readonly && !gitlens:untrusted && gitlens:gk:organization:ai:enabled",
2299222972
"group": "1_gitlens@2"
2299322973
},
2299422974
{

src/commands/generateRebase.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,11 @@ export class GenerateCommitsCommand extends GlCommandBase {
8585
createReference(uncommitted, svc.path, { refType: 'revision' }),
8686
createReference('HEAD', svc.path, { refType: 'revision' }),
8787
args?.source ?? { source: 'commandPalette' },
88-
{ title: 'Generate Commits', progress: { location: ProgressLocation.Notification } },
88+
{
89+
title: 'Generate Commits',
90+
progress: { location: ProgressLocation.Notification },
91+
generateCommits: true,
92+
},
8993
);
9094
} catch (ex) {
9195
Logger.error(ex, 'GenerateCommitsCommand', 'execute');
@@ -165,7 +169,12 @@ export async function generateRebase(
165169
head: GitReference,
166170
base: GitReference,
167171
source: Source,
168-
options?: { title?: string; cancellation?: CancellationToken; progress?: ProgressOptions },
172+
options?: {
173+
title?: string;
174+
cancellation?: CancellationToken;
175+
progress?: ProgressOptions;
176+
generateCommits?: boolean;
177+
},
169178
): Promise<void> {
170179
const { title, ...aiOptions } = options ?? {};
171180

src/config.ts

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -217,14 +217,6 @@ interface AIConfig {
217217
readonly explainChanges: {
218218
readonly customInstructions: string;
219219
};
220-
readonly experimental: {
221-
readonly generateCommits: {
222-
readonly enabled: boolean;
223-
};
224-
readonly generateRebase: {
225-
readonly enabled: boolean;
226-
};
227-
};
228220
readonly generateChangelog: {
229221
readonly customInstructions: string;
230222
};

src/constants.storage.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ export type DeprecatedGlobalStorage = {
6363

6464
export type GlobalStorage = {
6565
avatars: [string, StoredAvatar][];
66+
'confirm:ai:generateCommits': boolean;
67+
'confirm:ai:generateRebase': boolean;
6668
'confirm:ai:tos': boolean;
6769
repoVisibility: [string, StoredRepoVisibilityInfo][];
6870
pendingWhatsNewOnFocus: boolean;

src/plus/ai/aiProviderService.ts

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -871,6 +871,7 @@ export class AIProviderService implements Disposable {
871871
context?: string;
872872
generating?: Deferred<AIModel>;
873873
progress?: ProgressOptions;
874+
generateCommits?: boolean;
874875
},
875876
): Promise<AIRebaseResult | undefined> {
876877
const result: Mutable<AIRebaseResult> = {
@@ -880,12 +881,43 @@ export class AIProviderService implements Disposable {
880881
commits: [],
881882
} as unknown as AIRebaseResult;
882883

884+
const confirmed = this.container.storage.get(
885+
options?.generateCommits ? 'confirm:ai:generateCommits' : 'confirm:ai:generateRebase',
886+
false,
887+
);
888+
if (!confirmed) {
889+
const accept: MessageItem = { title: 'Continue' };
890+
const cancel: MessageItem = { title: 'Cancel', isCloseAffordance: true };
891+
892+
const result = await window.showInformationMessage(
893+
`This will ${
894+
options?.generateCommits
895+
? 'stash all of your changes and commit directly to your current branch'
896+
: 'create a new branch at the chosen commit and commit directly to that branch'
897+
}.`,
898+
{ modal: true },
899+
accept,
900+
cancel,
901+
);
902+
903+
if (result === cancel) {
904+
return undefined;
905+
} else if (result === accept) {
906+
await this.container.storage.store(
907+
options?.generateCommits ? 'confirm:ai:generateCommits' : 'confirm:ai:generateRebase',
908+
true,
909+
);
910+
}
911+
}
912+
883913
const rq = await this.sendRequest(
884914
'generate-rebase',
885915
async (model, reporting, cancellation, maxInputTokens, retries) => {
886916
const diff = await repo.git.diff.getDiff?.(headRef, baseRef, { notation: '...' });
887917
if (!diff?.contents) {
888-
throw new AINoRequestDataError('No changes found to generate a rebase from.');
918+
throw new AINoRequestDataError(
919+
`No changes found to generate ${options?.generateCommits ? 'commits' : 'a rebase'} from.`,
920+
);
889921
}
890922
if (cancellation.isCancellationRequested) throw new CancellationError();
891923

@@ -937,7 +969,7 @@ export class AIProviderService implements Disposable {
937969
const messages: AIChatMessage[] = [{ role: 'user', content: prompt }];
938970
return messages;
939971
},
940-
m => `Generating rebase with ${m.name}...`,
972+
m => `Generating ${options?.generateCommits ? 'commits' : 'rebase'} with ${m.name}...`,
941973
source,
942974
m => ({
943975
key: 'ai/generate',
@@ -959,7 +991,7 @@ export class AIProviderService implements Disposable {
959991
result.commits = JSON.parse(content) as AIRebaseResult['commits'];
960992
} catch {
961993
debugger;
962-
throw new Error('Unable to parse rebase result');
994+
throw new Error(`Unable to parse ${options?.generateCommits ? 'commits' : 'rebase'} result`);
963995
}
964996

965997
return {
@@ -1408,6 +1440,8 @@ export class AIProviderService implements Disposable {
14081440
resetConfirmations(): void {
14091441
void this.container.storage.deleteWithPrefix(`confirm:ai:tos`);
14101442
void this.container.storage.deleteWorkspaceWithPrefix(`confirm:ai:tos`);
1443+
void this.container.storage.deleteWithPrefix(`confirm:ai:generateCommits`);
1444+
void this.container.storage.deleteWithPrefix(`confirm:ai:generateRebase`);
14111445
}
14121446

14131447
resetProviderKey(provider: AIProviders, silent?: boolean): void {

src/webviews/apps/home/stateProvider.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ export class HomeStateProvider implements StateProvider<State> {
8080
this._state.previewEnabled = msg.params.previewEnabled;
8181
this._state.previewCollapsed = msg.params.previewCollapsed;
8282
this._state.aiEnabled = msg.params.aiEnabled;
83-
this._state.aiGenerateCommitsEnabled = msg.params.aiGenerateCommitsEnabled;
8483
this._state.timestamp = Date.now();
8584

8685
this.provider.setValue(this._state, true);

src/webviews/apps/plus/home/components/active-work.ts

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -269,15 +269,13 @@ export class GlActiveBranchCard extends GlBranchCardBase {
269269
const actions = [];
270270
if (aiEnabled) {
271271
if (hasWip) {
272-
if (this._homeState.aiGenerateCommitsEnabled) {
273-
actions.push(
274-
html`<menu-item
275-
?disabled=${isFetching}
276-
href=${this.createCommandLink('gitlens.ai.generateCommits:home')}
277-
>Generate Commits with AI (Experimental)</menu-item
278-
>`,
279-
);
280-
}
272+
actions.push(
273+
html`<menu-item
274+
?disabled=${isFetching}
275+
href=${this.createCommandLink('gitlens.ai.generateCommits:home')}
276+
>Generate Commits with AI (Preview)</menu-item
277+
>`,
278+
);
281279
actions.push(
282280
html`<menu-item ?disabled=${isFetching} href=${this.createCommandLink('gitlens.ai.explainWip:home')}
283281
>Explain Working Changes (Preview)</menu-item

0 commit comments

Comments
 (0)