feat: improve make start

This commit is contained in:
Carlos Florêncio
2026-02-03 09:50:43 +00:00
parent 7f883deb8f
commit 2d0985599a
3 changed files with 48 additions and 12 deletions
+9 -1
View File
@@ -20,6 +20,8 @@ CYAN := \033[36m
YELLOW := \033[33m
MAGENTA := \033[35m
VERBOSE ?= 0
# Phase headers
define phase
@printf "\n$(BOLD)$(BLUE)━━━ $(1) ━━━$(RESET)\n\n"
@@ -49,6 +51,8 @@ help:
@echo ""
@echo "Production Commands:"
@echo " start Install deps, build, and start backend + web in production mode"
@echo " start-verbose Start in production mode with info logs from backend + web"
@echo " start VERBOSE=1 Same as start-verbose"
@echo ""
@echo "Build Commands:"
@echo " build Build backend and web app"
@@ -123,7 +127,11 @@ start:
@$(MAKE) -s build-web-quiet
$(call success,Build complete)
$(call phase,Starting Server)
@cd $(APPS_DIR) && $(PNPM) -C cli dev -- start
@cd $(APPS_DIR) && $(PNPM) -C cli dev -- start $(if $(filter 1 true yes,$(VERBOSE)),--verbose,)
.PHONY: start-verbose
start-verbose:
@$(MAKE) start VERBOSE=1
.PHONY: build-backend
build-backend:
+8 -2
View File
@@ -15,6 +15,7 @@ type CliOptions = {
version?: string;
backendPort?: number;
webPort?: number;
verbose?: boolean;
};
function printHelp() {
@@ -23,7 +24,7 @@ function printHelp() {
Usage:
kandev run [--version <tag>] [--backend-port <port>] [--web-port <port>]
kandev dev [--backend-port <port>] [--web-port <port>]
kandev start [--backend-port <port>] [--web-port <port>]
kandev start [--backend-port <port>] [--web-port <port>] [--verbose]
kandev [--version <tag>] [--backend-port <port>] [--web-port <port>]
kandev --dev [--backend-port <port>] [--web-port <port>]
@@ -44,6 +45,7 @@ Options:
--version Release tag to install (default: latest).
--backend-port Override backend port.
--web-port Override web port.
--verbose, -v Show info logs from backend + web (start mode only).
--help, -h Show help.
`);
}
@@ -91,6 +93,10 @@ function parseArgs(argv: string[]): CliOptions {
opts.webPort = Number(arg.split("=")[1]);
continue;
}
if (arg === "--verbose" || arg === "-v") {
opts.verbose = true;
continue;
}
}
return opts;
}
@@ -137,7 +143,7 @@ async function main(): Promise<void> {
if (!repoRoot) {
throw new Error("Unable to locate repo root for start. Run from the repo.");
}
await runStart({ repoRoot, backendPort, webPort });
await runStart({ repoRoot, backendPort, webPort, verbose: raw.verbose });
return;
}
+31 -9
View File
@@ -34,6 +34,8 @@ export type StartOptions = {
backendPort?: number;
/** Optional preferred web port (finds available port if not specified) */
webPort?: number;
/** Show info logs from backend + web */
verbose?: boolean;
};
/**
@@ -49,7 +51,12 @@ export type StartOptions = {
* @param options - Configuration for the start command
* @throws Error if backend binary or web build is not found
*/
export async function runStart({ repoRoot, backendPort, webPort }: StartOptions): Promise<void> {
export async function runStart({
repoRoot,
backendPort,
webPort,
verbose = false,
}: StartOptions): Promise<void> {
const ports = await pickPorts(backendPort, webPort);
const backendBin = path.join(repoRoot, "apps", "backend", "bin", getBinaryName("kandev"));
@@ -62,24 +69,39 @@ export async function runStart({ repoRoot, backendPort, webPort }: StartOptions)
if (!fs.existsSync(webServerPath)) {
throw new Error("Web standalone build not found. Run `make build` first.");
}
const webStandaloneDir = path.dirname(webServerPath);
const webStaticDir = path.join(repoRoot, "apps", "web", ".next", "static");
const standaloneStaticDir = path.join(webStandaloneDir, ".next", "static");
if (fs.existsSync(webStaticDir) && !fs.existsSync(standaloneStaticDir)) {
fs.mkdirSync(path.dirname(standaloneStaticDir), { recursive: true });
try {
fs.symlinkSync(webStaticDir, standaloneStaticDir, "junction");
} catch (err) {
console.warn(
`[kandev] failed to link Next.js static assets: ${err instanceof Error ? err.message : String(err)}`,
);
}
}
// Production mode: use warn log level for clean output
const backendEnv = buildBackendEnv({ ports, logLevel: "warn" });
// Production mode: use warn log level for clean output unless verbose
const backendEnv = buildBackendEnv({ ports, logLevel: verbose ? "info" : "warn" });
const webEnv = buildWebEnv({ ports, includeMcp: true, production: true });
const supervisor = createProcessSupervisor();
supervisor.attachSignalHandlers();
// Start backend with piped stdio (quiet mode)
// Start backend with piped stdio (quiet mode unless verbose)
const backendProc = spawn(backendBin, [], {
cwd: path.dirname(backendBin),
env: backendEnv,
stdio: ["ignore", "pipe", "pipe"],
stdio: verbose ? ["ignore", "inherit", "inherit"] : ["ignore", "pipe", "pipe"],
});
supervisor.children.push(backendProc);
// Forward stderr only (warnings/errors)
backendProc.stderr?.pipe(process.stderr);
// Forward stderr only (warnings/errors) when quiet
if (!verbose) {
backendProc.stderr?.pipe(process.stderr);
}
attachBackendExitHandler(backendProc, supervisor);
@@ -88,12 +110,12 @@ export async function runStart({ repoRoot, backendPort, webPort }: StartOptions)
launchWebApp({
command: "node",
args: [webServerPath],
cwd: path.dirname(webServerPath),
cwd: webStandaloneDir,
env: webEnv,
url: webUrl,
supervisor,
label: "web",
quiet: true,
quiet: !verbose,
});
const healthTimeoutMs = resolveHealthTimeoutMs(HEALTH_TIMEOUT_MS_RELEASE);