@kontextmind/kxm
Version:
KXM local-first multi-agent orchestration and operator dashboard
51 lines (46 loc) • 2.03 kB
text/typescript
import { spawn } from "node:child_process";
import { join } from "node:path";
import { discoverKxmProjectRoot } from "../project-config.ts";
import { findKxmRepoRoot } from "../repo-root.ts";
import { print, type Runtime } from "./types.ts";
export interface LandOptions {
pr?: string;
stage?: string;
title?: string;
bodyFile?: string;
}
function childEnv(): NodeJS.ProcessEnv {
const env: NodeJS.ProcessEnv = {};
for (const [name, value] of Object.entries(process.env)) {
if (value === undefined) continue;
if (name.toUpperCase().startsWith("GIT_")) continue;
env[name] = value;
}
return env;
}
function refuse(runtime: Runtime, error: string, text: string): number {
print(runtime.io, runtime.json, { ok: false, command: "land", error }, text);
return 1;
}
/** Spawn scripts/pr-land.mjs and stream its JSON lines. The exit code is the script's. */
export function cmdLand(runtime: Runtime, options: LandOptions = {}): Promise<number> {
const root = discoverKxmProjectRoot(runtime.cwd);
if (!root) {
return Promise.resolve(refuse(runtime, "project_required", "land requires a KXM project (run kxm init first)"));
}
const script = join(findKxmRepoRoot(import.meta.url), "scripts", "pr-land.mjs");
const args = [script];
if (options.pr) args.push("--pr", options.pr);
if (options.stage) args.push("--stage", options.stage);
if (options.title) args.push("--title", options.title);
if (options.bodyFile) args.push("--body-file", options.bodyFile);
if (runtime.json) args.push("--json");
if (runtime.dryRun) args.push("--dry-run");
return new Promise((resolveExit) => {
const child = spawn(process.execPath, args, { cwd: root, env: childEnv(), windowsHide: true });
child.stdout.on("data", (chunk: Buffer) => runtime.io.stdout(chunk.toString("utf8")));
child.stderr.on("data", (chunk: Buffer) => runtime.io.stderr(chunk.toString("utf8")));
child.once("error", () => resolveExit(1));
child.once("close", (code) => resolveExit(code ?? 1));
});
}