Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion dev/cli/src/commands/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ import { join } from 'path';
export async function envCheck(root: string) {
ui.header('Environment Variable Check');

let allGood = true;

const envLocalPath = join(root, '.env.local');
const envLocalExists = await Bun.file(envLocalPath).exists();
if (envLocalExists) {
ui.success('.env.local exists');
} else {
ui.error('.env.local missing — run: vercel env pull');
allGood = false;
}

const vercelProjectPath = join(root, '.vercel', 'project.json');
Expand All @@ -20,10 +23,10 @@ export async function envCheck(root: string) {
ui.success('Vercel project linked');
} else {
ui.warn('Vercel project not linked — run: vercel link --project kilocode-app');
allGood = false;
}

const servicesWithEnv = services.filter(s => s.envFile);
let allGood = true;

for (const svc of servicesWithEnv) {
const examplePath = join(root, svc.dir, svc.envFile!);
Expand Down
11 changes: 10 additions & 1 deletion dev/cli/src/commands/logs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,21 @@ export async function logs(args: string[], root: string) {
return;
}

if (svc.type === 'infra') {
// Only docker compose services support `docker compose logs`.
// Infra services like 'migrations' use non-docker commands (e.g. pnpm drizzle migrate)
// and have no persistent container to tail.
const dockerComposeServices = new Set(['postgres', 'redis']);

if (svc.type === 'infra' && dockerComposeServices.has(svc.name)) {
const proc = Bun.spawn(
['docker', 'compose', '-f', 'dev/docker-compose.yml', 'logs', '-f', svc.name],
{ stdout: 'inherit', stderr: 'inherit', cwd: root }
);
await proc.exited;
} else if (svc.type === 'infra') {
ui.warn(
`"${svc.name}" is not a Docker Compose service — no logs to tail.\n It runs: ${svc.devCommand ?? 'n/a'}`
);
} else {
ui.warn(
`Log tailing for running dev servers is not yet supported.\n Start the service with 'pnpm kilo dev up ${name}' to see its output.`
Expand Down
39 changes: 35 additions & 4 deletions dev/cli/src/commands/status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,42 @@ export async function status(root: string) {
);

const portServices = services.filter(s => s.port && s.type !== 'infra');

// Group services by port to detect shared ports
const portToServices = new Map<number, string[]>();
for (const svc of portServices) {
const list = portToServices.get(svc.port!) ?? [];
list.push(svc.name);
portToServices.set(svc.port!, list);
}

// Track ports we've already checked to avoid duplicate probes
const checkedPorts = new Set<number>();

for (const svc of portServices) {
const listening = await isPortListening(svc.port!);
console.log(
` ${listening ? ui.green('●') : ui.dim('○')} ${svc.name.padEnd(12)} ${listening ? `port ${svc.port}` : ui.dim('not running')}`
);
const port = svc.port!;
const sharesPort = portToServices.get(port)!;

if (checkedPorts.has(port)) {
// Already reported for this port — skip duplicate probe
continue;
}
checkedPorts.add(port);

const listening = await isPortListening(port);

if (sharesPort.length > 1) {
// Multiple services claim this port — show them together with a note
const names = sharesPort.join(' / ');
const ambiguityNote = ui.dim('(shared port — cannot distinguish)');
console.log(
` ${listening ? ui.green('●') : ui.dim('○')} ${names.padEnd(24)} ${listening ? `port ${port} ${ambiguityNote}` : ui.dim('not running')}`
);
} else {
console.log(
` ${listening ? ui.green('●') : ui.dim('○')} ${svc.name.padEnd(12)} ${listening ? `port ${port}` : ui.dim('not running')}`
);
}
}

console.log();
Expand Down
2 changes: 2 additions & 0 deletions dev/cli/src/projects/auto-fix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { ProjectDef } from './types';
import { spawnService, run } from '../utils/process';
import * as ui from '../utils/ui';
import { join } from 'path';
import { mkdir } from 'fs/promises';
import { createHmac, randomUUID } from 'crypto';

const GENERIC_BODY = JSON.stringify(
Expand Down Expand Up @@ -50,6 +51,7 @@ async function upCommand(args: string[], root: string): Promise<void> {
const skipRoot = args.includes('--no-root');

const logDir = join(root, 'dev', '.dev-logs', 'auto-fix');
await mkdir(logDir, { recursive: true });
await Bun.write(join(logDir, '.gitkeep'), '');

ui.header('Kilo Cloud Dev Services — Auto Fix');
Expand Down
2 changes: 2 additions & 0 deletions dev/cli/src/projects/code-review.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { ProjectDef } from './types';
import { spawnService, run } from '../utils/process';
import * as ui from '../utils/ui';
import { join } from 'path';
import { mkdir } from 'fs/promises';
import { createHmac, randomUUID } from 'crypto';

const GENERIC_BODY = JSON.stringify(
Expand Down Expand Up @@ -48,6 +49,7 @@ async function upCommand(args: string[], root: string): Promise<void> {
const skipRoot = args.includes('--no-root');

const logDir = join(root, 'dev', '.dev-logs', 'review');
await mkdir(logDir, { recursive: true });
await Bun.write(join(logDir, '.gitkeep'), '');

ui.header('Kilo Cloud Dev Services — Code Review');
Expand Down