Files
NetMesh/domain/buildAITerminalSessionInfo.ts
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

107 lines
3.7 KiB
TypeScript

import { classifyDistroId, resolveHostOs } from './host';
import type { PortForwardingRule } from './models';
import type { Host, TerminalSession } from '../types';
export type AITerminalSessionInfo = {
sessionId: string;
hostId: string;
hostname: string;
label: string;
os?: string;
username?: string;
protocol?: string;
shellType?: string;
deviceType?: string;
connected: boolean;
hostChain?: Array<{ hostId: string; label?: string; hostname?: string }>;
activePortForwards?: Array<{
ruleId: string;
label?: string;
type?: string;
localPort?: number;
status?: string;
}>;
};
function summarizeHostChain(
host: Host | undefined,
allHosts: Host[],
): AITerminalSessionInfo['hostChain'] | undefined {
if (!host?.hostChain?.hostIds?.length) return undefined;
return host.hostChain.hostIds.map((hostId) => {
const jumpHost = allHosts.find((entry) => entry.id === hostId);
return {
hostId,
label: jumpHost?.label,
hostname: jumpHost?.hostname,
};
});
}
export const buildAITerminalSessionInfo = (
session: TerminalSession | undefined,
host: Host | undefined,
localOs: 'linux' | 'macos' | 'windows',
options?: {
allHosts?: Host[];
portForwardingRules?: PortForwardingRule[];
},
): AITerminalSessionInfo => {
const protocol = session?.protocol || host?.protocol;
const isLocalSession = protocol === 'local' || session?.hostId?.startsWith('local-');
const allHosts = options?.allHosts ?? (host ? [host] : []);
const hostChain = summarizeHostChain(host, allHosts);
const activePortForwards = host?.id && options?.portForwardingRules
? options.portForwardingRules
.filter((rule) => rule.hostId === host.id && (rule.status === 'active' || rule.status === 'connecting'))
.map((rule) => ({
ruleId: rule.id,
label: rule.label,
type: rule.type,
localPort: rule.localPort,
status: rule.status,
}))
: undefined;
// Mosh / ET sessions always run over a shell-backed PTY and cannot reach a
// vendor CLI, so network device mode never applies to them.
const isMoshOrEt = Boolean(
session?.moshEnabled || host?.moshEnabled || session?.etEnabled || host?.etEnabled,
);
// Report 'network' when the host is explicitly a network device OR when the
// detected distro/vendor classifies as one (Huawei VRP, Cisco IOS, ...). This
// mirrors the terminal's own gating (Terminal.tsx / systemTarget.ts) so AI
// exec skips shell wrapping (routing to the raw-PTY path) and the system
// prompt gets vendor-CLI guidance even before the user manually flips
// Network Device Mode (#2367).
const isNetworkDevice = host?.deviceType === 'network'
|| classifyDistroId(host?.distro) === 'network-device';
const deviceType = isMoshOrEt
? undefined
: (isNetworkDevice ? 'network' : host?.deviceType);
return {
sessionId: session?.id || '',
hostId: session?.hostId || '',
hostname: host?.hostname || session?.hostname || '',
label: host?.label || session?.hostLabel || '',
os: isLocalSession ? localOs : resolveHostOs(host),
username: host?.username || session?.username,
protocol,
shellType: session?.shellType && session.shellType !== 'unknown' ? session.shellType : undefined,
deviceType,
connected: session?.status === 'connected',
...(hostChain?.length ? { hostChain } : {}),
...(activePortForwards?.length ? { activePortForwards } : {}),
};
};
export type AIPanelContext = {
scopeType: 'terminal' | 'workspace';
scopeTargetId?: string;
scopeHostIds: string[];
scopeLabel: string;
/** Focused pane in a workspace; used to inherit AI chat after terminal merge. */
focusedSessionId?: string;
terminalSessions: AITerminalSessionInfo[];
};