feat: add D601 dev backend path

This commit is contained in:
Codex
2026-05-18 10:31:43 +00:00
parent 11b94f3a95
commit 37504a28e8
56 changed files with 10489 additions and 311 deletions
+68 -18
View File
@@ -21,7 +21,6 @@ const syntaxFiles = [
"scripts/src/docker.ts",
"scripts/src/e2e.ts",
"scripts/src/remote.ts",
"src/components/backend-core/src/index.ts",
"src/components/frontend/src/index.ts",
"src/components/frontend/src/app.tsx",
"src/components/frontend/src/decision-center.tsx",
@@ -40,6 +39,7 @@ export interface CheckOptions {
components: boolean;
compose: boolean;
logs: boolean;
rust: boolean;
}
const defaultCheckOptions: CheckOptions = {
@@ -49,8 +49,32 @@ const defaultCheckOptions: CheckOptions = {
components: false,
compose: false,
logs: false,
rust: false,
};
export function checkHelp(): Record<string, unknown> {
return {
ok: true,
command: "check",
usage: "bun scripts/cli.ts check [--syntax-only|--full|--files|--scripts-typecheck|--components|--compose|--logs|--rust]",
defaultMode: "syntax/config only; Rust is never compiled on the master server by default",
options: [
{ name: "--syntax-only|--basic", description: "Run only config validation, Bun version and TypeScript syntax transpile." },
{ name: "--full", description: "Enable all local checks except Rust compilation." },
{ name: "--files", description: "Verify required entrypoint files, including backend-core Cargo files." },
{ name: "--scripts-typecheck", description: "Run scripts TypeScript typecheck." },
{ name: "--components", description: "Run component TypeScript typecheck." },
{ name: "--compose", description: "Render Docker Compose config." },
{ name: "--logs", description: "Check unified log rotation policy." },
{ name: "--rust", description: "Run cargo check only when UNIDESK_D601_RUST_CHECK=1 is set inside D601 CI/dev execution." },
],
rustBoundary: {
masterServer: "do not run cargo check/build here",
d601: "use deploy apply --env dev --service backend-core and CI with UNIDESK_D601_RUST_CHECK=1",
},
};
}
export function parseCheckOptions(args: string[]): CheckOptions {
const options = { ...defaultCheckOptions };
for (const arg of args) {
@@ -71,15 +95,10 @@ export function parseCheckOptions(args: string[]): CheckOptions {
options.compose = true;
} else if (arg === "--logs") {
options.logs = true;
} else if (arg === "--rust") {
options.rust = true;
} else if (arg === "--basic" || arg === "--syntax-only") {
options.full = false;
options.files = false;
options.scriptsTypecheck = false;
options.components = false;
options.compose = false;
options.logs = false;
} else if (arg === "--help" || arg === "-h") {
throw new Error("check usage: bun scripts/cli.ts check [--syntax-only|--full|--files|--scripts-typecheck|--components|--compose|--logs]");
Object.assign(options, defaultCheckOptions);
} else {
throw new Error(`unknown check option: ${arg}`);
}
@@ -92,8 +111,8 @@ function fileItem(path: string): CheckItem {
return { name: `file:${path}`, ok: existsSync(absolute), detail: absolute };
}
function commandItem(name: string, command: string[], timeoutMs = 30_000): CheckItem {
const result = runCommand(command, repoRoot, { timeoutMs });
function commandItem(name: string, command: string[], timeoutMs = 30_000, env: NodeJS.ProcessEnv = process.env): CheckItem {
const result = runCommand(command, repoRoot, { timeoutMs, env });
return {
name,
ok: result.exitCode === 0,
@@ -133,9 +152,9 @@ function syntaxItem(): CheckItem {
function unifiedLogRotationItem(): CheckItem {
const serviceFiles = [
"src/components/backend-core/src/logger.ts",
"src/components/frontend/src/index.ts",
"src/components/provider-gateway/src/index.ts",
"src/components/microservices/code-queue-mgr/src/index.ts",
"src/components/microservices/code-queue/src/index.ts",
"src/components/microservices/k3sctl-adapter/src/index.ts",
"src/components/microservices/mdtodo/src/index.ts",
@@ -143,7 +162,6 @@ function unifiedLogRotationItem(): CheckItem {
"src/components/microservices/baidu-netdisk/src/index.ts",
"src/components/microservices/oa-event-flow/src/index.ts",
"src/components/microservices/decision-center/src/index.ts",
"src/components/microservices/code-queue-mgr/src/index.ts",
];
const offenders = serviceFiles.flatMap((path) => {
const text = readFileSync(rootPath(path), "utf8");
@@ -151,17 +169,41 @@ function unifiedLogRotationItem(): CheckItem {
const missingWriter = !text.includes("createHourlyJsonlWriter");
return directLogAppend || missingWriter ? [{ path, directLogAppend, missingWriter }] : [];
});
const backendLogger = readFileSync(rootPath("src/components/backend-core/src/logger.rs"), "utf8");
const backendMissingRotation = !backendLogger.includes("current_path") || !backendLogger.includes("prune");
const backendDirectUnboundedAppend = backendLogger.includes("appendFileSync");
if (backendMissingRotation || backendDirectUnboundedAppend) {
offenders.push({ path: "src/components/backend-core/src/logger.rs", directLogAppend: backendDirectUnboundedAppend, missingWriter: backendMissingRotation });
}
return {
name: "logs:unified-hourly-rotation",
ok: offenders.length === 0,
detail: {
sharedWriter: "src/components/shared/src/rotating-jsonl.ts",
checkedFiles: serviceFiles,
checkedFiles: ["src/components/backend-core/src/logger.rs", ...serviceFiles],
offenders,
},
};
}
function rustCheckItem(): CheckItem {
if (process.env.UNIDESK_D601_RUST_CHECK !== "1") {
return {
name: "rust:backend-core",
ok: false,
detail: {
skipped: true,
reason: "Rust compilation is intentionally not allowed on the master server; run it from D601 CI/dev deploy.",
enableOnD601: "UNIDESK_D601_RUST_CHECK=1 bun scripts/cli.ts check --rust",
deployPath: "bun scripts/cli.ts deploy apply --env dev --service backend-core",
},
};
}
const envPath = process.env.HOME ? `${process.env.HOME}/.cargo/bin:${process.env.PATH ?? ""}` : process.env.PATH;
const env = envPath ? { ...process.env, PATH: envPath } : process.env;
return commandItem("rust:backend-core", ["cargo", "check", "--manifest-path", "src/components/backend-core/Cargo.toml"], 180_000, env);
}
function skippedItem(name: string, reason: string, enableWith: string): CheckItem {
return { name, ok: true, detail: { skipped: true, reason, enableWith } };
}
@@ -178,7 +220,10 @@ export function runChecks(config: UniDeskConfig, options: CheckOptions = default
fileItem("AGENTS.md"),
fileItem("TEST.md"),
fileItem("docker-compose.yml"),
fileItem("src/components/backend-core/src/index.ts"),
fileItem("src/components/backend-core/Cargo.toml"),
fileItem("src/components/backend-core/Cargo.lock"),
fileItem("src/components/backend-core/src/main.rs"),
fileItem("src/components/backend-core/src/http.rs"),
fileItem("src/components/frontend/src/index.ts"),
fileItem("src/components/provider-gateway/src/index.ts"),
fileItem("src/components/microservices/oa-event-flow/src/index.ts"),
@@ -193,19 +238,19 @@ export function runChecks(config: UniDeskConfig, options: CheckOptions = default
items.push(skippedItem("files:required-entrypoints", "required file presence scan is opt-in", "--files or --full"));
}
if (options.scriptsTypecheck) {
items.push(commandItem("typescript:scripts", ["bunx", "tsc", "-p", "scripts/tsconfig.json", "--noEmit", "--pretty", "false"]));
items.push(commandItem("typescript:scripts", ["bunx", "tsc", "-p", "scripts/tsconfig.json", "--noEmit", "--pretty", "false"], 120_000));
} else {
items.push(skippedItem("typescript:scripts", "scripts TypeScript typecheck is opt-in", "--scripts-typecheck or --full"));
}
if (options.logs) {
items.push(unifiedLogRotationItem());
} else {
items.push(skippedItem("logs:unified-hourly-rotation", "heavy policy scan is opt-in", "--logs or --full"));
items.push(skippedItem("logs:unified-hourly-rotation", "policy scan is opt-in", "--logs or --full"));
}
if (options.components) {
items.push(commandItem("typescript:components", ["bunx", "tsc", "-p", "src/tsconfig.check.json", "--pretty", "false"], 180_000));
} else {
items.push(skippedItem("typescript:components", "full component TypeScript check is opt-in", "--components or --full"));
items.push(skippedItem("typescript:components", "component TypeScript check is opt-in", "--components or --full"));
}
if (options.compose) {
const compose = composeConfig(config);
@@ -225,5 +270,10 @@ export function runChecks(config: UniDeskConfig, options: CheckOptions = default
} else {
items.push(skippedItem("docker-compose:config", "Docker Compose config rendering is opt-in", "--compose or --full"));
}
if (options.rust) {
items.push(rustCheckItem());
} else {
items.push(skippedItem("rust:backend-core", "Rust check/build must run on D601 dev deploy or CI, not on the master server", "--rust inside D601 CI with UNIDESK_D601_RUST_CHECK=1"));
}
return { ok: items.every((item) => item.ok), mode: options.full ? "full" : "basic", options, items };
}