Skip to Content
👋 Добро пожаловать в документацию lite-fsm!
Пакеты@lite-fsm/cli

@lite-fsm/cli

@lite-fsm/cli предоставляет команду lite-fsm для работы с проектом из терминала. В alpha-версии пакет умеет создавать React starter-проекты, добавлять автоматы в generated store, строить project graph по TypeScript-файлам проекта и запускать локальный Visualizer с готовой graph-сессией.

Команды create и add-machine пишут файлы проекта. Команды export-graph и visualize используют @lite-fsm/graph: находят MachineManager, определяют автоматы, переданные в этот менеджер, строят граф состояний, переходов, reducer-веток и событий effects. CLI не запускает приложение и не выполняет пользовательский код.

Пакет находится в alpha-версии.

Установка

npm install --save-dev @lite-fsm/cli

После установки доступна команда lite-fsm.

Для одноразового запуска без установки в проект можно использовать npx @lite-fsm/cli ....

Команды

КомандаНазначение
createСоздать Next.js или Vite React starter, уже подключенный к lite-fsm
add-machineДобавить доменный автомат в generated src/store
export-graphПостроить project graph и записать JSON export document
visualizeПостроить project graph, поднять локальный Visualizer и открыть graph-сессию проекта

Быстрый старт с нуля

npx @lite-fsm/cli create my-app --template vite cd my-app npx @lite-fsm/cli add-machine user-session npm run dev

Этот сценарий создаёт starter с базовым автоматом app, затем добавляет отдельный автомат userSession. Для Next.js используйте --template next.

Команда create

lite-fsm create my-app --template vite

create создаёт React starter на базе Vite или Next.js и добавляет готовый lite-fsm store под src/store. Проект получает @lite-fsm/core, @lite-fsm/react, @lite-fsm/middleware, immer, typed helper createMachine, React hooks и минимальный автомат app.

Команда вызывает framework scaffold (create-vite или create-next-app), патчит entrypoint приложения, добавляет FSMContextProvider, настраивает alias @/* и по умолчанию устанавливает зависимости.

Примеры:

lite-fsm create my-app --template next lite-fsm create . --template next lite-fsm create my-app --template vite --css none lite-fsm create apps/demo --template vite --package-manager pnpm --no-install

<project-name> должен быть относительным путём внутри текущей директории или . для генерации в текущую директорию. Для новых директорий родительская директория должна существовать, а целевая директория — отсутствовать.

Опции create

ОпцияОбязательнаНазначение
<project-name>ДаОтносительная директория проекта, например my-app, apps/demo или .
--template <next|vite>ДаFramework starter: Next.js App Router или Vite React
--css <tailwind|none>НетCSS preset; по умолчанию tailwind
--package-manager <pnpm|npm|yarn|bun>НетPackage manager для scaffold, install и next steps; по умолчанию npm
--install / --no-installНетУстановить зависимости после генерации или пропустить install; по умолчанию install включен

Generated store

create добавляет одинаковую структуру store для Next.js и Vite:

src/store/ create-machine.ts deps.ts hooks.ts index.ts types.ts machines/app.ts

src/store/index.ts экспортирует machines, makeStore, AppState, AppStore, hooks и типы. Автомат app принимает событие DO_INIT и показывает минимальный паттерн: общий AppEvents, typed createMachine, MachineManager с immerMiddleware и dependencies через manager.setDependencies(...).

Команда add-machine

lite-fsm add-machine user-session

add-machine запускается из корня проекта, созданного через lite-fsm create. Команда создаёт файл автомата, регистрирует его в src/store/index.ts и добавляет namespace событий в src/store/types.ts.

Для user-session результат выглядит так:

src/store/machines/user-session.ts src/store/index.ts src/store/types.ts

Новый автомат экспортируется как userSession, а стартовое событие получает имя DO_USER_SESSION_INIT.

Команда принимает имена в kebab-case, snake_case и camelCase:

ВводФайлExportСобытие
user-sessionuser-session.tsuserSessionDO_USER_SESSION_INIT
user_sessionuser-session.tsuserSessionDO_USER_SESSION_INIT
userSessionuser-session.tsuserSessionDO_USER_SESSION_INIT
checkoutcheckout.tscheckoutDO_CHECKOUT_INIT

add-machine рассчитан на generated store shape из lite-fsm create: должны существовать src/store/create-machine.ts, src/store/index.ts, src/store/types.ts и src/store/machines. Если store был сильно переписан, CLI вернёт diagnostic и попросит обновить регистрацию вручную.

Опции add-machine

ОпцияОбязательнаНазначение
<name>ДаИмя автомата: ASCII kebab-case, snake_case или camelCase, начинается с буквы

Команда export-graph

lite-fsm export-graph --entry store/index.ts --out lite-fsm.graph.json --tsconfig tsconfig.json

export-graph строит проектный граф и записывает JSON-файл. Это основной способ подготовить данные для визуализатора, проверок и собственных инструментов анализа.

Команда принимает входной TypeScript-файл, ищет в нем выбранный MachineManager(...), затем проходит по импортам, которые нужны для автоматов этого менеджера.

Минимальный пример

// store/index.ts import { MachineManager, createMachine } from "@lite-fsm/core"; export const lamp = createMachine({ config: { off: { SWITCH: "on" }, on: { SWITCH: "off" }, }, initialState: "off", initialContext: {}, }); export const manager = MachineManager({ lamp });
lite-fsm export-graph --entry store/index.ts --out lite-fsm.graph.json

Результат будет записан в lite-fsm.graph.json.

Опции export-graph

ОпцияОбязательнаНазначение
--entry <path>ДаВходной TypeScript-файл, где виден выбранный MachineManager(...)
--out <path>ДаПуть к JSON-файлу, который нужно записать
--tsconfig <path>НетЯвный tsconfig.json для разрешения импортов
--include-sourceНетДобавить исходный текст найденных файлов в JSON

Значение --out - не поддерживается. Здесь - — это не пустой путь, а специальное значение, которое в некоторых CLI означает «вывести результат в терминал». lite-fsm export-graph так не работает: передайте обычный путь к файлу, например --out lite-fsm.graph.json.

Входной файл

--entry указывает на файл, от которого начинается обход проекта. Обычно это файл, где создается основной MachineManager.

Поддерживаемый вариант:

import { MachineManager } from "@lite-fsm/core"; import { auth } from "./machines/auth"; import { profile } from "./machines/profile"; export const manager = MachineManager({ auth, profile, });

CLI ожидает, что карта автоматов в MachineManager читается статически: через объект, локальную константу, поддерживаемые именованные импорты или повторные экспорты. Если карта строится динамически, команда вернёт диагностику о неполном статическом анализе.

На этом этапе проектный обход рассчитан на .ts файлы. Импорты с неподдерживаемым расширением попадают в диагностику.

Работа с tsconfig

lite-fsm export-graph --entry src/store/index.ts --out graph.json --tsconfig tsconfig.json

Если --tsconfig передан явно, CLI использует именно этот файл. Если файл не найден или содержит ошибку, команда завершится с ошибкой.

Если --tsconfig не передан, CLI ищет ближайший tsconfig.json от папки входного файла вверх по дереву каталогов. Если файл найден, команда использует его compilerOptions, включая baseUrl и paths.

Если tsconfig.json не найден, CLI использует настройки разрешения импортов по умолчанию и добавляет информационную диагностику LFC_TSCONFIG_NOT_FOUND в export document.

Включение исходников

lite-fsm export-graph --entry store/index.ts --out lite-fsm.graph.json --include-source

Без --include-source JSON содержит только граф, список найденных файлов, их роли и хеши. Исходный текст файлов в результат не попадает.

С --include-source команда добавляет sources.files[]:

{ "sources": { "files": [ { "fileName": "store/index.ts", "language": "ts", "hash": "abc", "text": "import { MachineManager } from \"@lite-fsm/core\";" } ] } }

Эта опция полезна для интерфейсов, которые показывают граф вместе с исходным кодом. Для публичных артефактов включайте ее осознанно: JSON будет содержать текст файлов проекта.

Команда visualize

lite-fsm visualize --entry store/index.ts

visualize строит project graph, создает локальную сессию и запускает встроенный Visualizer на 127.0.0.1. По умолчанию команда использует порт 3030, открывает браузер, печатает URL вида http://127.0.0.1:3030/?session=... и держит процесс запущенным до SIGINT или SIGTERM.

Команда не записывает JSON-файл. Graph document передается Visualizer-у через локальный API с session token из URL, а исходники читаются по запросу только для файлов, которые попали в текущий graph document.

Опции visualize

ОпцияОбязательнаНазначение
--entry <path>ДаВходной TypeScript-файл, где виден выбранный MachineManager(...)
--tsconfig <path>НетЯвный tsconfig.json для разрешения импортов
--port <number>НетПорт локального сервера; по умолчанию 3030, допустимы значения от 1 до 65535
--no-openНетНе открывать браузер автоматически; команда только напечатает URL локальной сессии

Если порт занят, static artifact Visualizer-а отсутствует или браузер не удалось открыть, команда завершится с CLI diagnostic и кодом выхода 1. С --no-open browser opener полностью пропускается: URL можно открыть вручную, пока процесс lite-fsm visualize продолжает работать.

Локальная сессия visualize

Успешный запуск создает session token и открывает Visualizer с query parameter session. Token нужен локальному API:

GET /api/session?token=<token> GET /api/source?token=<token>&fileName=<project-relative-file>

/api/session возвращает project graph export document, capabilities локального host-а, entry path и project root. /api/source возвращает текст только для файлов из текущего graph document. Абсолютные пути, .., неизвестные файлы и измененные после сборки graph-файлы отклоняются.

Graph diagnostics не блокируют запуск visualize, если graph document удалось построить: Visualizer открывается, чтобы показать найденные проблемы. Blocking CLI diagnostics, например некорректный explicit tsconfig, останавливают запуск сервера.

Формат export document

export-graph записывает JSON-файл в формате lite-fsm.project-graph-export/v1. visualize использует тот же export document внутри локальной сессии и возвращает его через /api/session.

type LiteFsmProjectGraphExportDocument = { version: "lite-fsm.project-graph-export/v1"; createdBy: { package: "@lite-fsm/cli"; version: string; }; entry: { path: string; tsconfigPath?: string; }; graph: LiteFsmGraphDocument; files: LiteFsmGraphProjectFile[]; diagnostics: CliDiagnostic[]; sources?: LiteFsmProjectGraphSourceBundle; };

Основные поля:

  • version — версия формата экспортируемого документа.
  • createdBy — пакет и версия CLI, который создал файл.
  • entry — входной файл и использованный tsconfig, если он был найден или передан явно.
  • graph — граф @lite-fsm/graph с автоматами, менеджерами, переходами и diagnostics компилятора.
  • files — найденные файлы проекта, их роли и хеши.
  • diagnostics — сообщения CLI.
  • sources — исходный текст файлов, только если передан --include-source.

При export-graph JSON записывается в стабильном порядке ключей и заканчивается переводом строки. Такой формат подходит для сравнения файлов в тестах и проверках.

Роли файлов

files[] показывает, зачем файл попал в граф:

РольЗначение
entryвходной файл из --entry
machineфайл с найденным автоматом
barrelфайл с повторными экспортами
helperфайл с локальной оберткой над API lite-fsm

Роли помогают визуализатору и собственным инструментам объяснить, откуда взялся каждый автомат.

Диагностика

Диагностика CLI использует коды LFC_* и находится в верхнем поле diagnostics.

Диагностика компилятора графа использует коды LFG_* и остается внутри graph.diagnostics. При выводе в терминал команда показывает оба набора сообщений, но в JSON они разделены.

Такое разделение важно:

  • diagnostics описывает запуск CLI: параметры, tsconfig, чтение файлов, запись результата.
  • graph.diagnostics описывает сам граф: неподдержанные формы кода, проблемы поиска автоматов, ошибки компиляции графа.

Коды CLI:

КодЗначение
LFC_INVALID_OPTIONSневерные или неполные параметры команды
LFC_TSCONFIG_NOT_FOUNDtsconfig.json не найден
LFC_TSCONFIG_INVALIDtsconfig.json не прочитан или содержит ошибку
LFC_GRAPH_PROJECT_FAILEDграф проекта не удалось построить
LFC_NO_MACHINES_EXPORTEDв графе нет автоматов, подключенных к менеджеру
LFC_SOURCE_BUNDLE_FILE_UNREADABLEфайл нельзя встроить через --include-source
LFC_VISUALIZER_STATIC_MISSINGstatic artifact Visualizer-а не найден
LFC_VISUALIZER_PORT_UNAVAILABLEпорт локального Visualizer-а занят
LFC_VISUALIZER_SERVER_FAILEDлокальный server Visualizer-а не стартовал
LFC_VISUALIZER_OPEN_FAILEDбраузер не удалось открыть автоматически
LFC_CREATE_TARGET_EXISTSцелевой путь для create уже существует
LFC_CREATE_TARGET_PARENT_MISSINGродительская директория для create не найдена
LFC_CREATE_SCAFFOLD_FAILEDframework scaffold завершился ошибкой
LFC_CREATE_INSTALL_FAILEDinstall dependencies завершился ошибкой
LFC_CREATE_PATCH_FAILEDgenerated project не удалось пропатчить
LFC_CREATE_VALIDATION_FAILEDgenerated project не прошёл финальную проверку
LFC_ADD_MACHINE_STORE_NOT_FOUNDgenerated src/store не найден или не прочитан
LFC_ADD_MACHINE_CONFLICTдобавляемый автомат конфликтует с текущим store
LFC_ADD_MACHINE_PATCH_FAILEDindex.ts или types.ts не удалось обновить
LFC_WRITE_FAILEDфайл проекта или итоговый JSON нельзя записать

Поведение при ошибках

Команды возвращают код выхода 0, если нет CLI diagnostics с серьезностью error. visualize при успешном запуске держит процесс активным и завершает его с кодом 0 после SIGINT или SIGTERM.

Команды возвращают код выхода 1, если есть хотя бы одна blocking CLI error.

create завершается с ошибкой, когда:

  • не передан <project-name> или --template;
  • имя проекта является абсолютным путём, содержит .. или указывает на уже существующий target, кроме . для текущей директории;
  • родительская директория target-а не существует;
  • framework scaffold, install, patching или финальная validation завершаются ошибкой.

add-machine завершается с ошибкой, когда:

  • не передан <name> или имя нельзя преобразовать в безопасный JS identifier;
  • команда запущена не из generated проекта с src/store;
  • файл автомата, import, key в machines или member в AppEvents уже существуют;
  • src/store/index.ts или src/store/types.ts не соответствуют ожидаемому generated shape.

export-graph не пишет частичный JSON, когда:

  • не передан --entry или --out;
  • --out равен -;
  • явный --tsconfig не найден или некорректен;
  • компилятор графа вернул блокирующие diagnostics;
  • в найденном менеджере нет автоматов;
  • не удалось прочитать файл для --include-source;
  • не удалось записать итоговый файл.

visualize не стартует server, когда:

  • не передан --entry;
  • --port не является целым числом от 1 до 65535;
  • explicit --tsconfig не найден или некорректен;
  • graph build не вернул document;
  • static artifact Visualizer-а отсутствует в пакете CLI;
  • порт занят или local server не стартовал;
  • browser opener завершился ошибкой, если не передан --no-open.

Что использовать дальше

Project graph, подготовленный CLI, можно:

  • открыть через lite-fsm visualize без ручного JSON-файла;
  • записать в JSON и открыть в визуализаторе;
  • хранить как артефакт проверки;
  • сравнивать в тестах;
  • передавать собственным инструментам анализа;
  • использовать вместе с @lite-fsm/graph/view-model.

Для программного построения графа без терминальной команды используйте @lite-fsm/graph.

Связанные разделы

Last updated on