gadget/gadget-tasks/src/config/env.ts
Rob Colbert b906cb2377 feat(gadget-tasks): course correction — headless IDE client architecture
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
2026-05-17 00:48:39 -04:00

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 */