Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | 11x 11x 11x 11x 9x 9x 10x 10x | /**
* System Router — health, status, systemHealthCheck
*/
import { z } from 'zod';
import { join } from 'node:path';
import { access } from 'node:fs/promises';
import type { ProcedureBuilder } from '../trpc.js';
import { requireAccountRepository, requireProjectRepository } from './_helpers.js';
import { checkAccountHealth } from '../../agent/accounts/usage.js';
import { getProjectCloneDir } from '../../git/project-clones.js';
export const healthResponseSchema = z.object({
status: z.literal('ok'),
uptime: z.number().int().nonnegative(),
processCount: z.number().int().nonnegative(),
});
export type HealthResponse = z.infer<typeof healthResponseSchema>;
export const processInfoSchema = z.object({
id: z.string(),
pid: z.number().int().positive(),
command: z.string(),
status: z.string(),
startedAt: z.string(),
});
export type ProcessInfo = z.infer<typeof processInfoSchema>;
export const statusResponseSchema = z.object({
server: z.object({
startedAt: z.string(),
uptime: z.number().int().nonnegative(),
pid: z.number().int().positive(),
}),
processes: z.array(processInfoSchema),
});
export type StatusResponse = z.infer<typeof statusResponseSchema>;
export function systemProcedures(publicProcedure: ProcedureBuilder) {
return {
health: publicProcedure
.output(healthResponseSchema)
.query(({ ctx }): HealthResponse => {
const uptime = ctx.serverStartedAt
? Math.floor((Date.now() - ctx.serverStartedAt.getTime()) / 1000)
: 0;
return {
status: 'ok',
uptime,
processCount: ctx.processCount,
};
}),
status: publicProcedure
.output(statusResponseSchema)
.query(({ ctx }): StatusResponse => {
const uptime = ctx.serverStartedAt
? Math.floor((Date.now() - ctx.serverStartedAt.getTime()) / 1000)
: 0;
return {
server: {
startedAt: ctx.serverStartedAt?.toISOString() ?? '',
uptime,
pid: process.pid,
},
processes: [],
};
}),
systemHealthCheck: publicProcedure
.query(async ({ ctx }) => {
const uptime = ctx.serverStartedAt
? Math.floor((Date.now() - ctx.serverStartedAt.getTime()) / 1000)
: 0;
const accountRepo = requireAccountRepository(ctx);
const allAccounts = await accountRepo.findAll();
const allAgents = ctx.agentManager ? await ctx.agentManager.list() : [];
const accounts = await Promise.all(
allAccounts.map(account => checkAccountHealth(account, allAgents, ctx.credentialManager, ctx.workspaceRoot ?? undefined))
);
const projectRepo = requireProjectRepository(ctx);
const allProjects = await projectRepo.findAll();
const projects = await Promise.all(
allProjects.map(async project => {
let repoExists = false;
if (ctx.workspaceRoot) {
const clonePath = join(ctx.workspaceRoot, getProjectCloneDir(project.name, project.id));
try { await access(clonePath); repoExists = true; } catch { repoExists = false; }
}
return { id: project.id, name: project.name, url: project.url, repoExists };
})
);
return {
server: { status: 'ok' as const, uptime, startedAt: ctx.serverStartedAt?.toISOString() ?? null },
accounts,
projects,
};
}),
};
}
|