165 lines
5.4 KiB
JavaScript
165 lines
5.4 KiB
JavaScript
#!/usr/bin/env node
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
import os from 'node:os';
|
|
|
|
const CONFIG_FILE = path.join(os.homedir(), '.xflow.json');
|
|
|
|
interface XFlowConfig {
|
|
serverUrl: string;
|
|
userId: string;
|
|
apiKey?: string;
|
|
}
|
|
|
|
function loadConfig(): XFlowConfig {
|
|
if (fs.existsSync(CONFIG_FILE)) {
|
|
try {
|
|
return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));
|
|
} catch {
|
|
// fallback
|
|
}
|
|
}
|
|
return {
|
|
serverUrl: process.env.XFLOW_SERVER_URL || 'http://localhost:3000',
|
|
userId: process.env.XFLOW_USER_ID || 'default-user'
|
|
};
|
|
}
|
|
|
|
function saveConfig(config: XFlowConfig) {
|
|
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8');
|
|
console.log(`[XFlow] Настройки сохранены в ${CONFIG_FILE}`);
|
|
}
|
|
|
|
async function addNote(title: string, listTitle: string = 'Фильмы', category: string = 'movies') {
|
|
const config = loadConfig();
|
|
const url = `${config.serverUrl.replace(/\/$/, '')}/api/v1/lists/items`;
|
|
|
|
console.log(`[XFlow Desktop] Отправка заметки: "${title}" в список "${listTitle}"...`);
|
|
|
|
try {
|
|
const res = await fetch(url, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({
|
|
title,
|
|
listTitle,
|
|
category,
|
|
ownerId: config.userId
|
|
})
|
|
});
|
|
|
|
const data = await res.json() as any;
|
|
if (res.ok && data.success) {
|
|
console.log(`\x1b[32m✔ Успешно добавлено!\x1b[0m ID: ${data.item.id}, Статус: ${data.item.status}`);
|
|
console.log(` Синхронизировано с сервером и отправлено на мобильный клиент.`);
|
|
} else {
|
|
console.error(`\x1b[31m✖ Ошибка сервера:\x1b[0m`, data.message || data);
|
|
}
|
|
} catch (err: any) {
|
|
console.error(`\x1b[31m✖ Не удалось связаться с сервером XFlow (${config.serverUrl}):\x1b[0m ${err.message}`);
|
|
console.log(` Убедитесь, что сервер XFlow запущен на ${config.serverUrl}`);
|
|
}
|
|
}
|
|
|
|
async function listNotes(category?: string) {
|
|
const config = loadConfig();
|
|
const query = category ? `?category=${encodeURIComponent(category)}` : '';
|
|
const url = `${config.serverUrl.replace(/\/$/, '')}/api/v1/lists${query}`;
|
|
|
|
try {
|
|
const res = await fetch(url);
|
|
const data = await res.json() as any;
|
|
if (res.ok && data.success) {
|
|
console.log(`\n\x1b[1m=== Списки XFlow ===\x1b[0m`);
|
|
for (const list of data.lists) {
|
|
console.log(`\n📂 \x1b[36m${list.title}\x1b[0m (${list.category}) [${list.items?.length || 0} элементов]:`);
|
|
for (const item of list.items || []) {
|
|
const check = item.isCompleted ? '☑' : '☐';
|
|
console.log(` ${check} ${item.title} \x1b[90m(статус: ${item.status})\x1b[0m`);
|
|
}
|
|
}
|
|
console.log('');
|
|
} else {
|
|
console.error(`Ошибка:`, data.message);
|
|
}
|
|
} catch (err: any) {
|
|
console.error(`Ошибка связи с сервером: ${err.message}`);
|
|
}
|
|
}
|
|
|
|
async function main() {
|
|
const args = process.argv.slice(2);
|
|
const command = args[0];
|
|
|
|
if (!command || command === '--help' || command === '-h') {
|
|
console.log(`
|
|
\x1b[1m🚀 XFlow CLI — Native Desktop & Terminal Agent Bridge\x1b[0m
|
|
|
|
Использование:
|
|
xflow movie "<название фильма>" Быстро добавить фильм в список на просмотр
|
|
xflow add "<заметка>" [--list <список>] Добавить элемент в указанный список
|
|
xflow list [категория] Показать списки и элементы
|
|
xflow config --url <url> --user <id> Настроить подключение к серверу XFlow
|
|
|
|
Примеры:
|
|
xflow movie "Интерстеллар"
|
|
xflow add "Купить молоко" --list "Покупки"
|
|
xflow list
|
|
`);
|
|
return;
|
|
}
|
|
|
|
if (command === 'movie') {
|
|
const title = args.slice(1).join(' ');
|
|
if (!title) {
|
|
console.error('Укажите название фильма: xflow movie "Интерстеллар"');
|
|
return;
|
|
}
|
|
await addNote(title, 'Фильмы на просмотр', 'movies');
|
|
return;
|
|
}
|
|
|
|
if (command === 'add') {
|
|
const title = args[1];
|
|
let listTitle = 'Общий список';
|
|
let category = 'general';
|
|
|
|
for (let i = 2; i < args.length; i++) {
|
|
if (args[i] === '--list' && args[i + 1]) {
|
|
listTitle = args[i + 1];
|
|
if (listTitle.toLowerCase().includes('фильм')) category = 'movies';
|
|
if (listTitle.toLowerCase().includes('покупк')) category = 'shopping';
|
|
}
|
|
}
|
|
|
|
if (!title) {
|
|
console.error('Укажите текст заметки: xflow add "Заметка"');
|
|
return;
|
|
}
|
|
await addNote(title, listTitle, category);
|
|
return;
|
|
}
|
|
|
|
if (command === 'list') {
|
|
const category = args[1];
|
|
await listNotes(category);
|
|
return;
|
|
}
|
|
|
|
if (command === 'config') {
|
|
const config = loadConfig();
|
|
for (let i = 1; i < args.length; i++) {
|
|
if (args[i] === '--url' && args[i + 1]) config.serverUrl = args[i + 1];
|
|
if (args[i] === '--user' && args[i + 1]) config.userId = args[i + 1];
|
|
}
|
|
saveConfig(config);
|
|
return;
|
|
}
|
|
|
|
console.error(`Неизвестная команда: ${command}. Используйте --help`);
|
|
}
|
|
|
|
main().catch(console.error);
|