@lenne.tech/cli
Version:
lenne.Tech CLI: lt
173 lines (172 loc) • 9.19 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const caddy_1 = require("../../lib/caddy");
const dev_process_1 = require("../../lib/dev-process");
const dev_project_1 = require("../../lib/dev-project");
const dev_state_1 = require("../../lib/dev-state");
const dev_ticket_1 = require("../../lib/dev-ticket");
/**
* Show what is running.
*
* Default: status for the current project (PIDs + URLs + DB).
* `--all`: list every project in the central registry with health checks.
*/
const StatusCommand = {
alias: ['s'],
description: 'Show lt dev status',
hidden: false,
name: 'status',
run: (toolbox) => __awaiter(void 0, void 0, void 0, function* () {
var _a, _b, _c, _d;
const { filesystem, parameters, print: { colors, info, warning }, } = toolbox;
const all = Boolean(parameters.options.all);
const reg = (0, dev_state_1.loadRegistry)();
if (all) {
info('');
info(colors.bold('All registered lt dev projects'));
info(colors.dim('─'.repeat(60)));
const slugs = Object.keys(reg.projects).sort();
if (slugs.length === 0) {
warning('No projects registered. Run `lt dev init` in a project.');
}
else {
for (const slug of slugs) {
const e = reg.projects[slug];
const session = (0, dev_state_1.loadSession)(e.path);
const apiAlive = (session === null || session === void 0 ? void 0 : session.pids.api) ? (0, dev_state_1.isPidAlive)(session.pids.api) : false;
const appAlive = (session === null || session === void 0 ? void 0 : session.pids.app) ? (0, dev_state_1.isPidAlive)(session.pids.app) : false;
const status = apiAlive || appAlive ? colors.green('●') : colors.dim('○');
info(` ${status} ${slug.padEnd(30)} ${colors.dim(e.path)}`);
for (const [sub, host] of Object.entries(e.subdomains))
info(` ${sub.padEnd(6)} https://${host}`);
}
}
info('');
if (!parameters.options.fromGluegunMenu)
process.exit();
return 'dev status: all';
}
const layout = (0, dev_project_1.resolveLayout)(filesystem.cwd(), filesystem);
// Ticket-aware: a ticket worktree reports its OWN suffixed stack.
const { identity, ticket } = (0, dev_ticket_1.resolveDevIdentity)(layout, { ticket: parameters.options.ticket });
const entry = reg.projects[identity.slug];
info('');
info(colors.bold(`lt dev status: ${identity.slug}`) + (ticket ? colors.dim(` (ticket ${ticket})`) : ''));
info(colors.dim('─'.repeat(60)));
if (!entry) {
warning('Not registered. Run `lt dev init` first.');
// Show what migrate would do (legacy code present?) so the user
// can judge urgency before running it.
const legacyFiles = [];
if (layout.apiDir) {
const f = (0, dev_project_1.apiNeedsPortPatch)(layout.apiDir);
if (f)
legacyFiles.push(f);
}
if (layout.appDir)
legacyFiles.push(...(0, dev_project_1.appNeedsPortPatch)(layout.appDir));
if (legacyFiles.length > 0) {
info(colors.dim(' Legacy hardcoded ports detected — `lt dev init` will patch:'));
legacyFiles.forEach((f) => info(colors.dim(` - ${f}`)));
}
else {
info(colors.dim(' Code is already env-aware; `lt dev init` will only register + patch CLAUDE.md.'));
}
info('');
if (!parameters.options.fromGluegunMenu)
process.exit();
return 'dev status: not registered';
}
for (const [sub, host] of Object.entries(entry.subdomains)) {
const port = sub === 'api' ? entry.internalPorts.api : entry.internalPorts.app;
info(` ${sub.padEnd(6)} https://${host}${port ? colors.dim(` → 127.0.0.1:${port}`) : ''}`);
}
if (entry.dbName)
info(` db mongodb://127.0.0.1/${entry.dbName}`);
// Patch status — quick view whether legacy ports are still in source.
const legacyFiles = [];
if (layout.apiDir) {
const f = (0, dev_project_1.apiNeedsPortPatch)(layout.apiDir);
if (f)
legacyFiles.push(f);
}
if (layout.appDir)
legacyFiles.push(...(0, dev_project_1.appNeedsPortPatch)(layout.appDir));
if (legacyFiles.length > 0) {
info('');
warning(' Legacy hardcoded ports still present:');
legacyFiles.forEach((f) => info(colors.dim(` - ${f}`)));
info(colors.dim(' Run `lt dev init` to patch them; otherwise Caddy may proxy into the void.'));
}
// Caddy status — quick view whether the daemon is reachable.
{
const caddyOk = yield (0, caddy_1.caddyAvailable)();
const daemonOk = caddyOk ? yield (0, caddy_1.caddyDaemonRunning)() : false;
info('');
if (!caddyOk) {
warning(' Caddy not installed — run `lt dev install` first.');
}
else if (!daemonOk) {
warning(' Caddy daemon not running — run `lt dev install` to (re)start the lt-dev service.');
}
else {
info(colors.dim(' Caddy: ready'));
}
}
info('');
const session = (0, dev_state_1.loadSession)(layout.root);
if (!session) {
info(colors.dim(' no `lt dev up` session active'));
}
else {
const apiAlive = session.pids.api ? (0, dev_state_1.isPidAlive)(session.pids.api) : false;
const appAlive = session.pids.app ? (0, dev_state_1.isPidAlive)(session.pids.app) : false;
info(` api: ${apiAlive ? colors.green('running') : colors.red('dead')} (pid ${(_a = session.pids.api) !== null && _a !== void 0 ? _a : '-'})`);
info(` app: ${appAlive ? colors.green('running') : colors.red('dead')} (pid ${(_b = session.pids.app) !== null && _b !== void 0 ? _b : '-'})`);
info(colors.dim(` started: ${session.startedAt}`));
// Live port snapshot
const ports = [entry.internalPorts.api, entry.internalPorts.app].filter((p) => typeof p === 'number');
if (ports.length > 0) {
info('');
info(colors.bold(' Live upstream state'));
const snap = yield (0, dev_process_1.listenSnapshot)(ports);
for (const p of ports) {
const r = snap.get(p);
info(` ${p}: ${r ? colors.green(`bound to ${r.command} (pid ${r.pid})`) : colors.dim('free')}`);
}
}
}
// Isolated test stack (`lt dev test`), if one is up / left with --keep.
const testSession = (0, dev_state_1.loadSession)(layout.root, dev_state_1.TEST_SESSION_FILE);
if (testSession) {
const testEntry = reg.projects[`${identity.slug}-test`];
info('');
info(colors.bold(' Isolated test stack (lt dev test)'));
if (testEntry) {
for (const [sub, host] of Object.entries(testEntry.subdomains))
info(` ${sub.padEnd(6)} https://${host}`);
if (testEntry.dbName)
info(` db mongodb://127.0.0.1/${testEntry.dbName}`);
}
const apiAlive = testSession.pids.api ? (0, dev_state_1.isPidAlive)(testSession.pids.api) : false;
const appAlive = testSession.pids.app ? (0, dev_state_1.isPidAlive)(testSession.pids.app) : false;
info(` api: ${apiAlive ? colors.green('running') : colors.red('dead')} (pid ${(_c = testSession.pids.api) !== null && _c !== void 0 ? _c : '-'})`);
info(` app: ${appAlive ? colors.green('running') : colors.red('dead')} (pid ${(_d = testSession.pids.app) !== null && _d !== void 0 ? _d : '-'})`);
info(colors.dim(' stop: lt dev test down'));
}
info('');
if (!parameters.options.fromGluegunMenu)
process.exit();
return `dev status: ${identity.slug}`;
}),
};
module.exports = StatusCommand;