feat: generalize target-app-hints for common macOS apps#7428
Conversation
Replace the Vellum-only app detection with a table-driven approach that recognizes 20+ common macOS apps (browsers, terminals, IDEs, communication tools, productivity apps, Apple built-ins). Generic words like "notes", "mail", "terminal", "messages", and "settings" require action-verb context (open/launch/test/qa/in/check/use) to avoid false positives. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 7305074777
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| bundleId: 'com.microsoft.VSCode', | ||
| }, | ||
| { | ||
| patterns: [/\bcursor\b/], |
There was a problem hiding this comment.
Narrow Cursor hint to app-intent phrases
The pattern \bcursor\b matches common UI wording (for example, "move cursor to the submit button"), so resolveComputerUseTargetAppHint can incorrectly lock a computer-use session to the Cursor IDE when no app was requested. This value is propagated as targetAppName/targetAppBundleId and then enforced by the target-app guard, which can block otherwise valid workflows in unrelated apps.
Useful? React with 👍 / 👎.
| bundleId: 'com.hnc.Discord', | ||
| }, | ||
| { | ||
| patterns: [/\bzoom\b/], |
There was a problem hiding this comment.
Avoid treating verb "zoom" as Zoom app intent
Using \bzoom\b as a direct app hint causes verb phrases like "zoom in on the chart" to resolve to the Zoom desktop app, which is a false positive for many computer-use tasks. Because this hint scopes the session to a specific app, these tasks can be misrouted and then blocked by the app-scope guard.
Useful? React with 👍 / 👎.
| patterns: [contextPattern('terminal')], | ||
| appName: 'Terminal', | ||
| bundleId: 'com.apple.Terminal', | ||
| }, |
There was a problem hiding this comment.
Match iTerm before generic Terminal context
The generic Terminal rule is evaluated before the iTerm rule, so prompts that explicitly mention iTerm but also contain "terminal" (for example, "open terminal in iterm2") resolve to Terminal instead of iTerm. Since first match wins and the result is used to enforce app scope, this ordering can lock the session to the wrong bundle ID.
Useful? React with 👍 / 👎.
| return new RegExp( | ||
| `(?:(?:(?:open|launch|switch\\s+to|in|test|qa|check|use)\\s+)${word}|${word}\\s+app)\\b`, | ||
| 'i', |
There was a problem hiding this comment.
🔴 Missing word boundary in contextPattern causes false-positive app matches on substring verb matches
The contextPattern function at assistant/src/daemon/target-app-hints.ts:17-25 builds a regex without a \b word boundary before the action verb group, causing the verbs (open, launch, in, test, qa, check, use) to match as substrings within other words. This leads to incorrect app hint resolution.
Root Cause and Impact
The generated regex pattern is:
(?:(?:(?:open|launch|switch\s+to|in|test|qa|check|use)\s+)WORD|WORD\s+app)\b
Since there's no \b before the verb alternation, the verb in matches inside words like "login", "begin", "certain", "domain", "main", "plain", "explain". Similarly, test matches inside "latest", check inside "recheck", use inside "misuse", open inside "reopen", and launch inside "relaunch".
Additionally, the second alternative WORD\s+app also lacks a \b before WORD, so "email app" falsely matches Mail and "denotes app" falsely matches Notes.
Concrete false positives in production:
"login terminal and check credentials"→ incorrectly resolves to Terminal app"domain mail server configuration"→ incorrectly resolves to Mail app"main settings page needs updating"→ incorrectly resolves to System Settings"latest terminal update"→ incorrectly resolves to Terminal app"explain messages protocol"→ incorrectly resolves to Messages app
Impact: When resolveComputerUseTargetAppHint returns a false positive, the CU session gets locked to the wrong app via targetAppName/targetAppBundleId (see assistant/src/daemon/handlers/shared.ts:297 and assistant/src/daemon/handlers/misc.ts:116), causing the computer-use session to target an unintended application.
| return new RegExp( | |
| `(?:(?:(?:open|launch|switch\\s+to|in|test|qa|check|use)\\s+)${word}|${word}\\s+app)\\b`, | |
| 'i', | |
| `(?:(?:(?:^|\\b)(?:open|launch|switch\\s+to|in|test|qa|check|use)\\s+)${word}|\\b${word}\\s+app)\\b`, | |
| 'i', | |
Was this helpful? React with 👍 or 👎 to provide feedback.
|
Addressed in #7457 |
Summary
APP_HINTSarray covering 20+ common macOS apps (browsers, terminals, IDEs, communication tools, productivity apps, Apple built-ins)contextPattern()helper for generic words (notes, mail, terminal, messages, settings) to prevent false positives -- these only match when preceded by action verbs (open/launch/test/qa/in/check/use) or followed by "app"Test plan
bun test src/__tests__/target-app-hints.test.ts🤖 Generated with Claude Code