@kontextmind/kxm
Version:
KXM local-first multi-agent orchestration and operator dashboard
87 lines (80 loc) • 2.35 kB
text/typescript
import { join } from "node:path";
import { verifyArtifactExists } from "./artifacts-exist.ts";
import type { KxmRuntimeContext } from "./runtime-service.ts";
export interface KxmArtifactsObservation {
completeness: "complete";
spawned: 0;
pid: null;
exitCode: null;
signal: null;
exitObserved: 0;
closeObserved: 0;
stopCause: "none";
signalsAttempted: "none";
errorClass: null;
stdoutSha256: null;
stdoutBytes: null;
stdoutComplete: null;
stderrSha256: null;
stderrBytes: null;
stderrComplete: null;
checkedCount: number;
failedCount: number;
elapsedMs: number;
startedAt: string;
finishedAt: string;
}
export interface KxmArtifactsGateSeams {
afterPathChecked?: ((input: {
path: string;
index: number;
checkedCount: number;
failedCount: number;
}) => void) | undefined;
}
export const kxmArtifactsGateSeams: KxmArtifactsGateSeams = {};
/**
* Check every pinned path under control `.kxm/assets`. Normal helper failures
* are complete failed facts. Exceptions after checks begin must propagate.
*/
export function evaluateArtifactsGate(
context: KxmRuntimeContext,
definition: { readonly kind: "artifacts-exist"; readonly paths: readonly string[] },
): KxmArtifactsObservation {
const root = join(context.projectRoot, ".kxm", "assets");
const startedAt = new Date().toISOString();
const startTime = process.hrtime.bigint();
let checkedCount = 0;
let failedCount = 0;
for (const [index, path] of definition.paths.entries()) {
checkedCount += 1;
const result = verifyArtifactExists(root, join(root, path));
if (!result.ok) failedCount += 1;
kxmArtifactsGateSeams.afterPathChecked?.({ path, index, checkedCount, failedCount });
}
const elapsedNs = process.hrtime.bigint() - startTime;
const finishedAt = new Date().toISOString();
return {
completeness: "complete",
spawned: 0,
pid: null,
exitCode: null,
signal: null,
exitObserved: 0,
closeObserved: 0,
stopCause: "none",
signalsAttempted: "none",
errorClass: null,
stdoutSha256: null,
stdoutBytes: null,
stdoutComplete: null,
stderrSha256: null,
stderrBytes: null,
stderrComplete: null,
checkedCount,
failedCount,
elapsedMs: Math.max(0, Math.floor(Number(elapsedNs) / 1_000_000)),
startedAt,
finishedAt,
};
}