Skip to content
Merged
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
43545c1
Add command executor MCP server
steveluc Jan 17, 2026
bf20673
Add copyright header to view-logs.sh
steveluc Jan 17, 2026
7c2a81a
Fix repo policy issues
steveluc Jan 17, 2026
82a1910
Run prettier to format files
steveluc Jan 17, 2026
ea66752
Fix repo policy issues - trademark format and package.json script order
steveluc Jan 17, 2026
e4672de
Enhance VSCode split editor functionality
steveluc Jan 19, 2026
81d7d0c
Merge main into branch and resolve conflicts
steveluc Jan 19, 2026
7cf1b80
Fix prettier formatting for README and VSCODE_CAPABILITIES
steveluc Jan 19, 2026
0ebe52c
Add support for creating playlists with song lists in player agent
steveluc Jan 19, 2026
4d47a68
Merge remote-tracking branch 'origin/main' into add-command-executor-…
steveluc Jan 19, 2026
3938cc6
Add coderWrapper package for CLI assistant PTY wrapper
steveluc Jan 19, 2026
b88be7b
Fix prettier formatting for coderWrapper package
steveluc Jan 19, 2026
ec83de6
Merge remote-tracking branch 'origin/main' into add-command-executor-…
steveluc Jan 19, 2026
4c5b90d
Update pnpm-lock.yaml for coderWrapper package
steveluc Jan 19, 2026
cfa7c49
Add copyright header to test-wrapper.js
steveluc Jan 19, 2026
ccd621c
Add trademark section to README and copyright header to pnpm-lock.yaml
steveluc Jan 19, 2026
c9179ee
Complete trademark section with third-party policy
steveluc Jan 19, 2026
f2e77f2
Add cache support to coderWrapper with shared dispatcher
steveluc Jan 20, 2026
b0010a9
Fix prettier formatting
steveluc Jan 20, 2026
7618fa3
Merge remote-tracking branch 'origin/main' into add-command-executor-…
steveluc Jan 20, 2026
cba739e
Add Agent SDK wrapper with TypeAgent caching and MCP integration
steveluc Jan 20, 2026
5574534
Merge main into add-command-executor-mcp-server and resolve conflicts
steveluc Jan 20, 2026
3be0315
Fix CodeQL security issues in HTML processing
steveluc Jan 20, 2026
5dc7496
Add html-to-text dependencies to package.json
steveluc Jan 20, 2026
0bcba33
Add trademark section to agentSdkWrapper README
steveluc Jan 20, 2026
f75868a
Add user confirmation flow for yes/no prompts in MCP server
steveluc Jan 20, 2026
0b51ef5
Merge main into add-command-executor-mcp-server
steveluc Jan 20, 2026
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
56 changes: 53 additions & 3 deletions ts/packages/commandExecutor/src/commandServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ function executeCommandRequestSchema() {
return {
request: z.string(),
cacheCheck: z.boolean().optional(),
confirmed: z.boolean().optional(),
};
}
const ExecuteCommandRequestSchema = z.object(executeCommandRequestSchema());
Expand Down Expand Up @@ -122,6 +123,7 @@ async function processHtmlImages(content: string): Promise<string> {
function createMcpClientIO(
logger: Logger,
responseCollector: { messages: string[] },
getConfirmedFlag: () => boolean,
): ClientIO {
return {
clear(): void {
Expand Down Expand Up @@ -195,10 +197,19 @@ function createMcpClientIO(
requestId: RequestId,
defaultValue?: boolean,
): Promise<boolean> {
// Check if this request was pre-confirmed
if (getConfirmedFlag()) {
logger.log(
`ClientIO: askYesNo(requestId=${requestId}) - "${message}" (auto-approved due to confirmed=true)`,
);
return true;
}

// Otherwise, throw error requiring user confirmation
logger.log(
`ClientIO: askYesNo(requestId=${requestId}) - "${message}" (defaulting to ${defaultValue ?? false})`,
`ClientIO: askYesNo(requestId=${requestId}) - "${message}" (requires user confirmation)`,
);
return defaultValue ?? false;
throw new Error(`USER_CONFIRMATION_REQUIRED: ${message}`);
},
async proposeAction(
actionTemplates: TemplateEditConfig,
Expand Down Expand Up @@ -268,6 +279,7 @@ export class CommandServer {
private reconnectDelayMs: number = 5000; // 5 seconds between reconnection attempts
private logger: Logger;
private responseCollector: { messages: string[] } = { messages: [] };
private currentRequestConfirmed: boolean = false;

/**
* Creates a new CommandServer instance
Expand Down Expand Up @@ -317,6 +329,7 @@ export class CommandServer {
const clientIO = createMcpClientIO(
this.logger,
this.responseCollector,
() => this.currentRequestConfirmed,
);
this.dispatcher = await connectDispatcher(
clientIO,
Expand Down Expand Up @@ -377,7 +390,15 @@ export class CommandServer {
"- Music & media: play songs, control playback\n" +
"- Lists & tasks: manage shopping lists, todo lists\n" +
"- Calendar: schedule events, view calendar\n" +
"- VSCode automation: change theme (e.g. 'switch to monokai theme'), open files, create folders, run tasks, manage editor layout, open terminals, toggle settings",
"- VSCode automation: change theme (e.g. 'switch to monokai theme'), open files, create folders, run tasks, manage editor layout, open terminals, toggle settings\n\n" +
"Parameters:\n" +
"- request: The command to execute\n" +
"- cacheCheck: (optional) Check cache before executing\n" +
"- confirmed: (optional) Set to true if user has already confirmed any yes/no prompts\n\n" +
"Confirmation Flow:\n" +
"Some commands (like deleting sessions or clearing data) require user confirmation. " +
"If a command requires confirmation, the tool will return an error message indicating what needs to be confirmed. " +
"Ask the user for confirmation, then retry the same command with confirmed=true if they approve.",
},
async (request: ExecuteCommandRequest) =>
this.executeCommand(request),
Expand All @@ -389,6 +410,12 @@ export class CommandServer {
): Promise<CallToolResult> {
this.logger.log(`User request: ${request.request}`);

// Set confirmation flag for this request
this.currentRequestConfirmed = request.confirmed ?? false;
if (this.currentRequestConfirmed) {
this.logger.log("Request has confirmed=true flag");
}

// If not connected, try to connect now (lazy connection)
if (!this.dispatcher && !this.isConnecting) {
this.logger.log(
Expand Down Expand Up @@ -502,13 +529,36 @@ export class CommandServer {
// Fallback if no messages were collected
return toolResult(`Successfully executed: ${request.request}`);
} catch (error) {
// Check if this is a user confirmation request
if (
error instanceof Error &&
error.message.startsWith("USER_CONFIRMATION_REQUIRED:")
) {
const question = error.message.replace(
"USER_CONFIRMATION_REQUIRED: ",
"",
);
this.logger.log(
`Command requires user confirmation: ${question}`,
);
return toolResult(
`⚠️ Confirmation Required\n\n` +
`The action you requested requires confirmation:\n\n` +
`"${question}"\n\n` +
`Please confirm with the user, then retry the command with confirmed=true if they approve.`,
);
}

const errorMsg = `Failed to execute command: ${error instanceof Error ? error.message : String(error)}`;
this.logger.error(errorMsg);

// Mark dispatcher as disconnected so we'll try to reconnect
this.dispatcher = null;

return toolResult(errorMsg);
} finally {
// Always reset confirmation flag after request completes
this.currentRequestConfirmed = false;
}
}

Expand Down
Loading