UNPKG

@lenne.tech/cli

Version:

lenne.Tech CLI: lt

173 lines (172 loc) 9.19 kB
"use strict"; 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;