@aura-ai/cli
Version:
A Go-to-Market CLI tool for analyzing product positioning and market strategy
135 lines (134 loc) • 6.15 kB
JavaScript
import React, { useState } from 'react';
import { Box, Text, useApp, useInput } from 'ink';
import { TextInput, Alert } from '@inkjs/ui';
import InitCommand from './commands/init.js';
/**
* 6.1 Interactive interface main component
*/
export default function App() {
const [mode, setMode] = useState('input');
const [inputValue, setInputValue] = useState('');
const [commandHistory, setCommandHistory] = useState([]);
const [historyIndex, setHistoryIndex] = useState(-1);
const [error, setError] = useState('');
const { exit } = useApp();
// 6.3 Command definitions
const commands = [
{
name: '/init',
description: 'Analyze a project repository and generate GTM insights',
handler: () => setMode('init')
},
{
name: '/help',
description: 'Show available commands',
handler: () => setMode('help')
},
{
name: '/exit',
description: 'Exit the application',
handler: () => exit()
}
];
// 6.3 Parse and execute command
const handleCommand = (command) => {
const trimmedCommand = command.trim().toLowerCase();
// Add to history
if (trimmedCommand && !commandHistory.includes(trimmedCommand)) {
setCommandHistory([...commandHistory, trimmedCommand]);
}
// Reset history navigation
setHistoryIndex(-1);
setInputValue('');
setError('');
// Find and execute command
const matchedCommand = commands.find(cmd => cmd.name === trimmedCommand);
if (matchedCommand) {
matchedCommand.handler();
}
else if (trimmedCommand) {
setError(`Unknown command: ${trimmedCommand}. Type /help for available commands.`);
}
};
// 6.7 Handle command history navigation
useInput((input, key) => {
if (mode !== 'input')
return;
if (key.upArrow && commandHistory.length > 0) {
const newIndex = historyIndex < commandHistory.length - 1
? historyIndex + 1
: commandHistory.length - 1;
setHistoryIndex(newIndex);
const historyValue = commandHistory[commandHistory.length - 1 - newIndex];
if (historyValue) {
setInputValue(historyValue);
}
}
else if (key.downArrow && historyIndex > 0) {
const newIndex = historyIndex - 1;
setHistoryIndex(newIndex);
const historyValue = commandHistory[commandHistory.length - 1 - newIndex];
if (historyValue) {
setInputValue(historyValue);
}
}
else if (key.downArrow && historyIndex === 0) {
setHistoryIndex(-1);
setInputValue('');
}
});
// Handle return from help mode
useInput((input, key) => {
if (mode === 'help' && (key.return || key.escape)) {
setMode('input');
}
});
// 6.7 Generate autocomplete suggestions
const getSuggestions = () => {
if (!inputValue.startsWith('/'))
return [];
return commands
.map(cmd => cmd.name)
.filter(name => name.startsWith(inputValue.toLowerCase()))
.slice(0, 3);
};
// Render based on current mode
switch (mode) {
case 'init':
// 6.4 Render init command
return (React.createElement(Box, { flexDirection: "column" },
React.createElement(InitCommand, null),
React.createElement(Box, { marginTop: 1 },
React.createElement(Text, { dimColor: true }, "Press Ctrl+C to return to interactive mode"))));
case 'help':
// 6.5 Display help
return (React.createElement(Box, { flexDirection: "column" },
React.createElement(Text, { bold: true, color: "cyan" }, "\uD83D\uDE80 Aura CLI - Available Commands"),
React.createElement(Box, { marginTop: 1, flexDirection: "column" }, commands.map((cmd) => (React.createElement(Box, { key: cmd.name, marginBottom: 1 },
React.createElement(Text, { color: "green" }, cmd.name.padEnd(10)),
React.createElement(Text, { dimColor: true }, cmd.description))))),
React.createElement(Box, { marginTop: 1 },
React.createElement(Text, { dimColor: true }, "Press Enter or Escape to return..."))));
case 'input':
default: {
// 6.2 Main input interface
const suggestions = getSuggestions();
return (React.createElement(Box, { flexDirection: "column" },
React.createElement(Box, { marginBottom: 1 },
React.createElement(Text, { bold: true, color: "cyan" }, "\uD83D\uDE80 Aura CLI"),
React.createElement(Text, { dimColor: true }, " - Type /help for commands")),
error && (React.createElement(Box, { marginBottom: 1 },
React.createElement(Alert, { variant: "error" }, error))),
suggestions.length > 0 && (React.createElement(Box, { marginBottom: 1, flexDirection: "column" },
React.createElement(Text, { dimColor: true }, "Suggestions:"),
suggestions.map((suggestion) => (React.createElement(Text, { key: suggestion, color: "gray" },
" ",
suggestion))))),
React.createElement(Box, null,
React.createElement(Text, { color: "green" }, "\u276F "),
React.createElement(TextInput, { key: `input-${historyIndex}`, defaultValue: inputValue, onChange: (value) => setInputValue(value), onSubmit: handleCommand, placeholder: "Type a command (e.g., /init)", suggestions: suggestions })),
commandHistory.length > 0 && (React.createElement(Box, { marginTop: 1 },
React.createElement(Text, { dimColor: true }, "\u2191\u2193 to navigate history \u2022 Ctrl+C to exit")))));
}
}
}