feat: add /ade command to open agent in browser (#409)
Co-authored-by: Letta <noreply@letta.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { Box, Text } from "ink";
|
||||
import { memo } from "react";
|
||||
import { useTerminalWidth } from "../hooks/useTerminalWidth";
|
||||
import { colors } from "./colors";
|
||||
|
||||
type StatusLine = {
|
||||
kind: "status";
|
||||
@@ -8,6 +9,35 @@ type StatusLine = {
|
||||
lines: string[];
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse text with **highlighted** segments and render with colors.
|
||||
* Text wrapped in ** will be rendered with the accent color.
|
||||
*/
|
||||
function renderColoredText(text: string): React.ReactNode {
|
||||
// Split on **...** pattern, keeping the delimiters
|
||||
const parts = text.split(/(\*\*[^*]+\*\*)/g);
|
||||
|
||||
return parts.map((part, i) => {
|
||||
if (part.startsWith("**") && part.endsWith("**")) {
|
||||
// Remove ** markers and render with accent color
|
||||
const content = part.slice(2, -2);
|
||||
return (
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: Static text parts never reorder
|
||||
<Text key={i} color={colors.footer.agentName}>
|
||||
{content}
|
||||
</Text>
|
||||
);
|
||||
}
|
||||
// Regular dimmed text
|
||||
return (
|
||||
// biome-ignore lint/suspicious/noArrayIndexKey: Static text parts never reorder
|
||||
<Text key={i} dimColor>
|
||||
{part}
|
||||
</Text>
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* StatusMessage - Displays multi-line status messages
|
||||
*
|
||||
@@ -16,6 +46,7 @@ type StatusLine = {
|
||||
* - Where memory blocks came from (global/project/new)
|
||||
*
|
||||
* Layout matches ErrorMessage with a left column icon (grey circle)
|
||||
* Supports **text** syntax for highlighted (accent colored) text.
|
||||
*/
|
||||
export const StatusMessage = memo(({ line }: { line: StatusLine }) => {
|
||||
const columns = useTerminalWidth();
|
||||
@@ -30,7 +61,7 @@ export const StatusMessage = memo(({ line }: { line: StatusLine }) => {
|
||||
<Text dimColor>{idx === 0 ? "●" : " "}</Text>
|
||||
</Box>
|
||||
<Box flexGrow={1} width={contentWidth}>
|
||||
<Text dimColor>{text}</Text>
|
||||
<Text>{renderColoredText(text)}</Text>
|
||||
</Box>
|
||||
</Box>
|
||||
))}
|
||||
|
||||
@@ -55,39 +55,6 @@ type LoadingState =
|
||||
| "selecting_global"
|
||||
| "ready";
|
||||
|
||||
/**
|
||||
* Generate status hints based on session type and block provenance.
|
||||
* Pure function - no React dependencies.
|
||||
*/
|
||||
export function getAgentStatusHints(
|
||||
continueSession: boolean,
|
||||
agentState?: Letta.AgentState | null,
|
||||
_agentProvenance?: AgentProvenance | null,
|
||||
): string[] {
|
||||
const hints: string[] = [];
|
||||
|
||||
// For resumed agents, show memory blocks and --new hint
|
||||
if (continueSession) {
|
||||
if (agentState?.memory?.blocks) {
|
||||
const blocks = agentState.memory.blocks;
|
||||
const count = blocks.length;
|
||||
const labels = blocks
|
||||
.map((b) => b.label)
|
||||
.filter(Boolean)
|
||||
.join(", ");
|
||||
if (labels) {
|
||||
hints.push(
|
||||
`→ Attached ${count} memory block${count !== 1 ? "s" : ""}: ${labels}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
hints.push("→ To create a new agent, use --new");
|
||||
return hints;
|
||||
}
|
||||
|
||||
return hints;
|
||||
}
|
||||
|
||||
export function WelcomeScreen({
|
||||
loadingState,
|
||||
continueSession,
|
||||
|
||||
Reference in New Issue
Block a user