Converts gadget-tasks from a duplicated codebase with direct MongoDB access to a headless IDE client that uses gadget-code's REST API and Socket.IO protocol to submit and process task prompts through the existing pipeline. Deleted (no longer needed): - gadget-tasks/src/models/ (5 Mongoose models — duplicated from gadget-code) - gadget-tasks/data/prompts/ (11 prompt templates — duplicated from gadget-code) - gadget-tasks/src/services/executor.ts (629-line AWL loop — duplicated from gadget-drone) - gadget-tasks/src/services/ai.ts (direct AI API calls — drones do this now) - gadget-tasks/src/services/workspace.ts (workspace management — drones do this now) Added: - gadget-tasks/src/services/platform.ts — REST API + Socket.IO headless IDE client with session lock, workspace mode, prompt submission, work order tracking Rewritten: - gadget-tasks/src/gadget-tasks.ts — new startup: user login → auth → drone selection → Socket.IO connect → schedule tasks (no MongoDB) - gadget-tasks/src/services/scheduler.ts — delegates to PlatformService.executeTask() - gadget-tasks/src/config/env.ts — platform.baseUrl config, no mongodb/google gadget-code changes: - Added PATCH /api/v1/projects/:projectId/tasks/:taskId/lastRun route - Added ProjectService.updateTaskLastRun() for atomic task field update Config changes: - GadgetTasksConfig: replaced mongodb with platform.baseUrl, removed google.cse - Dependencies: removed mongoose, @gadget/ai, @gadget/ai-toolbox, dayjs, simple-git, nanoid; added socket.io-client, @inquirer/prompts
89 lines
3.0 KiB
TypeScript
89 lines
3.0 KiB
TypeScript
// config/env.ts
|
|
// Copyright (C) 2026 Rob Colbert <rob.colbert@openplatform.us>
|
|
// Licensed under the Apache License, Version 2.0
|
|
|
|
import path, { dirname } from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
import { loadGadgetTasksConfig, resolvePath } from "@gadget/config";
|
|
import type PackageJson from "../../package.json";
|
|
import { GadgetLog, GadgetLogFile } from "@gadget/api";
|
|
|
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
|
// INSTALL_DIR: where the package is installed (for loading assets, etc.)
|
|
export const INSTALL_DIR = path.resolve(__dirname, "..", "..");
|
|
|
|
// Load YAML configuration
|
|
const yamlConfig = loadGadgetTasksConfig();
|
|
|
|
// Validate required fields
|
|
if (!yamlConfig.platform?.baseUrl) {
|
|
throw new Error(
|
|
"Configuration error: platform.baseUrl is required in gadget-tasks.yaml\n" +
|
|
"See documentation: ./docs/configuration.md",
|
|
);
|
|
}
|
|
|
|
async function readJsonFile<T>(filePath: string): Promise<T> {
|
|
const fs = await import("node:fs");
|
|
const file = await fs.promises.readFile(filePath);
|
|
return JSON.parse(file.toString("utf-8")) as T;
|
|
}
|
|
|
|
/* eslint-disable no-process-env */
|
|
export default {
|
|
NODE_ENV: process.env.NODE_ENV || "develop",
|
|
timezone: yamlConfig.timezone || "America/New_York",
|
|
installDir: INSTALL_DIR,
|
|
pkg: await readJsonFile<typeof PackageJson>(
|
|
path.join(INSTALL_DIR, "package.json"),
|
|
),
|
|
platform: {
|
|
baseUrl: yamlConfig.platform.baseUrl,
|
|
},
|
|
redis: {
|
|
host: yamlConfig.redis?.host || "localhost",
|
|
port: yamlConfig.redis?.port || 6379,
|
|
password: yamlConfig.redis?.password,
|
|
keyPrefix: yamlConfig.redis?.keyPrefix || "gadget:",
|
|
},
|
|
concurrency: yamlConfig.concurrency || 1,
|
|
log: {
|
|
console: {
|
|
enabled: yamlConfig.logging?.console?.enabled === true,
|
|
},
|
|
file: {
|
|
enabled: yamlConfig.logging?.file?.enabled === true,
|
|
path: yamlConfig.logging?.file?.path
|
|
? resolvePath(yamlConfig.logging.file.path)
|
|
: path.join(INSTALL_DIR, "logs"),
|
|
name: yamlConfig.logging?.file?.name || "gadget-tasks",
|
|
maxWritesPerFile: yamlConfig.logging?.file?.maxWritesPerFile || 10000,
|
|
maxFiles: yamlConfig.logging?.file?.maxFiles || 10,
|
|
},
|
|
levels: {
|
|
debug: yamlConfig.logging?.levels?.debug === true,
|
|
info: yamlConfig.logging?.levels?.info === true,
|
|
warn: yamlConfig.logging?.levels?.warn === true,
|
|
},
|
|
},
|
|
};
|
|
|
|
// Configure GadgetLog for this package
|
|
GadgetLog.consoleEnabled = yamlConfig.logging?.console?.enabled === true;
|
|
if (yamlConfig.logging?.file?.enabled === true) {
|
|
const logFileOptions = {
|
|
basePath: yamlConfig.logging.file.path
|
|
? resolvePath(yamlConfig.logging.file.path)
|
|
: path.join(INSTALL_DIR, "logs"),
|
|
name: yamlConfig.logging.file.name || "gadget-tasks",
|
|
maxWritesPerFile: yamlConfig.logging.file.maxWritesPerFile || 10000,
|
|
maxFiles: yamlConfig.logging.file.maxFiles || 10,
|
|
};
|
|
const defaultLogFile = new GadgetLogFile(logFileOptions);
|
|
defaultLogFile.open();
|
|
GadgetLog.defaultFile = defaultLogFile;
|
|
}
|
|
|
|
/* eslint-enable no-process-env */
|