-
Notifications
You must be signed in to change notification settings - Fork 244
feat: wire feedback modal and IPC wiring #491
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
jeffscottward
wants to merge
10
commits into
RunMaestro:main
Choose a base branch
from
jeffscottward:symphony/issue-457-mm82lf08
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
579335b
[Symphony] Start contribution for #457
jeffscottward c24754d
MAESTRO: add feedback issue prompt template
jeffscottward 77dbcfc
MAESTRO: add shared FeedbackView component
jeffscottward 87620f2
MAESTRO: wire FeedbackView into AboutModal
jeffscottward 52e1936
MAESTRO: fix feedback modal state wiring in quick actions
jeffscottward 440d49d
feat: wire feedback modal and IPC wiring
jeffscottward 4805547
fix: address PR review feedback for feedback modal
jeffscottward b051a06
fix: address failing checks for PR #491
599a3e8
fix: address failing checks for PR #491
b0b90b3
fix: address failing checks for PR #491
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,150 @@ | ||
| /** | ||
| * Feedback IPC Handlers | ||
| * | ||
| * This module handles: | ||
| * - Checking GitHub CLI availability and authentication | ||
| * - Submitting feedback text to the selected agent as a structured prompt | ||
| */ | ||
|
|
||
| import { ipcMain, app } from 'electron'; | ||
| import fs from 'fs/promises'; | ||
| import path from 'path'; | ||
| import { logger } from '../../utils/logger'; | ||
| import { withIpcErrorLogging, CreateHandlerOptions } from '../../utils/ipcHandler'; | ||
| import { | ||
| isGhInstalled, | ||
| setCachedGhStatus, | ||
| getCachedGhStatus, | ||
| getExpandedEnv, | ||
| } from '../../utils/cliDetection'; | ||
| import { execFileNoThrow } from '../../utils/execFile'; | ||
| import { ProcessManager } from '../../process-manager'; | ||
|
|
||
| const LOG_CONTEXT = '[Feedback]'; | ||
|
|
||
| const GH_NOT_INSTALLED_MESSAGE = | ||
| 'GitHub CLI (gh) is not installed. Install it from https://cli.github.com'; | ||
| const GH_NOT_AUTHENTICATED_MESSAGE = | ||
| 'GitHub CLI is not authenticated. Run "gh auth login" in your terminal.'; | ||
|
|
||
| function getPromptPath(): string { | ||
| if (app.isPackaged) { | ||
| return path.join(process.resourcesPath, 'prompts', 'feedback.md'); | ||
| } | ||
|
|
||
| return path.join(app.getAppPath(), 'src', 'prompts', 'feedback.md'); | ||
| } | ||
|
|
||
| /** | ||
| * Helper to create handler options with consistent context | ||
| */ | ||
| const handlerOpts = ( | ||
| operation: string, | ||
| extra?: Partial<CreateHandlerOptions> | ||
| ): Pick<CreateHandlerOptions, 'context' | 'operation'> => ({ | ||
| context: LOG_CONTEXT, | ||
| operation, | ||
| ...extra, | ||
| }); | ||
|
|
||
| /** | ||
| * Dependencies required for feedback handler registration | ||
| */ | ||
| export interface FeedbackHandlerDependencies { | ||
| getProcessManager: () => ProcessManager | null; | ||
| } | ||
|
|
||
| /** | ||
| * Register feedback IPC handlers. | ||
| */ | ||
| export function registerFeedbackHandlers(deps: FeedbackHandlerDependencies): void { | ||
| const { getProcessManager } = deps; | ||
|
|
||
| logger.info('Registering feedback IPC handlers', LOG_CONTEXT); | ||
|
|
||
| // Check if GitHub CLI is installed and authenticated | ||
| ipcMain.handle( | ||
| 'feedback:check-gh-auth', | ||
| withIpcErrorLogging( | ||
| handlerOpts('check-gh-auth'), | ||
| async (): Promise<{ authenticated: boolean; message?: string }> => { | ||
| // Prefer cache when available | ||
| const cached = getCachedGhStatus(); | ||
| if (cached) { | ||
| if (!cached.installed) { | ||
| return { authenticated: false, message: GH_NOT_INSTALLED_MESSAGE }; | ||
| } | ||
| if (!cached.authenticated) { | ||
| return { authenticated: false, message: GH_NOT_AUTHENTICATED_MESSAGE }; | ||
| } | ||
| return { authenticated: true }; | ||
| } | ||
|
|
||
| // Check if gh is installed | ||
| const installed = await isGhInstalled(); | ||
| if (!installed) { | ||
| setCachedGhStatus(false, false); | ||
| return { authenticated: false, message: GH_NOT_INSTALLED_MESSAGE }; | ||
| } | ||
|
|
||
| // Check auth status (command output ignored; exit code is the signal) | ||
| const authResult = await execFileNoThrow( | ||
| 'gh', | ||
| ['auth', 'status'], | ||
| undefined, | ||
| getExpandedEnv() | ||
| ); | ||
| const authenticated = authResult.exitCode === 0; | ||
| setCachedGhStatus(true, authenticated); | ||
|
|
||
| if (!authenticated) { | ||
| return { authenticated: false, message: GH_NOT_AUTHENTICATED_MESSAGE }; | ||
| } | ||
|
|
||
| return { authenticated: true }; | ||
| } | ||
| ) | ||
| ); | ||
|
|
||
| // Submit feedback by writing to an active process | ||
| ipcMain.handle( | ||
| 'feedback:submit', | ||
| withIpcErrorLogging( | ||
| handlerOpts('submit'), | ||
| async ({ | ||
| sessionId, | ||
| feedbackText, | ||
| }: { | ||
| sessionId: string; | ||
| feedbackText: string; | ||
| }): Promise<{ success: boolean; error?: string }> => { | ||
| if (!sessionId || typeof sessionId !== 'string') { | ||
| return { success: false, error: 'No target agent was selected.' }; | ||
| } | ||
|
|
||
| const trimmedFeedback = typeof feedbackText === 'string' ? feedbackText.trim() : ''; | ||
| if (!trimmedFeedback) { | ||
| return { success: false, error: 'Feedback cannot be empty.' }; | ||
| } | ||
| if (trimmedFeedback.length > 5000) { | ||
| return { success: false, error: 'Feedback exceeds the maximum length (5000).' }; | ||
| } | ||
|
|
||
| const processManager = getProcessManager(); | ||
| if (!processManager) { | ||
| return { success: false, error: 'Agent process not available' }; | ||
| } | ||
|
|
||
| const promptTemplate = await fs.readFile(getPromptPath(), 'utf-8'); | ||
| const finalPrompt = promptTemplate.replace('{{FEEDBACK}}', trimmedFeedback); | ||
| const writeSuccess = processManager.write(sessionId, `${finalPrompt}\n`); | ||
|
|
||
| if (!writeSuccess) { | ||
| return { success: false, error: 'Agent process not available' }; | ||
| } | ||
|
|
||
| return { success: true }; | ||
| } | ||
| ) | ||
| ); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,51 @@ | ||
| /** | ||
| * Preload API for feedback submission | ||
| * | ||
| * Provides the window.maestro.feedback namespace for: | ||
| * - Checking GitHub CLI auth status for feedback submission | ||
| * - Submitting structured feedback to an active agent session | ||
| */ | ||
|
|
||
| import { ipcRenderer } from 'electron'; | ||
|
|
||
| /** | ||
| * Feedback auth check response | ||
| */ | ||
| export interface FeedbackAuthResponse { | ||
| authenticated: boolean; | ||
| message?: string; | ||
| } | ||
|
|
||
| /** | ||
| * Feedback submission response | ||
| */ | ||
| export interface FeedbackSubmitResponse { | ||
| success: boolean; | ||
| error?: string; | ||
| } | ||
|
|
||
| /** | ||
| * Feedback API | ||
| */ | ||
| export interface FeedbackApi { | ||
| /** | ||
| * Check whether gh CLI is available and authenticated | ||
| */ | ||
| checkGhAuth: () => Promise<FeedbackAuthResponse>; | ||
| /** | ||
| * Submit user feedback to an active agent session | ||
| */ | ||
| submit: (sessionId: string, feedbackText: string) => Promise<FeedbackSubmitResponse>; | ||
| } | ||
|
|
||
| /** | ||
| * Creates the feedback API object for preload exposure | ||
| */ | ||
| export function createFeedbackApi() { | ||
| return { | ||
| checkGhAuth: (): Promise<FeedbackAuthResponse> => ipcRenderer.invoke('feedback:check-gh-auth'), | ||
|
|
||
| submit: (sessionId: string, feedbackText: string): Promise<FeedbackSubmitResponse> => | ||
| ipcRenderer.invoke('feedback:submit', { sessionId, feedbackText }), | ||
| }; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,33 @@ | ||
| # Feedback Issue Authoring Instructions | ||
|
|
||
| You are creating a GitHub issue from user feedback for RunMaestro. | ||
|
|
||
| User-provided feedback: | ||
| {{FEEDBACK}} | ||
|
|
||
| Do not ask for clarification. Use the text as-is and proceed. | ||
|
|
||
| 1. Classify feedback type as one of: | ||
|
|
||
| - Bug report | ||
| - Feature request | ||
| - Improvement | ||
| - General feedback | ||
|
|
||
| 2. Write a concise GitHub issue title prefixed with the type, e.g., "Bug: ...". | ||
|
|
||
| 3. Write issue body with these sections: | ||
|
|
||
| - Description | ||
| - Expected vs Current Behavior | ||
| - Steps to Reproduce (for bug reports; if unavailable, clearly note "Not provided") | ||
| - Proposed Solution (for feature/improvement items) | ||
| - Impact and Priority (brief) | ||
|
|
||
| 4. Run: | ||
| `gh label create "Maestro-feedback" --repo RunMaestro/Maestro --description "User feedback submitted via Maestro" --color "0E8A16"` | ||
|
|
||
| 5. Then run: | ||
| `gh issue create --repo RunMaestro/Maestro --label "Maestro-feedback" --title "TITLE" --body "BODY"` | ||
|
|
||
| 6. Reply with only the created issue URL. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.