|
@@ -1,6 +1,7 @@
|
|
|
import { Command } from "commander";
|
|
import { Command } from "commander";
|
|
|
import { Scheduler } from "@actalk/inkos-core";
|
|
import { Scheduler } from "@actalk/inkos-core";
|
|
|
import { loadConfig, findProjectRoot, buildPipelineConfig, log, logError } from "../utils.js";
|
|
import { loadConfig, findProjectRoot, buildPipelineConfig, log, logError } from "../utils.js";
|
|
|
|
|
+import { createWriteStream, type WriteStream } from "node:fs";
|
|
|
import { writeFile, readFile, unlink } from "node:fs/promises";
|
|
import { writeFile, readFile, unlink } from "node:fs/promises";
|
|
|
import { join } from "node:path";
|
|
import { join } from "node:path";
|
|
|
|
|
|
|
@@ -8,7 +9,9 @@ const PID_FILE = "inkos.pid";
|
|
|
|
|
|
|
|
export const upCommand = new Command("up")
|
|
export const upCommand = new Command("up")
|
|
|
.description("Start the InkOS daemon (autonomous mode)")
|
|
.description("Start the InkOS daemon (autonomous mode)")
|
|
|
- .action(async () => {
|
|
|
|
|
|
|
+ .option("-q, --quiet", "Suppress console output")
|
|
|
|
|
+ .action(async (opts) => {
|
|
|
|
|
+ let logStream: WriteStream | undefined;
|
|
|
try {
|
|
try {
|
|
|
const config = await loadConfig();
|
|
const config = await loadConfig();
|
|
|
const root = findProjectRoot();
|
|
const root = findProjectRoot();
|
|
@@ -32,8 +35,12 @@ export const upCommand = new Command("up")
|
|
|
// Write PID file
|
|
// Write PID file
|
|
|
await writeFile(pidPath, String(process.pid), "utf-8");
|
|
await writeFile(pidPath, String(process.pid), "utf-8");
|
|
|
|
|
|
|
|
|
|
+ // File logging for daemon
|
|
|
|
|
+ const logPath = join(root, "inkos.log");
|
|
|
|
|
+ logStream = createWriteStream(logPath, { flags: "a" });
|
|
|
|
|
+
|
|
|
const scheduler = new Scheduler({
|
|
const scheduler = new Scheduler({
|
|
|
- ...buildPipelineConfig(config, root),
|
|
|
|
|
|
|
+ ...buildPipelineConfig(config, root, { logFile: logStream, quiet: opts.quiet }),
|
|
|
radarCron: config.daemon.schedule.radarCron,
|
|
radarCron: config.daemon.schedule.radarCron,
|
|
|
writeCron: config.daemon.schedule.writeCron,
|
|
writeCron: config.daemon.schedule.writeCron,
|
|
|
maxConcurrentBooks: config.daemon.maxConcurrentBooks,
|
|
maxConcurrentBooks: config.daemon.maxConcurrentBooks,
|
|
@@ -54,6 +61,7 @@ export const upCommand = new Command("up")
|
|
|
const shutdown = async () => {
|
|
const shutdown = async () => {
|
|
|
log("\nShutting down daemon...");
|
|
log("\nShutting down daemon...");
|
|
|
scheduler.stop();
|
|
scheduler.stop();
|
|
|
|
|
+ logStream?.end();
|
|
|
try {
|
|
try {
|
|
|
await unlink(pidPath);
|
|
await unlink(pidPath);
|
|
|
} catch {
|
|
} catch {
|
|
@@ -71,6 +79,7 @@ export const upCommand = new Command("up")
|
|
|
// Keep process alive
|
|
// Keep process alive
|
|
|
await new Promise(() => {});
|
|
await new Promise(() => {});
|
|
|
} catch (e) {
|
|
} catch (e) {
|
|
|
|
|
+ logStream?.end();
|
|
|
logError(`Failed to start daemon: ${e}`);
|
|
logError(`Failed to start daemon: ${e}`);
|
|
|
process.exit(1);
|
|
process.exit(1);
|
|
|
}
|
|
}
|