Skip to content
Merged
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
3 changes: 3 additions & 0 deletions src/assets/images/jules.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/main/core/agent-hooks/classifiers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { createDroidClassifier } from './droid';
import { createGeminiClassifier } from './gemini';
import { createGenericClassifier } from './generic';
import { createGooseClassifier } from './goose';
import { createJulesClassifier } from './jules';
import { createJunieClassifier } from './junie';
import { createKilocodeClassifier } from './kilocode';
import { createKimiClassifier } from './kimi';
Expand All @@ -40,6 +41,7 @@ const classifierFactories: Partial<Record<AgentProviderId, () => ProviderClassif
droid: createDroidClassifier,
gemini: createGeminiClassifier,
goose: createGooseClassifier,
jules: createJulesClassifier,
junie: createJunieClassifier,
kilocode: createKilocodeClassifier,
kimi: createKimiClassifier,
Expand Down
43 changes: 43 additions & 0 deletions src/main/core/agent-hooks/classifiers/jules.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { createProviderClassifier, type ClassificationResult } from './base';

export function createJulesClassifier() {
return createProviderClassifier((text: string): ClassificationResult => {
const tail = text.slice(-500);

if (/approve|reject|permission|allow|confirm/i.test(tail)) {
return {
type: 'notification',
notificationType: 'permission_prompt',
};
}

if (/Ready|Awaiting|Press Enter|Jules/i.test(tail)) {
return {
type: 'notification',
notificationType: 'idle_prompt',
};
}
Comment on lines +14 to +19

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 The bare Jules word in the idle_prompt regex will fire a false idle notification any time Jules prints its own name — for example during normal progress output like "Jules is analyzing your codebase…" or "Jules created a new remote session". All other classifiers in this repo use a specific terminal-prompt anchor (e.g., goose\s*>) rather than the tool's own name. This will cause spurious idle notifications during normal Jules operation.

Suggested change
if (/Ready|Awaiting|Press Enter|Jules/i.test(tail)) {
return {
type: 'notification',
notificationType: 'idle_prompt',
};
}
if (/Ready|Awaiting|Press Enter|jules\s*[>$]/i.test(tail)) {
return {
type: 'notification',
notificationType: 'idle_prompt',
};
}
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/main/core/agent-hooks/classifiers/jules.ts
Line: 14-19

Comment:
The bare `Jules` word in the `idle_prompt` regex will fire a false idle notification any time Jules prints its own name — for example during normal progress output like "Jules is analyzing your codebase…" or "Jules created a new remote session". All other classifiers in this repo use a specific terminal-prompt anchor (e.g., `goose\s*>`) rather than the tool's own name. This will cause spurious idle notifications during normal Jules operation.

```suggestion
    if (/Ready|Awaiting|Press Enter|jules\s*[>$]/i.test(tail)) {
      return {
        type: 'notification',
        notificationType: 'idle_prompt',
      };
    }
```

How can I resolve this? If you propose a fix, please make it concise.


if (/Successfully authenticated|Login successful|Signed in/i.test(text)) {
return {
type: 'notification',
notificationType: 'auth_success',
};
}

if (/What.*\?|How.*\?|Which.*\?|Please (provide|specify|clarify)/i.test(tail)) {
return {
type: 'notification',
notificationType: 'elicitation_dialog',
};
}

if (/error:|fatal:|exception|failed/i.test(text)) {
return {
type: 'error',
};
}

return undefined;
});
}
2 changes: 2 additions & 0 deletions src/renderer/lib/providers/meta.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import geminiIcon from '@/assets/images/gemini.png';
import ghcopilotIcon from '@/assets/images/gh-copilot.svg?raw';
import gooseIcon from '@/assets/images/goose.png';
import hermesIcon from '@/assets/images/hermesagent.jpg';
import julesIcon from '@/assets/images/jules.svg?raw';
import junieIcon from '@/assets/images/junie-color.png';
import kilocodeIcon from '@/assets/images/kilocode.png';
import kimiIcon from '@/assets/images/kimi.png';
Expand Down Expand Up @@ -42,6 +43,7 @@ const ICONS: Record<string, string> = {
'gh-copilot.svg': ghcopilotIcon,
'goose.png': gooseIcon,
'hermesagent.jpg': hermesIcon,
'jules.svg': julesIcon,
'junie-color.png': junieIcon,
'kimi.png': kimiIcon,
'kilocode.png': kilocodeIcon,
Expand Down
7 changes: 7 additions & 0 deletions src/renderer/utils/agentConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import geminiLogo from '../../assets/images/gemini.png';
import copilotLogoSvg from '../../assets/images/gh-copilot.svg?raw';
import gooseLogo from '../../assets/images/goose.png';
import hermesLogo from '../../assets/images/hermesagent.jpg';
import julesLogoSvg from '../../assets/images/jules.svg?raw';
import junieLogo from '../../assets/images/junie-color.png';
import kilocodeLogo from '../../assets/images/kilocode.png';
import kimiLogo from '../../assets/images/kimi.png';
Expand Down Expand Up @@ -55,6 +56,12 @@ export const agentConfig: Record<AgentProviderId, AgentInfo> = {
cline: { name: 'Cline', logo: clineLogo, alt: 'Cline CLI' },
continue: { name: 'Continue', logo: continueLogo, alt: 'Continue CLI' },
codebuff: { name: 'Codebuff', logo: codebuffLogo, alt: 'Codebuff CLI' },
jules: {
name: 'Jules',
logo: julesLogoSvg,
alt: 'Jules CLI',
isSvg: true,
},
junie: {
name: 'Junie CLI',
logo: junieLogo,
Expand Down
17 changes: 17 additions & 0 deletions src/shared/agent-provider-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export const AGENT_PROVIDER_IDS = [
'continue',
'codebuff',
'mistral',
'jules',
'junie',
'pi',
'autohand',
Expand Down Expand Up @@ -434,6 +435,22 @@ export const AGENT_PROVIDERS: AgentProviderDefinition[] = [
alt: 'Mistral Vibe CLI',
terminalOnly: true,
},
{
id: 'jules',
name: 'Jules',
description:
"Google's Jules CLI for managing asynchronous remote coding sessions and a terminal dashboard.",
docUrl: 'https://jules.google/docs/cli/reference/',
installCommand: 'npm install -g @google/jules',
commands: ['jules'],
versionArgs: ['version'],
cli: 'jules',
initialPromptFlag: '',
useKeystrokeInjection: true,
icon: 'jules.svg',
alt: 'Jules CLI',
terminalOnly: true,
},
{
id: 'junie',
name: 'Junie CLI',
Expand Down
Loading