@agenteract/core
Advanced tools
| export interface DevServerConfig { | ||
| command: string; | ||
| port: number; | ||
| cwd?: string; | ||
| env?: Record<string, string>; | ||
| validation?: { | ||
| fileExists?: string[]; | ||
| commandInPath?: string; | ||
| errorHints?: Record<string, string>; | ||
| }; | ||
| keyCommands?: Record<string, string>; | ||
| } | ||
| export interface ProjectConfig { | ||
| name: string; | ||
| path: string; | ||
| type?: 'expo' | 'vite' | 'flutter' | 'native' | 'auto'; | ||
| ptyPort?: number; | ||
| devServer?: DevServerConfig; | ||
| scheme?: string; | ||
| } | ||
| export interface AgenteractConfig { | ||
| server?: { | ||
| port?: number; | ||
| wsPort?: number; | ||
| logPort?: number; | ||
| }; | ||
| port?: number; | ||
| projects: ProjectConfig[]; | ||
| } |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); |
| import { AgenteractConfig, DevServerConfig, ProjectConfig } from '../config-types.js'; | ||
| export interface RuntimeConfig { | ||
| host: string; | ||
| port: number; | ||
| token: string; | ||
| defaultDevices?: Record<string, string>; | ||
| } | ||
| export declare function getRuntimeConfigPath(cwd?: string): string; | ||
| export declare function saveRuntimeConfig(config: RuntimeConfig, cwd?: string): Promise<void>; | ||
| export declare function loadRuntimeConfig(cwd?: string): Promise<RuntimeConfig | null>; | ||
| export declare function deleteRuntimeConfig(cwd?: string): Promise<void>; | ||
| export declare function generateAuthToken(): string; | ||
| /** | ||
| * Set the default device for a project | ||
| */ | ||
| export declare function setDefaultDevice(projectName: string, deviceId: string, cwd?: string): Promise<void>; | ||
| /** | ||
| * Get the default device for a project | ||
| */ | ||
| export declare function getDefaultDevice(projectName: string, cwd?: string): Promise<string | undefined>; | ||
| export declare class MissingConfigError extends Error { | ||
| constructor(message: string); | ||
| } | ||
| export declare function loadConfig(rootDir: string): Promise<AgenteractConfig>; | ||
| /** | ||
| * Find the root directory containing agenteract.config.js | ||
| * Searches upward from the current working directory | ||
| */ | ||
| export declare function findConfigRoot(startDir?: string): Promise<string | null>; | ||
| /** | ||
| * Get the URL for the agent server | ||
| */ | ||
| export declare function getAgentServerUrl(config: AgenteractConfig): string; | ||
| /** | ||
| * Get the URL for a project's dev server | ||
| */ | ||
| export declare function getProjectServerUrl(config: AgenteractConfig, projectName: string): string | null; | ||
| /** | ||
| * Get the URL for a dev server by type | ||
| */ | ||
| export declare function getDevServerUrlByType(config: AgenteractConfig, type: 'expo' | 'vite' | 'flutter'): string | null; | ||
| /** | ||
| * Type presets for backward compatibility | ||
| * Maps old 'type' field to new devServer configuration | ||
| */ | ||
| export declare const TYPE_PRESETS: Record<string, Omit<DevServerConfig, 'port'>>; | ||
| export declare function addConfig(rootDir: string, projectPath: string, name: string, typeOrCommand: string, port?: number, scheme?: string): Promise<void>; | ||
| /** | ||
| * Normalize project config: migrate old format to new format | ||
| * Logs deprecation warnings when using old 'type' field | ||
| */ | ||
| export declare function normalizeProjectConfig(project: ProjectConfig, rootDir: string): ProjectConfig; |
| "use strict"; | ||
| var __importDefault = (this && this.__importDefault) || function (mod) { | ||
| return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.TYPE_PRESETS = exports.MissingConfigError = void 0; | ||
| exports.getRuntimeConfigPath = getRuntimeConfigPath; | ||
| exports.saveRuntimeConfig = saveRuntimeConfig; | ||
| exports.loadRuntimeConfig = loadRuntimeConfig; | ||
| exports.deleteRuntimeConfig = deleteRuntimeConfig; | ||
| exports.generateAuthToken = generateAuthToken; | ||
| exports.setDefaultDevice = setDefaultDevice; | ||
| exports.getDefaultDevice = getDefaultDevice; | ||
| exports.loadConfig = loadConfig; | ||
| exports.findConfigRoot = findConfigRoot; | ||
| exports.getAgentServerUrl = getAgentServerUrl; | ||
| exports.getProjectServerUrl = getProjectServerUrl; | ||
| exports.getDevServerUrlByType = getDevServerUrlByType; | ||
| exports.addConfig = addConfig; | ||
| exports.normalizeProjectConfig = normalizeProjectConfig; | ||
| const promises_1 = __importDefault(require("fs/promises")); | ||
| const path_1 = __importDefault(require("path")); | ||
| const crypto_1 = require("crypto"); | ||
| function getRuntimeConfigPath(cwd = process.cwd()) { | ||
| return path_1.default.join(cwd, '.agenteract-runtime.json'); | ||
| } | ||
| async function saveRuntimeConfig(config, cwd = process.cwd()) { | ||
| await promises_1.default.writeFile(getRuntimeConfigPath(cwd), JSON.stringify(config, null, 2)); | ||
| } | ||
| async function loadRuntimeConfig(cwd = process.cwd()) { | ||
| try { | ||
| const content = await promises_1.default.readFile(getRuntimeConfigPath(cwd), 'utf-8'); | ||
| return JSON.parse(content); | ||
| } | ||
| catch { | ||
| return null; | ||
| } | ||
| } | ||
| async function deleteRuntimeConfig(cwd = process.cwd()) { | ||
| try { | ||
| await promises_1.default.unlink(getRuntimeConfigPath(cwd)); | ||
| } | ||
| catch { | ||
| // Ignore if file doesn't exist | ||
| } | ||
| } | ||
| function generateAuthToken() { | ||
| return (0, crypto_1.randomUUID)(); | ||
| } | ||
| /** | ||
| * Set the default device for a project | ||
| */ | ||
| async function setDefaultDevice(projectName, deviceId, cwd = process.cwd()) { | ||
| const config = await loadRuntimeConfig(cwd); | ||
| if (!config) { | ||
| throw new Error('Runtime config not found. Is the server running?'); | ||
| } | ||
| if (!config.defaultDevices) { | ||
| config.defaultDevices = {}; | ||
| } | ||
| config.defaultDevices[projectName] = deviceId; | ||
| await saveRuntimeConfig(config, cwd); | ||
| } | ||
| /** | ||
| * Get the default device for a project | ||
| */ | ||
| async function getDefaultDevice(projectName, cwd = process.cwd()) { | ||
| const config = await loadRuntimeConfig(cwd); | ||
| return config?.defaultDevices?.[projectName]; | ||
| } | ||
| class MissingConfigError extends Error { | ||
| constructor(message) { | ||
| super(message); | ||
| this.name = 'MissingConfigError'; | ||
| } | ||
| } | ||
| exports.MissingConfigError = MissingConfigError; | ||
| async function loadConfig(rootDir) { | ||
| const configPath = path_1.default.join(rootDir, 'agenteract.config.js'); | ||
| try { | ||
| await promises_1.default.access(configPath); | ||
| } | ||
| catch (error) { | ||
| throw new MissingConfigError('Agenteract config file not found'); | ||
| } | ||
| // In a Jest environment, dynamic import() of file URLs can be tricky. | ||
| // A simple and effective workaround is to read the file and evaluate it. | ||
| // This avoids the module resolution issues within the test runner. | ||
| const configContent = await promises_1.default.readFile(configPath, 'utf-8'); | ||
| // A simple regex to extract the default export object. | ||
| // This is not a full parser, but it's robust enough for our config file format. | ||
| const match = configContent.match(/export default (\{[\s\S]*\});/); | ||
| if (!match) { | ||
| console.error(`configContent: ${configContent}`); | ||
| throw new Error('Could not parse agenteract.config.js. Make sure it has a default export.'); | ||
| } | ||
| // We can use Function to evaluate the object literal. | ||
| // It's safer than eval() because it doesn't have access to the outer scope. | ||
| return new Function(`return ${match[1]}`)(); | ||
| } | ||
| /** | ||
| * Find the root directory containing agenteract.config.js | ||
| * Searches upward from the current working directory | ||
| */ | ||
| async function findConfigRoot(startDir = process.cwd()) { | ||
| let currentDir = startDir; | ||
| const root = path_1.default.parse(currentDir).root; | ||
| while (currentDir !== root) { | ||
| const configPath = path_1.default.join(currentDir, 'agenteract.config.js'); | ||
| try { | ||
| await promises_1.default.access(configPath); | ||
| return currentDir; | ||
| } | ||
| catch { | ||
| currentDir = path_1.default.dirname(currentDir); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| /** | ||
| * Get the URL for the agent server | ||
| */ | ||
| function getAgentServerUrl(config) { | ||
| return `http://localhost:${config.port || 8766}`; | ||
| } | ||
| /** | ||
| * Get the URL for a project's dev server | ||
| */ | ||
| function getProjectServerUrl(config, projectName) { | ||
| const project = config.projects.find(p => p.name === projectName); | ||
| if (!project) | ||
| return null; | ||
| // Check new devServer format first, then legacy ptyPort | ||
| const port = project.devServer?.port || project.ptyPort; | ||
| if (!port) { | ||
| return null; | ||
| } | ||
| return `http://localhost:${port}`; | ||
| } | ||
| /** | ||
| * Get the URL for a dev server by type | ||
| */ | ||
| function getDevServerUrlByType(config, type) { | ||
| const project = config.projects.find(p => p.type === type && (p.ptyPort || p.devServer?.port)); | ||
| if (!project) { | ||
| return null; | ||
| } | ||
| const port = project.devServer?.port || project.ptyPort; | ||
| return `http://localhost:${port}`; | ||
| } | ||
| /** | ||
| * Type presets for backward compatibility | ||
| * Maps old 'type' field to new devServer configuration | ||
| */ | ||
| exports.TYPE_PRESETS = { | ||
| expo: { | ||
| command: 'npx expo start', | ||
| keyCommands: { reload: 'r', ios: 'i', android: 'a' } | ||
| }, | ||
| vite: { | ||
| command: 'npx vite', | ||
| keyCommands: { reload: 'r', quit: 'q' } | ||
| }, | ||
| flutter: { | ||
| command: 'flutter run', | ||
| validation: { | ||
| fileExists: ['pubspec.yaml'], | ||
| commandInPath: 'flutter', | ||
| errorHints: { | ||
| 'command not found': 'Install Flutter: https://flutter.dev/docs/get-started/install', | ||
| 'No pubspec.yaml': 'Flutter projects require a pubspec.yaml file in the project directory' | ||
| } | ||
| }, | ||
| keyCommands: { reload: 'r', restart: 'R', quit: 'q', help: 'h' } | ||
| } | ||
| }; | ||
| /** | ||
| * Get default PTY port for a given type | ||
| */ | ||
| function getDefaultPortForType(type) { | ||
| const defaults = { | ||
| expo: 8790, | ||
| vite: 8791, | ||
| flutter: 8792 | ||
| }; | ||
| return defaults[type] || 8790; | ||
| } | ||
| async function addConfig(rootDir, projectPath, name, typeOrCommand, port, scheme) { | ||
| const configPath = path_1.default.join(rootDir, 'agenteract.config.js'); | ||
| let config; | ||
| try { | ||
| config = await loadConfig(rootDir); | ||
| } | ||
| catch (error) { | ||
| if (error instanceof MissingConfigError) { | ||
| config = { port: 8766, projects: [] }; | ||
| } | ||
| else { | ||
| // For other errors (like parsing), we should not proceed. | ||
| throw error; | ||
| } | ||
| } | ||
| config.projects = config.projects || []; | ||
| let nameExists = config.projects.find((p) => p.name === name); | ||
| let pathExists = config.projects.find((p) => p.path === projectPath); | ||
| if ((nameExists || pathExists) && nameExists !== pathExists) { | ||
| console.error('project name and path exist across multiple projects. Please use a different name or path.'); | ||
| console.error(`name: ${name}, path: ${projectPath}`); | ||
| return; | ||
| } | ||
| let update = nameExists || pathExists; | ||
| // Determine if this is legacy format (type) or new format (command) | ||
| const LEGACY_TYPES = ['expo', 'vite', 'flutter', 'native']; | ||
| const isLegacyFormat = LEGACY_TYPES.includes(typeOrCommand); | ||
| // Allocate a port if not provided | ||
| let ptyPort; | ||
| if (port) { | ||
| // Explicit port provided | ||
| ptyPort = port; | ||
| } | ||
| else if (update) { | ||
| // Reuse existing port when updating | ||
| ptyPort = update.ptyPort || update.devServer?.port || 8790; | ||
| } | ||
| else { | ||
| // Find next available port for new project | ||
| ptyPort = 8790; | ||
| while (config.projects.some((p) => (p.ptyPort === ptyPort) || (p.devServer?.port === ptyPort))) { | ||
| ptyPort++; | ||
| } | ||
| } | ||
| let newProjectConfig; | ||
| if (isLegacyFormat) { | ||
| // Legacy format: use old 'type' field for backwards compatibility | ||
| // Native apps don't have dev servers | ||
| if (typeOrCommand === 'native') { | ||
| newProjectConfig = { | ||
| name, | ||
| path: projectPath, | ||
| type: 'native', | ||
| ...(scheme && { scheme }) | ||
| }; | ||
| } | ||
| else { | ||
| // For non-native legacy types, create with new devServer format | ||
| const preset = exports.TYPE_PRESETS[typeOrCommand]; | ||
| if (!preset) { | ||
| console.error(`Unknown type '${typeOrCommand}'`); | ||
| return; | ||
| } | ||
| newProjectConfig = { | ||
| name, | ||
| path: projectPath, | ||
| devServer: { | ||
| ...preset, | ||
| port: ptyPort | ||
| }, | ||
| ...(scheme && { scheme }) | ||
| }; | ||
| console.log(`ℹ️ Creating config with new devServer format (migrated from legacy type '${typeOrCommand}')`); | ||
| } | ||
| } | ||
| else { | ||
| // New format: generic dev server command | ||
| newProjectConfig = { | ||
| name, | ||
| path: projectPath, | ||
| devServer: { | ||
| command: typeOrCommand, | ||
| port: ptyPort | ||
| }, | ||
| ...(scheme && { scheme }) | ||
| }; | ||
| } | ||
| // If the project already exists, replace it completely | ||
| if (update) { | ||
| // Find the index and replace the entire object to avoid keeping old fields | ||
| const index = config.projects.indexOf(update); | ||
| config.projects[index] = newProjectConfig; | ||
| } | ||
| else { | ||
| config.projects.push(newProjectConfig); | ||
| } | ||
| await promises_1.default.writeFile(configPath, `export default ${JSON.stringify(config, null, 2)};`); | ||
| console.log(`✅ Config updated: ${name} at ${projectPath}`); | ||
| if (newProjectConfig.devServer) { | ||
| console.log(` Dev server: ${newProjectConfig.devServer.command} (port: ${newProjectConfig.devServer.port})`); | ||
| } | ||
| if (scheme) { | ||
| console.log(` URL scheme: ${scheme}`); | ||
| } | ||
| } | ||
| /** | ||
| * Normalize project config: migrate old format to new format | ||
| * Logs deprecation warnings when using old 'type' field | ||
| */ | ||
| function normalizeProjectConfig(project, rootDir) { | ||
| // Already using new format | ||
| if (project.devServer) { | ||
| return project; | ||
| } | ||
| // Native type has no dev server | ||
| if (project.type === 'native') { | ||
| return project; | ||
| } | ||
| // Auto-migrate from old type-based format | ||
| if (project.type && project.type !== 'auto') { | ||
| console.warn(`⚠️ [${project.name}] Using deprecated 'type' field. ` + | ||
| `Migrate to 'devServer' config. See docs/MIGRATION_V2.md`); | ||
| const preset = exports.TYPE_PRESETS[project.type]; | ||
| if (!preset) { | ||
| console.error(`Unknown type '${project.type}' for project '${project.name}'`); | ||
| return project; | ||
| } | ||
| return { | ||
| ...project, | ||
| devServer: { | ||
| ...preset, | ||
| port: project.ptyPort || getDefaultPortForType(project.type) | ||
| } | ||
| }; | ||
| } | ||
| return project; | ||
| } |
| export * from './config.js'; | ||
| export * from './pnpm.js'; |
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
| for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| __exportStar(require("./config.js"), exports); | ||
| __exportStar(require("./pnpm.js"), exports); |
| /** | ||
| * if we're running in the agenteract monorepo, set node's CWD back to the original working directory | ||
| * otherwise pnpm commands have CWD set to the monorepo root | ||
| */ | ||
| export declare function resetPNPMWorkspaceCWD(): void; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.resetPNPMWorkspaceCWD = resetPNPMWorkspaceCWD; | ||
| /** | ||
| * if we're running in the agenteract monorepo, set node's CWD back to the original working directory | ||
| * otherwise pnpm commands have CWD set to the monorepo root | ||
| */ | ||
| function resetPNPMWorkspaceCWD() { | ||
| if (process.env.PNPM_PACKAGE_NAME == 'agenteract' && process.env.PWD && process.env.PWD !== process.cwd()) { | ||
| process.chdir(process.env.PWD); | ||
| } | ||
| } |
| export interface DevServerConfig { | ||
| command: string; | ||
| port: number; | ||
| cwd?: string; | ||
| env?: Record<string, string>; | ||
| validation?: { | ||
| fileExists?: string[]; | ||
| commandInPath?: string; | ||
| errorHints?: Record<string, string>; | ||
| }; | ||
| keyCommands?: Record<string, string>; | ||
| } | ||
| export interface ProjectConfig { | ||
| name: string; | ||
| path: string; | ||
| type?: 'expo' | 'vite' | 'flutter' | 'native' | 'auto'; | ||
| ptyPort?: number; | ||
| devServer?: DevServerConfig; | ||
| scheme?: string; | ||
| } | ||
| export interface AgenteractConfig { | ||
| server?: { | ||
| port?: number; | ||
| wsPort?: number; | ||
| logPort?: number; | ||
| }; | ||
| port?: number; | ||
| projects: ProjectConfig[]; | ||
| } |
| export {}; |
| import { AgenteractConfig, DevServerConfig, ProjectConfig } from '../config-types.js'; | ||
| export interface RuntimeConfig { | ||
| host: string; | ||
| port: number; | ||
| token: string; | ||
| defaultDevices?: Record<string, string>; | ||
| } | ||
| export declare function getRuntimeConfigPath(cwd?: string): string; | ||
| export declare function saveRuntimeConfig(config: RuntimeConfig, cwd?: string): Promise<void>; | ||
| export declare function loadRuntimeConfig(cwd?: string): Promise<RuntimeConfig | null>; | ||
| export declare function deleteRuntimeConfig(cwd?: string): Promise<void>; | ||
| export declare function generateAuthToken(): string; | ||
| /** | ||
| * Set the default device for a project | ||
| */ | ||
| export declare function setDefaultDevice(projectName: string, deviceId: string, cwd?: string): Promise<void>; | ||
| /** | ||
| * Get the default device for a project | ||
| */ | ||
| export declare function getDefaultDevice(projectName: string, cwd?: string): Promise<string | undefined>; | ||
| export declare class MissingConfigError extends Error { | ||
| constructor(message: string); | ||
| } | ||
| export declare function loadConfig(rootDir: string): Promise<AgenteractConfig>; | ||
| /** | ||
| * Find the root directory containing agenteract.config.js | ||
| * Searches upward from the current working directory | ||
| */ | ||
| export declare function findConfigRoot(startDir?: string): Promise<string | null>; | ||
| /** | ||
| * Get the URL for the agent server | ||
| */ | ||
| export declare function getAgentServerUrl(config: AgenteractConfig): string; | ||
| /** | ||
| * Get the URL for a project's dev server | ||
| */ | ||
| export declare function getProjectServerUrl(config: AgenteractConfig, projectName: string): string | null; | ||
| /** | ||
| * Get the URL for a dev server by type | ||
| */ | ||
| export declare function getDevServerUrlByType(config: AgenteractConfig, type: 'expo' | 'vite' | 'flutter'): string | null; | ||
| /** | ||
| * Type presets for backward compatibility | ||
| * Maps old 'type' field to new devServer configuration | ||
| */ | ||
| export declare const TYPE_PRESETS: Record<string, Omit<DevServerConfig, 'port'>>; | ||
| export declare function addConfig(rootDir: string, projectPath: string, name: string, typeOrCommand: string, port?: number, scheme?: string): Promise<void>; | ||
| /** | ||
| * Normalize project config: migrate old format to new format | ||
| * Logs deprecation warnings when using old 'type' field | ||
| */ | ||
| export declare function normalizeProjectConfig(project: ProjectConfig, rootDir: string): ProjectConfig; |
| import fs from 'fs/promises'; | ||
| import path from 'path'; | ||
| import { randomUUID } from 'crypto'; | ||
| export function getRuntimeConfigPath(cwd = process.cwd()) { | ||
| return path.join(cwd, '.agenteract-runtime.json'); | ||
| } | ||
| export async function saveRuntimeConfig(config, cwd = process.cwd()) { | ||
| await fs.writeFile(getRuntimeConfigPath(cwd), JSON.stringify(config, null, 2)); | ||
| } | ||
| export async function loadRuntimeConfig(cwd = process.cwd()) { | ||
| try { | ||
| const content = await fs.readFile(getRuntimeConfigPath(cwd), 'utf-8'); | ||
| return JSON.parse(content); | ||
| } | ||
| catch { | ||
| return null; | ||
| } | ||
| } | ||
| export async function deleteRuntimeConfig(cwd = process.cwd()) { | ||
| try { | ||
| await fs.unlink(getRuntimeConfigPath(cwd)); | ||
| } | ||
| catch { | ||
| // Ignore if file doesn't exist | ||
| } | ||
| } | ||
| export function generateAuthToken() { | ||
| return randomUUID(); | ||
| } | ||
| /** | ||
| * Set the default device for a project | ||
| */ | ||
| export async function setDefaultDevice(projectName, deviceId, cwd = process.cwd()) { | ||
| const config = await loadRuntimeConfig(cwd); | ||
| if (!config) { | ||
| throw new Error('Runtime config not found. Is the server running?'); | ||
| } | ||
| if (!config.defaultDevices) { | ||
| config.defaultDevices = {}; | ||
| } | ||
| config.defaultDevices[projectName] = deviceId; | ||
| await saveRuntimeConfig(config, cwd); | ||
| } | ||
| /** | ||
| * Get the default device for a project | ||
| */ | ||
| export async function getDefaultDevice(projectName, cwd = process.cwd()) { | ||
| const config = await loadRuntimeConfig(cwd); | ||
| return config?.defaultDevices?.[projectName]; | ||
| } | ||
| export class MissingConfigError extends Error { | ||
| constructor(message) { | ||
| super(message); | ||
| this.name = 'MissingConfigError'; | ||
| } | ||
| } | ||
| export async function loadConfig(rootDir) { | ||
| const configPath = path.join(rootDir, 'agenteract.config.js'); | ||
| try { | ||
| await fs.access(configPath); | ||
| } | ||
| catch (error) { | ||
| throw new MissingConfigError('Agenteract config file not found'); | ||
| } | ||
| // In a Jest environment, dynamic import() of file URLs can be tricky. | ||
| // A simple and effective workaround is to read the file and evaluate it. | ||
| // This avoids the module resolution issues within the test runner. | ||
| const configContent = await fs.readFile(configPath, 'utf-8'); | ||
| // A simple regex to extract the default export object. | ||
| // This is not a full parser, but it's robust enough for our config file format. | ||
| const match = configContent.match(/export default (\{[\s\S]*\});/); | ||
| if (!match) { | ||
| console.error(`configContent: ${configContent}`); | ||
| throw new Error('Could not parse agenteract.config.js. Make sure it has a default export.'); | ||
| } | ||
| // We can use Function to evaluate the object literal. | ||
| // It's safer than eval() because it doesn't have access to the outer scope. | ||
| return new Function(`return ${match[1]}`)(); | ||
| } | ||
| /** | ||
| * Find the root directory containing agenteract.config.js | ||
| * Searches upward from the current working directory | ||
| */ | ||
| export async function findConfigRoot(startDir = process.cwd()) { | ||
| let currentDir = startDir; | ||
| const root = path.parse(currentDir).root; | ||
| while (currentDir !== root) { | ||
| const configPath = path.join(currentDir, 'agenteract.config.js'); | ||
| try { | ||
| await fs.access(configPath); | ||
| return currentDir; | ||
| } | ||
| catch { | ||
| currentDir = path.dirname(currentDir); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| /** | ||
| * Get the URL for the agent server | ||
| */ | ||
| export function getAgentServerUrl(config) { | ||
| return `http://localhost:${config.port || 8766}`; | ||
| } | ||
| /** | ||
| * Get the URL for a project's dev server | ||
| */ | ||
| export function getProjectServerUrl(config, projectName) { | ||
| const project = config.projects.find(p => p.name === projectName); | ||
| if (!project) | ||
| return null; | ||
| // Check new devServer format first, then legacy ptyPort | ||
| const port = project.devServer?.port || project.ptyPort; | ||
| if (!port) { | ||
| return null; | ||
| } | ||
| return `http://localhost:${port}`; | ||
| } | ||
| /** | ||
| * Get the URL for a dev server by type | ||
| */ | ||
| export function getDevServerUrlByType(config, type) { | ||
| const project = config.projects.find(p => p.type === type && (p.ptyPort || p.devServer?.port)); | ||
| if (!project) { | ||
| return null; | ||
| } | ||
| const port = project.devServer?.port || project.ptyPort; | ||
| return `http://localhost:${port}`; | ||
| } | ||
| /** | ||
| * Type presets for backward compatibility | ||
| * Maps old 'type' field to new devServer configuration | ||
| */ | ||
| export const TYPE_PRESETS = { | ||
| expo: { | ||
| command: 'npx expo start', | ||
| keyCommands: { reload: 'r', ios: 'i', android: 'a' } | ||
| }, | ||
| vite: { | ||
| command: 'npx vite', | ||
| keyCommands: { reload: 'r', quit: 'q' } | ||
| }, | ||
| flutter: { | ||
| command: 'flutter run', | ||
| validation: { | ||
| fileExists: ['pubspec.yaml'], | ||
| commandInPath: 'flutter', | ||
| errorHints: { | ||
| 'command not found': 'Install Flutter: https://flutter.dev/docs/get-started/install', | ||
| 'No pubspec.yaml': 'Flutter projects require a pubspec.yaml file in the project directory' | ||
| } | ||
| }, | ||
| keyCommands: { reload: 'r', restart: 'R', quit: 'q', help: 'h' } | ||
| } | ||
| }; | ||
| /** | ||
| * Get default PTY port for a given type | ||
| */ | ||
| function getDefaultPortForType(type) { | ||
| const defaults = { | ||
| expo: 8790, | ||
| vite: 8791, | ||
| flutter: 8792 | ||
| }; | ||
| return defaults[type] || 8790; | ||
| } | ||
| export async function addConfig(rootDir, projectPath, name, typeOrCommand, port, scheme) { | ||
| const configPath = path.join(rootDir, 'agenteract.config.js'); | ||
| let config; | ||
| try { | ||
| config = await loadConfig(rootDir); | ||
| } | ||
| catch (error) { | ||
| if (error instanceof MissingConfigError) { | ||
| config = { port: 8766, projects: [] }; | ||
| } | ||
| else { | ||
| // For other errors (like parsing), we should not proceed. | ||
| throw error; | ||
| } | ||
| } | ||
| config.projects = config.projects || []; | ||
| let nameExists = config.projects.find((p) => p.name === name); | ||
| let pathExists = config.projects.find((p) => p.path === projectPath); | ||
| if ((nameExists || pathExists) && nameExists !== pathExists) { | ||
| console.error('project name and path exist across multiple projects. Please use a different name or path.'); | ||
| console.error(`name: ${name}, path: ${projectPath}`); | ||
| return; | ||
| } | ||
| let update = nameExists || pathExists; | ||
| // Determine if this is legacy format (type) or new format (command) | ||
| const LEGACY_TYPES = ['expo', 'vite', 'flutter', 'native']; | ||
| const isLegacyFormat = LEGACY_TYPES.includes(typeOrCommand); | ||
| // Allocate a port if not provided | ||
| let ptyPort; | ||
| if (port) { | ||
| // Explicit port provided | ||
| ptyPort = port; | ||
| } | ||
| else if (update) { | ||
| // Reuse existing port when updating | ||
| ptyPort = update.ptyPort || update.devServer?.port || 8790; | ||
| } | ||
| else { | ||
| // Find next available port for new project | ||
| ptyPort = 8790; | ||
| while (config.projects.some((p) => (p.ptyPort === ptyPort) || (p.devServer?.port === ptyPort))) { | ||
| ptyPort++; | ||
| } | ||
| } | ||
| let newProjectConfig; | ||
| if (isLegacyFormat) { | ||
| // Legacy format: use old 'type' field for backwards compatibility | ||
| // Native apps don't have dev servers | ||
| if (typeOrCommand === 'native') { | ||
| newProjectConfig = { | ||
| name, | ||
| path: projectPath, | ||
| type: 'native', | ||
| ...(scheme && { scheme }) | ||
| }; | ||
| } | ||
| else { | ||
| // For non-native legacy types, create with new devServer format | ||
| const preset = TYPE_PRESETS[typeOrCommand]; | ||
| if (!preset) { | ||
| console.error(`Unknown type '${typeOrCommand}'`); | ||
| return; | ||
| } | ||
| newProjectConfig = { | ||
| name, | ||
| path: projectPath, | ||
| devServer: { | ||
| ...preset, | ||
| port: ptyPort | ||
| }, | ||
| ...(scheme && { scheme }) | ||
| }; | ||
| console.log(`ℹ️ Creating config with new devServer format (migrated from legacy type '${typeOrCommand}')`); | ||
| } | ||
| } | ||
| else { | ||
| // New format: generic dev server command | ||
| newProjectConfig = { | ||
| name, | ||
| path: projectPath, | ||
| devServer: { | ||
| command: typeOrCommand, | ||
| port: ptyPort | ||
| }, | ||
| ...(scheme && { scheme }) | ||
| }; | ||
| } | ||
| // If the project already exists, replace it completely | ||
| if (update) { | ||
| // Find the index and replace the entire object to avoid keeping old fields | ||
| const index = config.projects.indexOf(update); | ||
| config.projects[index] = newProjectConfig; | ||
| } | ||
| else { | ||
| config.projects.push(newProjectConfig); | ||
| } | ||
| await fs.writeFile(configPath, `export default ${JSON.stringify(config, null, 2)};`); | ||
| console.log(`✅ Config updated: ${name} at ${projectPath}`); | ||
| if (newProjectConfig.devServer) { | ||
| console.log(` Dev server: ${newProjectConfig.devServer.command} (port: ${newProjectConfig.devServer.port})`); | ||
| } | ||
| if (scheme) { | ||
| console.log(` URL scheme: ${scheme}`); | ||
| } | ||
| } | ||
| /** | ||
| * Normalize project config: migrate old format to new format | ||
| * Logs deprecation warnings when using old 'type' field | ||
| */ | ||
| export function normalizeProjectConfig(project, rootDir) { | ||
| // Already using new format | ||
| if (project.devServer) { | ||
| return project; | ||
| } | ||
| // Native type has no dev server | ||
| if (project.type === 'native') { | ||
| return project; | ||
| } | ||
| // Auto-migrate from old type-based format | ||
| if (project.type && project.type !== 'auto') { | ||
| console.warn(`⚠️ [${project.name}] Using deprecated 'type' field. ` + | ||
| `Migrate to 'devServer' config. See docs/MIGRATION_V2.md`); | ||
| const preset = TYPE_PRESETS[project.type]; | ||
| if (!preset) { | ||
| console.error(`Unknown type '${project.type}' for project '${project.name}'`); | ||
| return project; | ||
| } | ||
| return { | ||
| ...project, | ||
| devServer: { | ||
| ...preset, | ||
| port: project.ptyPort || getDefaultPortForType(project.type) | ||
| } | ||
| }; | ||
| } | ||
| return project; | ||
| } |
| export * from './config.js'; | ||
| export * from './pnpm.js'; |
| export * from './config.js'; | ||
| export * from './pnpm.js'; |
| /** | ||
| * if we're running in the agenteract monorepo, set node's CWD back to the original working directory | ||
| * otherwise pnpm commands have CWD set to the monorepo root | ||
| */ | ||
| export declare function resetPNPMWorkspaceCWD(): void; |
| /** | ||
| * if we're running in the agenteract monorepo, set node's CWD back to the original working directory | ||
| * otherwise pnpm commands have CWD set to the monorepo root | ||
| */ | ||
| export function resetPNPMWorkspaceCWD() { | ||
| if (process.env.PNPM_PACKAGE_NAME == 'agenteract' && process.env.PWD && process.env.PWD !== process.cwd()) { | ||
| process.chdir(process.env.PWD); | ||
| } | ||
| } |
| export interface DevServerConfig { | ||
| command: string; | ||
| port: number; | ||
| cwd?: string; | ||
| env?: Record<string, string>; | ||
| validation?: { | ||
| fileExists?: string[]; | ||
| commandInPath?: string; | ||
| errorHints?: Record<string, string>; | ||
| }; | ||
| keyCommands?: Record<string, string>; | ||
| } | ||
| export interface ProjectConfig { | ||
| name: string; | ||
| path: string; | ||
| type?: 'expo' | 'vite' | 'flutter' | 'native' | 'auto'; | ||
| ptyPort?: number; | ||
| devServer?: DevServerConfig; | ||
| scheme?: string; | ||
| } | ||
| export interface AgenteractConfig { | ||
| server?: { | ||
| port?: number; | ||
| wsPort?: number; | ||
| logPort?: number; | ||
| }; | ||
| port?: number; | ||
| projects: ProjectConfig[]; | ||
| } |
| export {}; |
| import { AgenteractConfig, DevServerConfig, ProjectConfig } from '../config-types.js'; | ||
| export interface RuntimeConfig { | ||
| host: string; | ||
| port: number; | ||
| token: string; | ||
| defaultDevices?: Record<string, string>; | ||
| } | ||
| export declare function getRuntimeConfigPath(cwd?: string): string; | ||
| export declare function saveRuntimeConfig(config: RuntimeConfig, cwd?: string): Promise<void>; | ||
| export declare function loadRuntimeConfig(cwd?: string): Promise<RuntimeConfig | null>; | ||
| export declare function deleteRuntimeConfig(cwd?: string): Promise<void>; | ||
| export declare function generateAuthToken(): string; | ||
| /** | ||
| * Set the default device for a project | ||
| */ | ||
| export declare function setDefaultDevice(projectName: string, deviceId: string, cwd?: string): Promise<void>; | ||
| /** | ||
| * Get the default device for a project | ||
| */ | ||
| export declare function getDefaultDevice(projectName: string, cwd?: string): Promise<string | undefined>; | ||
| export declare class MissingConfigError extends Error { | ||
| constructor(message: string); | ||
| } | ||
| export declare function loadConfig(rootDir: string): Promise<AgenteractConfig>; | ||
| /** | ||
| * Find the root directory containing agenteract.config.js | ||
| * Searches upward from the current working directory | ||
| */ | ||
| export declare function findConfigRoot(startDir?: string): Promise<string | null>; | ||
| /** | ||
| * Get the URL for the agent server | ||
| */ | ||
| export declare function getAgentServerUrl(config: AgenteractConfig): string; | ||
| /** | ||
| * Get the URL for a project's dev server | ||
| */ | ||
| export declare function getProjectServerUrl(config: AgenteractConfig, projectName: string): string | null; | ||
| /** | ||
| * Get the URL for a dev server by type | ||
| */ | ||
| export declare function getDevServerUrlByType(config: AgenteractConfig, type: 'expo' | 'vite' | 'flutter'): string | null; | ||
| /** | ||
| * Type presets for backward compatibility | ||
| * Maps old 'type' field to new devServer configuration | ||
| */ | ||
| export declare const TYPE_PRESETS: Record<string, Omit<DevServerConfig, 'port'>>; | ||
| export declare function addConfig(rootDir: string, projectPath: string, name: string, typeOrCommand: string, port?: number, scheme?: string): Promise<void>; | ||
| /** | ||
| * Normalize project config: migrate old format to new format | ||
| * Logs deprecation warnings when using old 'type' field | ||
| */ | ||
| export declare function normalizeProjectConfig(project: ProjectConfig, rootDir: string): ProjectConfig; |
| import fs from 'fs/promises'; | ||
| import path from 'path'; | ||
| import { randomUUID } from 'crypto'; | ||
| export function getRuntimeConfigPath(cwd = process.cwd()) { | ||
| return path.join(cwd, '.agenteract-runtime.json'); | ||
| } | ||
| export async function saveRuntimeConfig(config, cwd = process.cwd()) { | ||
| await fs.writeFile(getRuntimeConfigPath(cwd), JSON.stringify(config, null, 2)); | ||
| } | ||
| export async function loadRuntimeConfig(cwd = process.cwd()) { | ||
| try { | ||
| const content = await fs.readFile(getRuntimeConfigPath(cwd), 'utf-8'); | ||
| return JSON.parse(content); | ||
| } | ||
| catch { | ||
| return null; | ||
| } | ||
| } | ||
| export async function deleteRuntimeConfig(cwd = process.cwd()) { | ||
| try { | ||
| await fs.unlink(getRuntimeConfigPath(cwd)); | ||
| } | ||
| catch { | ||
| // Ignore if file doesn't exist | ||
| } | ||
| } | ||
| export function generateAuthToken() { | ||
| return randomUUID(); | ||
| } | ||
| /** | ||
| * Set the default device for a project | ||
| */ | ||
| export async function setDefaultDevice(projectName, deviceId, cwd = process.cwd()) { | ||
| const config = await loadRuntimeConfig(cwd); | ||
| if (!config) { | ||
| throw new Error('Runtime config not found. Is the server running?'); | ||
| } | ||
| if (!config.defaultDevices) { | ||
| config.defaultDevices = {}; | ||
| } | ||
| config.defaultDevices[projectName] = deviceId; | ||
| await saveRuntimeConfig(config, cwd); | ||
| } | ||
| /** | ||
| * Get the default device for a project | ||
| */ | ||
| export async function getDefaultDevice(projectName, cwd = process.cwd()) { | ||
| const config = await loadRuntimeConfig(cwd); | ||
| return config?.defaultDevices?.[projectName]; | ||
| } | ||
| export class MissingConfigError extends Error { | ||
| constructor(message) { | ||
| super(message); | ||
| this.name = 'MissingConfigError'; | ||
| } | ||
| } | ||
| export async function loadConfig(rootDir) { | ||
| const configPath = path.join(rootDir, 'agenteract.config.js'); | ||
| try { | ||
| await fs.access(configPath); | ||
| } | ||
| catch (error) { | ||
| throw new MissingConfigError('Agenteract config file not found'); | ||
| } | ||
| // In a Jest environment, dynamic import() of file URLs can be tricky. | ||
| // A simple and effective workaround is to read the file and evaluate it. | ||
| // This avoids the module resolution issues within the test runner. | ||
| const configContent = await fs.readFile(configPath, 'utf-8'); | ||
| // A simple regex to extract the default export object. | ||
| // This is not a full parser, but it's robust enough for our config file format. | ||
| const match = configContent.match(/export default (\{[\s\S]*\});/); | ||
| if (!match) { | ||
| console.error(`configContent: ${configContent}`); | ||
| throw new Error('Could not parse agenteract.config.js. Make sure it has a default export.'); | ||
| } | ||
| // We can use Function to evaluate the object literal. | ||
| // It's safer than eval() because it doesn't have access to the outer scope. | ||
| return new Function(`return ${match[1]}`)(); | ||
| } | ||
| /** | ||
| * Find the root directory containing agenteract.config.js | ||
| * Searches upward from the current working directory | ||
| */ | ||
| export async function findConfigRoot(startDir = process.cwd()) { | ||
| let currentDir = startDir; | ||
| const root = path.parse(currentDir).root; | ||
| while (currentDir !== root) { | ||
| const configPath = path.join(currentDir, 'agenteract.config.js'); | ||
| try { | ||
| await fs.access(configPath); | ||
| return currentDir; | ||
| } | ||
| catch { | ||
| currentDir = path.dirname(currentDir); | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| /** | ||
| * Get the URL for the agent server | ||
| */ | ||
| export function getAgentServerUrl(config) { | ||
| return `http://localhost:${config.port || 8766}`; | ||
| } | ||
| /** | ||
| * Get the URL for a project's dev server | ||
| */ | ||
| export function getProjectServerUrl(config, projectName) { | ||
| const project = config.projects.find(p => p.name === projectName); | ||
| if (!project) | ||
| return null; | ||
| // Check new devServer format first, then legacy ptyPort | ||
| const port = project.devServer?.port || project.ptyPort; | ||
| if (!port) { | ||
| return null; | ||
| } | ||
| return `http://localhost:${port}`; | ||
| } | ||
| /** | ||
| * Get the URL for a dev server by type | ||
| */ | ||
| export function getDevServerUrlByType(config, type) { | ||
| const project = config.projects.find(p => p.type === type && (p.ptyPort || p.devServer?.port)); | ||
| if (!project) { | ||
| return null; | ||
| } | ||
| const port = project.devServer?.port || project.ptyPort; | ||
| return `http://localhost:${port}`; | ||
| } | ||
| /** | ||
| * Type presets for backward compatibility | ||
| * Maps old 'type' field to new devServer configuration | ||
| */ | ||
| export const TYPE_PRESETS = { | ||
| expo: { | ||
| command: 'npx expo start', | ||
| keyCommands: { reload: 'r', ios: 'i', android: 'a' } | ||
| }, | ||
| vite: { | ||
| command: 'npx vite', | ||
| keyCommands: { reload: 'r', quit: 'q' } | ||
| }, | ||
| flutter: { | ||
| command: 'flutter run', | ||
| validation: { | ||
| fileExists: ['pubspec.yaml'], | ||
| commandInPath: 'flutter', | ||
| errorHints: { | ||
| 'command not found': 'Install Flutter: https://flutter.dev/docs/get-started/install', | ||
| 'No pubspec.yaml': 'Flutter projects require a pubspec.yaml file in the project directory' | ||
| } | ||
| }, | ||
| keyCommands: { reload: 'r', restart: 'R', quit: 'q', help: 'h' } | ||
| } | ||
| }; | ||
| /** | ||
| * Get default PTY port for a given type | ||
| */ | ||
| function getDefaultPortForType(type) { | ||
| const defaults = { | ||
| expo: 8790, | ||
| vite: 8791, | ||
| flutter: 8792 | ||
| }; | ||
| return defaults[type] || 8790; | ||
| } | ||
| export async function addConfig(rootDir, projectPath, name, typeOrCommand, port, scheme) { | ||
| const configPath = path.join(rootDir, 'agenteract.config.js'); | ||
| let config; | ||
| try { | ||
| config = await loadConfig(rootDir); | ||
| } | ||
| catch (error) { | ||
| if (error instanceof MissingConfigError) { | ||
| config = { port: 8766, projects: [] }; | ||
| } | ||
| else { | ||
| // For other errors (like parsing), we should not proceed. | ||
| throw error; | ||
| } | ||
| } | ||
| config.projects = config.projects || []; | ||
| let nameExists = config.projects.find((p) => p.name === name); | ||
| let pathExists = config.projects.find((p) => p.path === projectPath); | ||
| if ((nameExists || pathExists) && nameExists !== pathExists) { | ||
| console.error('project name and path exist across multiple projects. Please use a different name or path.'); | ||
| console.error(`name: ${name}, path: ${projectPath}`); | ||
| return; | ||
| } | ||
| let update = nameExists || pathExists; | ||
| // Determine if this is legacy format (type) or new format (command) | ||
| const LEGACY_TYPES = ['expo', 'vite', 'flutter', 'native']; | ||
| const isLegacyFormat = LEGACY_TYPES.includes(typeOrCommand); | ||
| // Allocate a port if not provided | ||
| let ptyPort; | ||
| if (port) { | ||
| // Explicit port provided | ||
| ptyPort = port; | ||
| } | ||
| else if (update) { | ||
| // Reuse existing port when updating | ||
| ptyPort = update.ptyPort || update.devServer?.port || 8790; | ||
| } | ||
| else { | ||
| // Find next available port for new project | ||
| ptyPort = 8790; | ||
| while (config.projects.some((p) => (p.ptyPort === ptyPort) || (p.devServer?.port === ptyPort))) { | ||
| ptyPort++; | ||
| } | ||
| } | ||
| let newProjectConfig; | ||
| if (isLegacyFormat) { | ||
| // Legacy format: use old 'type' field for backwards compatibility | ||
| // Native apps don't have dev servers | ||
| if (typeOrCommand === 'native') { | ||
| newProjectConfig = { | ||
| name, | ||
| path: projectPath, | ||
| type: 'native', | ||
| ...(scheme && { scheme }) | ||
| }; | ||
| } | ||
| else { | ||
| // For non-native legacy types, create with new devServer format | ||
| const preset = TYPE_PRESETS[typeOrCommand]; | ||
| if (!preset) { | ||
| console.error(`Unknown type '${typeOrCommand}'`); | ||
| return; | ||
| } | ||
| newProjectConfig = { | ||
| name, | ||
| path: projectPath, | ||
| devServer: { | ||
| ...preset, | ||
| port: ptyPort | ||
| }, | ||
| ...(scheme && { scheme }) | ||
| }; | ||
| console.log(`ℹ️ Creating config with new devServer format (migrated from legacy type '${typeOrCommand}')`); | ||
| } | ||
| } | ||
| else { | ||
| // New format: generic dev server command | ||
| newProjectConfig = { | ||
| name, | ||
| path: projectPath, | ||
| devServer: { | ||
| command: typeOrCommand, | ||
| port: ptyPort | ||
| }, | ||
| ...(scheme && { scheme }) | ||
| }; | ||
| } | ||
| // If the project already exists, replace it completely | ||
| if (update) { | ||
| // Find the index and replace the entire object to avoid keeping old fields | ||
| const index = config.projects.indexOf(update); | ||
| config.projects[index] = newProjectConfig; | ||
| } | ||
| else { | ||
| config.projects.push(newProjectConfig); | ||
| } | ||
| await fs.writeFile(configPath, `export default ${JSON.stringify(config, null, 2)};`); | ||
| console.log(`✅ Config updated: ${name} at ${projectPath}`); | ||
| if (newProjectConfig.devServer) { | ||
| console.log(` Dev server: ${newProjectConfig.devServer.command} (port: ${newProjectConfig.devServer.port})`); | ||
| } | ||
| if (scheme) { | ||
| console.log(` URL scheme: ${scheme}`); | ||
| } | ||
| } | ||
| /** | ||
| * Normalize project config: migrate old format to new format | ||
| * Logs deprecation warnings when using old 'type' field | ||
| */ | ||
| export function normalizeProjectConfig(project, rootDir) { | ||
| // Already using new format | ||
| if (project.devServer) { | ||
| return project; | ||
| } | ||
| // Native type has no dev server | ||
| if (project.type === 'native') { | ||
| return project; | ||
| } | ||
| // Auto-migrate from old type-based format | ||
| if (project.type && project.type !== 'auto') { | ||
| console.warn(`⚠️ [${project.name}] Using deprecated 'type' field. ` + | ||
| `Migrate to 'devServer' config. See docs/MIGRATION_V2.md`); | ||
| const preset = TYPE_PRESETS[project.type]; | ||
| if (!preset) { | ||
| console.error(`Unknown type '${project.type}' for project '${project.name}'`); | ||
| return project; | ||
| } | ||
| return { | ||
| ...project, | ||
| devServer: { | ||
| ...preset, | ||
| port: project.ptyPort || getDefaultPortForType(project.type) | ||
| } | ||
| }; | ||
| } | ||
| return project; | ||
| } |
| export * from './config.js'; | ||
| export * from './pnpm.js'; |
| export * from './config.js'; | ||
| export * from './pnpm.js'; |
| /** | ||
| * if we're running in the agenteract monorepo, set node's CWD back to the original working directory | ||
| * otherwise pnpm commands have CWD set to the monorepo root | ||
| */ | ||
| export declare function resetPNPMWorkspaceCWD(): void; |
| /** | ||
| * if we're running in the agenteract monorepo, set node's CWD back to the original working directory | ||
| * otherwise pnpm commands have CWD set to the monorepo root | ||
| */ | ||
| export function resetPNPMWorkspaceCWD() { | ||
| if (process.env.PNPM_PACKAGE_NAME == 'agenteract' && process.env.PWD && process.env.PWD !== process.cwd()) { | ||
| process.chdir(process.env.PWD); | ||
| } | ||
| } |
@@ -1,1 +0,3 @@ | ||
| {"type":"commonjs"} | ||
| { | ||
| "type": "commonjs" | ||
| } |
@@ -19,1 +19,2 @@ export interface AgentCommand { | ||
| }; | ||
| export * from './config-types.js'; |
| "use strict"; | ||
| var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| var desc = Object.getOwnPropertyDescriptor(m, k); | ||
| if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
| desc = { enumerable: true, get: function() { return m[k]; } }; | ||
| } | ||
| Object.defineProperty(o, k2, desc); | ||
| }) : (function(o, m, k, k2) { | ||
| if (k2 === undefined) k2 = k; | ||
| o[k2] = m[k]; | ||
| })); | ||
| var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
| for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
@@ -33,1 +47,2 @@ exports.AGENTERACT_PROTOCOL_VERSION = void 0; | ||
| } | ||
| __exportStar(require("./config-types.js"), exports); |
@@ -1,1 +0,3 @@ | ||
| {"type":"module"} | ||
| { | ||
| "type": "module" | ||
| } |
@@ -19,1 +19,2 @@ export interface AgentCommand { | ||
| }; | ||
| export * from './config-types.js'; |
@@ -25,1 +25,2 @@ export const AGENTERACT_PROTOCOL_VERSION = '1.0.0'; | ||
| } | ||
| export * from './config-types.js'; |
@@ -19,1 +19,2 @@ export interface AgentCommand { | ||
| }; | ||
| export * from './config-types.js'; |
@@ -25,1 +25,2 @@ export const AGENTERACT_PROTOCOL_VERSION = '1.0.0'; | ||
| } | ||
| export * from './config-types.js'; |
+15
-3
| { | ||
| "name": "@agenteract/core", | ||
| "version": "0.0.3", | ||
| "version": "0.1.0", | ||
| "description": "Core message schema, bridge protocol, and shared utilities for Agenteract", | ||
@@ -8,2 +8,8 @@ "main": "./dist/cjs/src/index.js", | ||
| "types": "./dist/cjs/src/index.d.ts", | ||
| "files": [ | ||
| "dist/**/*.js", | ||
| "dist/**/*.d.ts", | ||
| "dist/**/package.json", | ||
| "!dist/**/*.tsbuildinfo" | ||
| ], | ||
| "repository": { | ||
@@ -31,2 +37,7 @@ "type": "git", | ||
| }, | ||
| "./node": { | ||
| "import": "./dist/esm/src/node/index.js", | ||
| "require": "./dist/cjs/src/node/index.js", | ||
| "types": "./dist/cjs/src/node/index.d.ts" | ||
| }, | ||
| "./package.json": "./package.json" | ||
@@ -39,8 +50,9 @@ }, | ||
| "scripts": { | ||
| "build": "npm run build:types && npm run build:cjs && npm run build:esm && npm run build:post", | ||
| "build": "pnpm run build:types && pnpm run build:cjs && pnpm run build:esm && pnpm run build:post", | ||
| "build:types": "tsc -p tsconfig.json", | ||
| "build:cjs": "tsc -p tsconfig.cjs.json", | ||
| "build:esm": "tsc -p tsconfig.esm.json", | ||
| "build:post": "echo '{\"type\":\"commonjs\"}' > dist/cjs/package.json && echo '{\"type\":\"module\"}' > dist/esm/package.json" | ||
| "build:post": "shx mkdir -p dist/cjs dist/esm && node ../../scripts/write-package-json.js commonjs dist/cjs/package.json && node ../../scripts/write-package-json.js module dist/esm/package.json", | ||
| "clean": "shx rm -rf dist .tsbuildinfo*" | ||
| } | ||
| } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
-4
| Agenteract | ||
| Copyright 2025 Michael Ribbons | ||
| This product includes software developed by the Agenteract project (https://github.com/agenteract). |
-43
| export interface AgentCommand { | ||
| action: string; | ||
| [key: string]: any; | ||
| } | ||
| export interface AgentResponse { | ||
| status: 'success' | 'error' | 'received'; | ||
| [key: string]: any; | ||
| } | ||
| export const AGENTERACT_PROTOCOL_VERSION = '1.0.0'; | ||
| export function encodeMessage(obj: object): string { | ||
| return JSON.stringify({ ...obj, _v: AGENTERACT_PROTOCOL_VERSION }); | ||
| } | ||
| export function decodeMessage<T>(json: string): T { | ||
| return JSON.parse(json) as unknown as T; | ||
| } | ||
| export function sendCommand(command: AgentCommand): Promise<AgentResponse> { | ||
| return Promise.resolve({ status: 'success', response: 'Command sent' }); | ||
| } | ||
| export function receiveResponse(response: AgentResponse): Promise<AgentCommand> { | ||
| return Promise.resolve({ action: 'response', response: response }); | ||
| } | ||
| export function detectInvoker(): { pkgManager: string, isNpx: boolean, isPnpmDlx: boolean } { | ||
| const ua = process.env.npm_config_user_agent || ''; | ||
| const execPath = process.env.npm_execpath || ''; | ||
| const pkgManager = | ||
| ua.startsWith('pnpm/') ? 'pnpm' : | ||
| ua.startsWith('yarn/') ? 'yarn' : | ||
| ua.startsWith('npm/') ? 'npm' : | ||
| 'unknown'; | ||
| const isNpx = execPath.includes('npx-cli.js'); | ||
| const isPnpmDlx = pkgManager === 'pnpm' && process.argv[1]?.includes('dlx'); | ||
| return { pkgManager, isNpx, isPnpmDlx }; | ||
| } |
| { | ||
| "extends": "./tsconfig.json", | ||
| "compilerOptions": { | ||
| "module": "CommonJS", | ||
| "outDir": "dist/cjs" | ||
| } | ||
| } | ||
| { | ||
| "extends": "./tsconfig.json", | ||
| "compilerOptions": { | ||
| "module": "ES2022", | ||
| "outDir": "dist/esm" | ||
| } | ||
| } | ||
| { | ||
| "extends": "../../tsconfig.base.json", | ||
| "exclude": ["node_modules", "dist"], | ||
| "include": ["src"], | ||
| "compilerOptions": { | ||
| "outDir": "dist", | ||
| "declaration": true, | ||
| "composite": true, | ||
| }, | ||
| } | ||
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 2 instances in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 4 instances in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
Unidentified License
LicenseSomething that seems like a license was found, but its contents could not be matched with a known license.
Found 1 instance in 1 package
34
88.89%0
-100%100
25%1404
635.08%63778
-53.75%22
175%7
Infinity%