Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ private Constants() {
public static final String GITHUB_JOBS_VIEW_ID = "com.microsoft.copilot.eclipse.ui.jobs.JobsView";
public static final String SUPPRESS_TERMINAL_DEPENDENCY_DIALOG = "suppressTerminalDependencyDialog";

// Auto-Approve settings
public static final String AUTO_APPROVE_TERMINAL_RULES = "autoApproveTerminalRules";
public static final String AUTO_APPROVE_UNMATCHED_TERMINAL = "autoApproveUnmatchedTerminal";

// Base excluded file types shared by both
// Copied from InelliJ, excluded file extension list
// https://github.com/microsoft/copilot-intellij/blob/main/core/src/main/kotlin/com/github/copilot/chat/references/FileSearchService.kt
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

package com.microsoft.copilot.eclipse.core.chat;

import java.util.Map;
import java.util.Objects;

import org.apache.commons.lang3.builder.ToStringBuilder;

/**
* Represents a button action in the confirmation UI. Each action has a label,
* a decision (accept or dismiss), a persistence scope, and optional metadata
* for the handler to know what to persist.
*/
public class ConfirmationAction {

/** Metadata key for the action type enum name. */
public static final String META_ACTION = "action";

private final String label;
private final boolean accept;
private final ConfirmationActionScope scope;
private final Map<String, String> metadata;
private final boolean primary;

/**
* Creates a new confirmation action.
*
* @param label the button label
* @param accept true for accept, false for dismiss
* @param scope the persistence scope (null for dismiss actions)
* @param metadata extra data for the handler (e.g., command names, server name)
* @param primary whether this is the primary/default button
*/
public ConfirmationAction(String label, boolean accept,
ConfirmationActionScope scope, Map<String, String> metadata,
boolean primary) {
this.label = label;
this.accept = accept;
this.scope = scope;
this.metadata = metadata != null ? metadata : Map.of();
this.primary = primary;
}

public String getLabel() {
return label;
}

public boolean isAccept() {
return accept;
}

public ConfirmationActionScope getScope() {
return scope;
}

public Map<String, String> getMetadata() {
return metadata;
}

public boolean isPrimary() {
return primary;
}

/** Creates a primary accept action (scope = ONCE). */
public static ConfirmationAction allowOnce(String label) {
return new ConfirmationAction(label, true,
ConfirmationActionScope.ONCE, null, true);
}

/** Creates a dismiss action. */
public static ConfirmationAction skip(String label) {
return new ConfirmationAction(label, false, null, null, false);
}

@Override
public int hashCode() {
return Objects.hash(accept, label, metadata, primary, scope);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ConfirmationAction other = (ConfirmationAction) obj;
return accept == other.accept
&& Objects.equals(label, other.label)
&& Objects.equals(metadata, other.metadata)
&& primary == other.primary && scope == other.scope;
}

@Override
public String toString() {
return new ToStringBuilder(this)
.append("label", label)
.append("accept", accept)
.append("scope", scope)
.append("metadata", metadata)
.append("primary", primary)
.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

package com.microsoft.copilot.eclipse.core.chat;

/**
* Scope of how a confirmation decision should be persisted.
*/
public enum ConfirmationActionScope {
/** One-time acceptance for this single invocation. */
ONCE,
/** Remember for the current conversation session (in-memory). */
SESSION,
/** Remember globally (application-level persistent, synced to CLS). */
GLOBAL
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

package com.microsoft.copilot.eclipse.core.chat;

import java.util.List;
import java.util.Objects;

import org.apache.commons.lang3.builder.ToStringBuilder;

/**
* Complete content for rendering a confirmation UI. Returned by handlers when a tool call
* needs user confirmation. Contains the display text and the list of action buttons.
*/
public class ConfirmationContent {

private final String title;
private final String message;
private final List<ConfirmationAction> actions;

/**
* Creates a new confirmation content.
*
* @param title bold title text displayed at the top
* @param message description text (may be null)
* @param actions list of button actions for the confirmation UI
*/
public ConfirmationContent(String title, String message,
List<ConfirmationAction> actions) {
this.title = title;
this.message = message;
this.actions = actions;
}

public String getTitle() {
return title;
}

public String getMessage() {
return message;
}

public List<ConfirmationAction> getActions() {
return actions;
}

@Override
public int hashCode() {
return Objects.hash(actions, message, title);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ConfirmationContent other = (ConfirmationContent) obj;
return Objects.equals(actions, other.actions)
&& Objects.equals(message, other.message)
&& Objects.equals(title, other.title);
}

@Override
public String toString() {
return new ToStringBuilder(this)
.append("title", title)
.append("message", message)
.append("actions", actions)
.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,68 @@

package com.microsoft.copilot.eclipse.core.chat;

import java.util.Objects;

import org.apache.commons.lang3.builder.ToStringBuilder;

/**
* Result of evaluating an auto-approve confirmation request.
* Either AUTO_APPROVED (no UI needed) or NEEDS_CONFIRMATION with content for the dialog.
*/
public enum ConfirmationResult {
/**
* The tool invocation is automatically approved and no user confirmation is needed.
*/
AUTO_APPROVED,

/**
* The tool invocation requires user confirmation before proceeding.
*/
NEEDS_CONFIRMATION
public class ConfirmationResult {

/** Auto-approved, no user confirmation needed. */
public static final ConfirmationResult AUTO_APPROVED = new ConfirmationResult(true, null);

private final boolean autoApproved;
private final ConfirmationContent content;

private ConfirmationResult(boolean autoApproved, ConfirmationContent content) {
this.autoApproved = autoApproved;
this.content = content;
}

/** Creates a result that requires user confirmation with the given content. */
public static ConfirmationResult needsConfirmation(
ConfirmationContent content) {
return new ConfirmationResult(false, content);
}

public boolean isAutoApproved() {
return autoApproved;
}

/** Returns the confirmation content, or null if auto-approved or using defaults. */
public ConfirmationContent getContent() {
return content;
}

@Override
public int hashCode() {
return Objects.hash(autoApproved, content);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
ConfirmationResult other = (ConfirmationResult) obj;
return autoApproved == other.autoApproved
&& Objects.equals(content, other.content);
}

@Override
public String toString() {
return new ToStringBuilder(this)
.append("autoApproved", autoApproved)
.append("content", content)
.toString();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.

package com.microsoft.copilot.eclipse.core.chat;

import java.util.Objects;

import org.apache.commons.lang3.builder.ToStringBuilder;

/**
* A single terminal auto-approve rule mapping a command name or regex pattern to an
* allow/deny decision.
*/
public class TerminalAutoApproveRule {
private String command;
private boolean autoApprove;

/**
* Creates a new rule.
*
* @param command the command name or regex pattern
* @param autoApprove true to auto-approve, false to always require confirmation
*/
public TerminalAutoApproveRule(String command, boolean autoApprove) {
this.command = command;
this.autoApprove = autoApprove;
}

/** Default constructor for Gson deserialization. */
public TerminalAutoApproveRule() {
}

public String getCommand() {
return command;
}

public void setCommand(String command) {
this.command = command;
}

public boolean isAutoApprove() {
return autoApprove;
}

public void setAutoApprove(boolean autoApprove) {
this.autoApprove = autoApprove;
}

@Override
public int hashCode() {
return Objects.hash(autoApprove, command);
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
TerminalAutoApproveRule other = (TerminalAutoApproveRule) obj;
return autoApprove == other.autoApprove
&& Objects.equals(command, other.command);
}

@Override
public String toString() {
return new ToStringBuilder(this)
.append("command", command)
.append("autoApprove", autoApprove)
.toString();
}
}
Loading