diff --git a/package.json b/package.json index 121adffe67..89fce86bd0 100644 --- a/package.json +++ b/package.json @@ -1673,6 +1673,12 @@ "title": "%command.issue.startWorkingBranchPrompt.title%", "category": "%command.issues.category%" }, + { + "command": "issue.startWorkingByNumber", + "title": "%command.issue.startWorkingByNumber.title%", + "category": "%command.issues.category%", + "icon": "$(symbol-numeric)" + }, { "command": "issue.stopWorking", "title": "%command.issue.stopWorking.title%", @@ -2510,6 +2516,10 @@ "command": "issue.startWorkingBranchPrompt", "when": "false" }, + { + "command": "issue.startWorkingByNumber", + "when": "gitHubOpenRepositoryCount != 0 && github:initialized && github:authenticated" + }, { "command": "issue.stopWorking", "when": "false" diff --git a/package.nls.json b/package.nls.json index 73c02b7684..fdda41a926 100644 --- a/package.nls.json +++ b/package.nls.json @@ -304,6 +304,7 @@ "command.issue.startWorkingBranchDescriptiveTitle.title": "Start Working on Issue and Checkout Topic Branch", "command.issue.continueWorking.title": "Continue Working on Issue", "command.issue.startWorkingBranchPrompt.title": "Start Working and Set Branch...", + "command.issue.startWorkingByNumber.title": "Start Working on Issue by Number...", "command.issue.stopWorking.title": "Stop Working on Issue", "command.issue.stopWorkingBranchDescriptiveTitle.title": "Stop Working on Issue and Leave Topic Branch", "command.issue.statusBar.title": "Current Issue Options", diff --git a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts index 71520fa1ec..aa7001a3d2 100644 --- a/src/@types/vscode.proposed.chatParticipantAdditions.d.ts +++ b/src/@types/vscode.proposed.chatParticipantAdditions.d.ts @@ -105,6 +105,7 @@ declare module 'vscode' { isComplete?: boolean; toolSpecificData?: ChatTerminalToolInvocationData; fromSubAgent?: boolean; + presentation?: 'hidden' | 'hiddenAfterComplete' | undefined; constructor(toolName: string, toolCallId: string, isError?: boolean); } diff --git a/src/issues/issueFeatureRegistrar.ts b/src/issues/issueFeatureRegistrar.ts index a4f253a57d..2359a04530 100644 --- a/src/issues/issueFeatureRegistrar.ts +++ b/src/issues/issueFeatureRegistrar.ts @@ -360,6 +360,19 @@ export class IssueFeatureRegistrar extends Disposable { this, ), ); + this._register( + vscode.commands.registerCommand( + 'issue.startWorkingByNumber', + () => { + /* __GDPR__ + "issue.startWorkingByNumber" : {} + */ + this.telemetry.sendTelemetryEvent('issue.startWorkingByNumber'); + return this.startWorkingByNumber(); + }, + this, + ), + ); this._register( vscode.commands.registerCommand( 'issue.stopWorking', @@ -855,6 +868,70 @@ export class IssueFeatureRegistrar extends Disposable { this.doStartWorking(this.manager.getManagerForIssueModel(issueModel), issueModel, true); } + async startWorkingByNumber() { + // Choose repository if multiple are available + const folderManager = await this.chooseRepo(vscode.l10n.t('Choose which repository you want to work on an issue in')); + if (!folderManager) { + return; + } + + // Get repository defaults for owner and name + let defaults: PullRequestDefaults | undefined; + try { + defaults = await folderManager.getPullRequestDefaults(); + } catch (e) { + vscode.window.showErrorMessage(vscode.l10n.t('Failed to get repository information')); + return; + } + + // Prompt for issue number or URL + const issueInput = await vscode.window.showInputBox({ + ignoreFocusOut: true, + prompt: vscode.l10n.t('Enter the issue number or URL'), + validateInput: (input: string) => { + if (!input) { + return vscode.l10n.t('Issue number or URL is required'); + } + const match = input.match(ISSUE_OR_URL_EXPRESSION); + const parsed = parseIssueExpressionOutput(match); + if (!parsed || !parsed.issueNumber) { + return vscode.l10n.t('Invalid issue number or URL'); + } + return undefined; + } + }); + + if (!issueInput) { + return; + } + + // Parse the input + const match = issueInput.match(ISSUE_OR_URL_EXPRESSION); + const parsed = parseIssueExpressionOutput(match); + if (!parsed || !parsed.issueNumber) { + vscode.window.showErrorMessage(vscode.l10n.t('Invalid issue number or URL')); + return; + } + + // Use repository defaults if owner/name not specified + if (!parsed.owner && defaults) { + parsed.owner = defaults.owner; + } + if (!parsed.name && defaults) { + parsed.name = defaults.repo; + } + + // Fetch the issue + const issueModel = await getIssue(this._stateManager, folderManager, issueInput, parsed); + if (!issueModel) { + vscode.window.showErrorMessage(vscode.l10n.t('Unable to find issue {0}', issueInput)); + return; + } + + // Start working on the issue + return this.doStartWorking(folderManager, issueModel); + } + async stopWorking(issueModel: any) { let folderManager = this.manager.getManagerForIssueModel(issueModel); if (!folderManager) {