giga-code
Version:
A personal AI CLI assistant powered by Grok for local development.
157 lines • 7.49 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
const react_1 = __importStar(require("react"));
const ink_1 = require("ink");
const api_keys_1 = require("../../utils/api-keys");
function AddMcpServer({ onClose, onAddServer }) {
const [currentField, setCurrentField] = (0, react_1.useState)('name');
const [formData, setFormData] = (0, react_1.useState)({
name: '',
command: '',
args: '',
env: '',
description: ''
});
(0, react_1.useEffect)(() => {
const keys = (0, api_keys_1.loadApiKeys)();
if (keys.exaApiKey) {
setFormData(prev => ({
...prev,
env: `EXA_API_KEY=${keys.exaApiKey}`
}));
}
}, []);
const fields = [
{ key: 'name', label: 'Server Name', placeholder: 'my-server', required: true },
{ key: 'command', label: 'Command', placeholder: 'npx @modelcontextprotocol/server-filesystem', required: true },
{ key: 'args', label: 'Arguments', placeholder: '/path/to/directory (space-separated)', required: false },
{ key: 'env', label: 'Environment', placeholder: 'KEY1=value1 KEY2=value2', required: false },
{ key: 'description', label: 'Description', placeholder: 'Optional description', required: false }
];
const currentFieldIndex = fields.findIndex(f => f.key === currentField);
(0, ink_1.useInput)((inputChar, key) => {
if (key.ctrl && inputChar === "c") {
onClose();
return;
}
if (key.escape) {
onClose();
return;
}
if (key.upArrow) {
const newIndex = currentFieldIndex === 0 ? fields.length - 1 : currentFieldIndex - 1;
setCurrentField(fields[newIndex].key);
return;
}
if (key.downArrow) {
const newIndex = (currentFieldIndex + 1) % fields.length;
setCurrentField(fields[newIndex].key);
return;
}
if (key.tab) {
const newIndex = (currentFieldIndex + 1) % fields.length;
setCurrentField(fields[newIndex].key);
return;
}
if (key.return) {
// If we're on the last field or have required fields filled, submit
if (currentFieldIndex === fields.length - 1 ||
(formData.name.trim() && formData.command.trim())) {
handleSubmit();
}
else {
// Move to next field
const newIndex = (currentFieldIndex + 1) % fields.length;
setCurrentField(fields[newIndex].key);
}
return;
}
if (key.backspace || key.delete) {
setFormData(prev => ({
...prev,
[currentField]: prev[currentField].slice(0, -1)
}));
return;
}
if (inputChar && !key.ctrl && !key.meta) {
setFormData(prev => ({
...prev,
[currentField]: prev[currentField] + inputChar
}));
return;
}
});
const handleSubmit = () => {
if (!formData.name.trim() || !formData.command.trim()) {
return; // Don't submit if required fields are empty
}
const args = formData.args.trim() ? formData.args.trim().split(' ') : undefined;
const env = formData.env.trim() ? parseEnvString(formData.env.trim()) : undefined;
const description = formData.description.trim() || undefined;
onAddServer(formData.name.trim(), formData.command.trim(), args, env, description);
};
const parseEnvString = (envStr) => {
const env = {};
const pairs = envStr.split(' ');
for (const pair of pairs) {
const [key, ...valueParts] = pair.split('=');
if (key && valueParts.length > 0) {
env[key] = valueParts.join('=');
}
}
return env;
};
const canSubmit = formData.name.trim() && formData.command.trim();
return (react_1.default.createElement(ink_1.Box, { flexDirection: "column", paddingX: 2, paddingY: 1 },
react_1.default.createElement(ink_1.Text, { color: "yellow" }, "\u2795 Add MCP Server"),
react_1.default.createElement(ink_1.Box, { marginBottom: 1 },
react_1.default.createElement(ink_1.Text, { color: "gray" }, "Fill in the server configuration:")),
react_1.default.createElement(ink_1.Box, { flexDirection: "column", marginBottom: 1 }, fields.map((field) => {
const isSelected = field.key === currentField;
const value = formData[field.key];
return (react_1.default.createElement(ink_1.Box, { key: field.key, borderStyle: "round", borderColor: isSelected ? "blue" : "gray", paddingX: 1, marginBottom: 1 },
react_1.default.createElement(ink_1.Box, { width: 15 },
react_1.default.createElement(ink_1.Text, { color: isSelected ? "blue" : "white" },
field.label,
field.required ? "*" : "",
":")),
react_1.default.createElement(ink_1.Box, { flexGrow: 1 },
react_1.default.createElement(ink_1.Text, { color: value ? "white" : "gray" },
value || field.placeholder,
isSelected ? "█" : ""))));
})),
react_1.default.createElement(ink_1.Box, { marginBottom: 1 },
react_1.default.createElement(ink_1.Text, { color: canSubmit ? "green" : "red" }, canSubmit ? "✓ Ready to add server" : "❌ Name and command are required")),
react_1.default.createElement(ink_1.Box, { flexDirection: "column", marginTop: 1 },
react_1.default.createElement(ink_1.Text, { color: "gray", dimColor: true }, "\u2022 Use \u2191/\u2193 arrows or Tab to navigate fields"),
react_1.default.createElement(ink_1.Text, { color: "gray", dimColor: true }, "\u2022 Type to edit current field"),
react_1.default.createElement(ink_1.Text, { color: "gray", dimColor: true },
"\u2022 Press Enter to ",
canSubmit ? "add server" : "go to next field"),
react_1.default.createElement(ink_1.Text, { color: "gray", dimColor: true }, "\u2022 Press Esc to cancel"))));
}
exports.default = AddMcpServer;
//# sourceMappingURL=add-mcp-server.js.map