mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-07-10 10:00:53 -07:00
chore: update channels
This commit is contained in:
@@ -575,6 +575,7 @@ describe('gemini.tsx main function kitty protocol', () => {
|
||||
rawOutput: undefined,
|
||||
acceptRawOutputRisk: undefined,
|
||||
isCommand: undefined,
|
||||
channels: undefined,
|
||||
});
|
||||
|
||||
await act(async () => {
|
||||
|
||||
@@ -285,13 +285,6 @@ export async function main() {
|
||||
});
|
||||
}
|
||||
|
||||
if (argv.channels && argv.channels.length > 0) {
|
||||
coreEvents.emitFeedback(
|
||||
'info',
|
||||
`Channels listening for messages: ${argv.channels.join(', ')}`,
|
||||
);
|
||||
}
|
||||
|
||||
// Check for invalid input combinations early to prevent crashes
|
||||
if (argv.promptInteractive && !process.stdin.isTTY) {
|
||||
writeToStderr(
|
||||
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
} from './types.js';
|
||||
import { checkPermissions } from './hooks/atCommandProcessor.js';
|
||||
import { MessageType, StreamingState } from './types.js';
|
||||
import { theme } from './semantic-colors.js';
|
||||
import { ToolActionsProvider } from './contexts/ToolActionsContext.js';
|
||||
import {
|
||||
type StartupWarning,
|
||||
@@ -66,7 +67,6 @@ import {
|
||||
flattenMemory,
|
||||
type MemoryChangedPayload,
|
||||
type ChannelMessagePayload,
|
||||
activeChannels,
|
||||
writeToStdout,
|
||||
disableMouseEvents,
|
||||
enterAlternateScreen,
|
||||
@@ -1233,22 +1233,6 @@ Logging in with Google... Restarting Gemini CLI to continue.
|
||||
};
|
||||
}, [channelsEnabled, addMessage]);
|
||||
|
||||
// Warn about requested channels whose MCP servers did not declare capability.
|
||||
const channelWarningFired = useRef(false);
|
||||
useEffect(() => {
|
||||
if (!isMcpReady || !channelsEnabled || channelWarningFired.current) return;
|
||||
channelWarningFired.current = true;
|
||||
const requested = config.getChannels();
|
||||
for (const name of requested) {
|
||||
if (!activeChannels.has(name)) {
|
||||
coreEvents.emitFeedback(
|
||||
'warning',
|
||||
`Channel "${name}" was requested but the MCP server did not declare channel capability.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [isMcpReady, channelsEnabled, config]);
|
||||
|
||||
cancelHandlerRef.current = useCallback(
|
||||
(shouldRestorePrompt: boolean = true) => {
|
||||
if (isToolAwaitingConfirmation(pendingHistoryItems)) {
|
||||
@@ -2011,10 +1995,16 @@ Logging in with Google... Restarting Gemini CLI to continue.
|
||||
);
|
||||
}
|
||||
|
||||
const isChannel = payload.style === 'channel';
|
||||
historyManager.addItem(
|
||||
{
|
||||
type,
|
||||
text: payload.message,
|
||||
...(isChannel && {
|
||||
icon: '» ',
|
||||
color: theme.text.secondary,
|
||||
marginTop: 0,
|
||||
}),
|
||||
},
|
||||
Date.now(),
|
||||
);
|
||||
|
||||
@@ -119,6 +119,7 @@ export const HistoryItemDisplay: React.FC<HistoryItemDisplayProps> = ({
|
||||
secondaryText={itemForDisplay.secondaryText}
|
||||
icon={itemForDisplay.icon}
|
||||
color={itemForDisplay.color}
|
||||
marginTop={itemForDisplay.marginTop}
|
||||
marginBottom={itemForDisplay.marginBottom}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -14,6 +14,7 @@ interface InfoMessageProps {
|
||||
secondaryText?: string;
|
||||
icon?: string;
|
||||
color?: string;
|
||||
marginTop?: number;
|
||||
marginBottom?: number;
|
||||
}
|
||||
|
||||
@@ -22,6 +23,7 @@ export const InfoMessage: React.FC<InfoMessageProps> = ({
|
||||
secondaryText,
|
||||
icon,
|
||||
color,
|
||||
marginTop,
|
||||
marginBottom,
|
||||
}) => {
|
||||
color ??= theme.status.warning;
|
||||
@@ -29,7 +31,11 @@ export const InfoMessage: React.FC<InfoMessageProps> = ({
|
||||
const prefixWidth = prefix.length;
|
||||
|
||||
return (
|
||||
<Box flexDirection="row" marginTop={1} marginBottom={marginBottom ?? 0}>
|
||||
<Box
|
||||
flexDirection="row"
|
||||
marginTop={marginTop ?? 1}
|
||||
marginBottom={marginBottom ?? 0}
|
||||
>
|
||||
<Box width={prefixWidth}>
|
||||
<Text color={color}>{prefix}</Text>
|
||||
</Box>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
import type React from 'react';
|
||||
import { Box, Text } from 'ink';
|
||||
import { theme } from '../../semantic-colors.js';
|
||||
import { RenderInline } from '../../utils/InlineMarkdownRenderer.js';
|
||||
import type { ChannelInfo } from '../../types.js';
|
||||
|
||||
interface ChannelsListProps {
|
||||
@@ -18,10 +19,11 @@ export const ChannelsList: React.FC<ChannelsListProps> = ({ channels }) => {
|
||||
return (
|
||||
<Box flexDirection="column" marginBottom={1}>
|
||||
<Text color={theme.text.primary}>No active channels.</Text>
|
||||
<Text color="gray">
|
||||
{
|
||||
"MCP servers must declare `experimental['gemini/channel']` in their capabilities to act as channels."
|
||||
}
|
||||
<Text color={theme.text.secondary}>
|
||||
<RenderInline
|
||||
text="Use `--channels <name>` to listen for channel messages from MCP servers."
|
||||
defaultColor={theme.text.secondary}
|
||||
/>
|
||||
</Text>
|
||||
</Box>
|
||||
);
|
||||
@@ -41,9 +43,11 @@ export const ChannelsList: React.FC<ChannelsListProps> = ({ channels }) => {
|
||||
<Text bold color={theme.text.accent}>
|
||||
{channel.displayName || channel.name} ({channel.name})
|
||||
</Text>
|
||||
<Text color="gray">
|
||||
<Text color={theme.text.secondary}>
|
||||
Direction:{' '}
|
||||
<Text color={channel.supportsReply ? 'green' : 'gray'}>
|
||||
<Text
|
||||
color={channel.supportsReply ? 'green' : theme.text.secondary}
|
||||
>
|
||||
{channel.supportsReply ? 'two-way' : 'one-way'}
|
||||
</Text>
|
||||
</Text>
|
||||
|
||||
@@ -173,6 +173,7 @@ export type HistoryItemInfo = HistoryItemBase & {
|
||||
secondaryText?: string;
|
||||
icon?: string;
|
||||
color?: string;
|
||||
marginTop?: number;
|
||||
marginBottom?: number;
|
||||
};
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ import {
|
||||
type TelemetryTarget,
|
||||
} from '../telemetry/index.js';
|
||||
import { coreEvents, CoreEvent } from '../utils/events.js';
|
||||
import { activeChannels } from '../channels/types.js';
|
||||
import { tokenLimit } from '../core/tokenLimits.js';
|
||||
import {
|
||||
DEFAULT_GEMINI_EMBEDDING_MODEL,
|
||||
@@ -1380,6 +1381,26 @@ export class Config implements McpContext, AgentLoopContext {
|
||||
debugLogger.error('Error initializing MCP clients:', result.reason);
|
||||
}
|
||||
}
|
||||
// Report channel status after all MCP servers have initialized.
|
||||
if (this.channels.length > 0) {
|
||||
const active = this.channels.filter((name) => activeChannels.has(name));
|
||||
if (active.length > 0) {
|
||||
coreEvents.emitFeedback(
|
||||
'info',
|
||||
`Channels listening for messages: ${active.join(', ')}`,
|
||||
undefined,
|
||||
{ style: 'channel' },
|
||||
);
|
||||
}
|
||||
for (const name of this.channels) {
|
||||
if (!activeChannels.has(name)) {
|
||||
coreEvents.emitFeedback(
|
||||
'warning',
|
||||
`Channel "${name}" was requested but the MCP server did not declare channel capability.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (!this.interactive || this.acpMode) {
|
||||
|
||||
@@ -41,6 +41,12 @@ export interface UserFeedbackPayload {
|
||||
* or verbose output, while keeping the 'message' field clean for end users.
|
||||
*/
|
||||
error?: unknown;
|
||||
/**
|
||||
* Optional semantic style hint for the UI.
|
||||
* 'channel' renders with secondary text color and a » icon,
|
||||
* suitable for channel status messages.
|
||||
*/
|
||||
style?: 'channel';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -285,8 +291,14 @@ export class CoreEventEmitter extends EventEmitter<CoreEvents> {
|
||||
severity: FeedbackSeverity,
|
||||
message: string,
|
||||
error?: unknown,
|
||||
options?: { style?: 'channel' },
|
||||
): void {
|
||||
const payload: UserFeedbackPayload = { severity, message, error };
|
||||
const payload: UserFeedbackPayload = {
|
||||
severity,
|
||||
message,
|
||||
error,
|
||||
...options,
|
||||
};
|
||||
this._emitOrQueue(CoreEvent.UserFeedback, payload);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user