mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-04 09:13:08 +00:00
refactor: update all imports to use shared packages
- Updated 150+ files to import from @automaker/* packages - Server imports now use @automaker/utils, @automaker/platform, @automaker/types, @automaker/model-resolver, @automaker/dependency-resolver, @automaker/git-utils - UI imports now use @automaker/dependency-resolver and @automaker/types - Deleted duplicate dependency-resolver files (222 lines eliminated) - Updated dependency-resolver to use ES modules for Vite compatibility - Added type annotation fix in auto-mode-service.ts - Updated feature-loader to re-export Feature type from @automaker/types - Both server and UI builds successfully verified Phase 1 of server refactoring complete. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,6 +19,12 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@anthropic-ai/claude-agent-sdk": "^0.1.72",
|
"@anthropic-ai/claude-agent-sdk": "^0.1.72",
|
||||||
|
"@automaker/dependency-resolver": "^1.0.0",
|
||||||
|
"@automaker/git-utils": "^1.0.0",
|
||||||
|
"@automaker/model-resolver": "^1.0.0",
|
||||||
|
"@automaker/platform": "^1.0.0",
|
||||||
|
"@automaker/types": "^1.0.0",
|
||||||
|
"@automaker/utils": "^1.0.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"express": "^5.2.1",
|
"express": "^5.2.1",
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { createServer } from "http";
|
|||||||
import dotenv from "dotenv";
|
import dotenv from "dotenv";
|
||||||
|
|
||||||
import { createEventEmitter, type EventEmitter } from "./lib/events.js";
|
import { createEventEmitter, type EventEmitter } from "./lib/events.js";
|
||||||
import { initAllowedPaths } from "./lib/security.js";
|
import { initAllowedPaths } from "@automaker/platform";
|
||||||
import { authMiddleware, getAuthStatus } from "./lib/auth.js";
|
import { authMiddleware, getAuthStatus } from "./lib/auth.js";
|
||||||
import { createFsRoutes } from "./routes/fs/index.js";
|
import { createFsRoutes } from "./routes/fs/index.js";
|
||||||
import { createHealthRoutes } from "./routes/health/index.js";
|
import { createHealthRoutes } from "./routes/health/index.js";
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
* - Convert history to Claude SDK message format
|
* - Convert history to Claude SDK message format
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { ConversationMessage } from "../providers/types.js";
|
import type { ConversationMessage } from "@automaker/types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract plain text from message content (handles both string and array formats)
|
* Extract plain text from message content (handles both string and array formats)
|
||||||
|
|||||||
@@ -1,221 +0,0 @@
|
|||||||
/**
|
|
||||||
* Dependency Resolution Utility (Server-side)
|
|
||||||
*
|
|
||||||
* Provides topological sorting and dependency analysis for features.
|
|
||||||
* Uses a modified Kahn's algorithm that respects both dependencies and priorities.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type { Feature } from "../services/feature-loader.js";
|
|
||||||
|
|
||||||
export interface DependencyResolutionResult {
|
|
||||||
orderedFeatures: Feature[]; // Features in dependency-aware order
|
|
||||||
circularDependencies: string[][]; // Groups of IDs forming cycles
|
|
||||||
missingDependencies: Map<string, string[]>; // featureId -> missing dep IDs
|
|
||||||
blockedFeatures: Map<string, string[]>; // featureId -> blocking dep IDs (incomplete dependencies)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves feature dependencies using topological sort with priority-aware ordering.
|
|
||||||
*
|
|
||||||
* Algorithm:
|
|
||||||
* 1. Build dependency graph and detect missing/blocked dependencies
|
|
||||||
* 2. Apply Kahn's algorithm for topological sort
|
|
||||||
* 3. Within same dependency level, sort by priority (1=high, 2=medium, 3=low)
|
|
||||||
* 4. Detect circular dependencies for features that can't be ordered
|
|
||||||
*
|
|
||||||
* @param features - Array of features to order
|
|
||||||
* @returns Resolution result with ordered features and dependency metadata
|
|
||||||
*/
|
|
||||||
export function resolveDependencies(features: Feature[]): DependencyResolutionResult {
|
|
||||||
const featureMap = new Map<string, Feature>(features.map(f => [f.id, f]));
|
|
||||||
const inDegree = new Map<string, number>();
|
|
||||||
const adjacencyList = new Map<string, string[]>(); // dependencyId -> [dependentIds]
|
|
||||||
const missingDependencies = new Map<string, string[]>();
|
|
||||||
const blockedFeatures = new Map<string, string[]>();
|
|
||||||
|
|
||||||
// Initialize graph structures
|
|
||||||
for (const feature of features) {
|
|
||||||
inDegree.set(feature.id, 0);
|
|
||||||
adjacencyList.set(feature.id, []);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build dependency graph and detect missing/blocked dependencies
|
|
||||||
for (const feature of features) {
|
|
||||||
const deps = feature.dependencies || [];
|
|
||||||
for (const depId of deps) {
|
|
||||||
if (!featureMap.has(depId)) {
|
|
||||||
// Missing dependency - track it
|
|
||||||
if (!missingDependencies.has(feature.id)) {
|
|
||||||
missingDependencies.set(feature.id, []);
|
|
||||||
}
|
|
||||||
missingDependencies.get(feature.id)!.push(depId);
|
|
||||||
} else {
|
|
||||||
// Valid dependency - add edge to graph
|
|
||||||
adjacencyList.get(depId)!.push(feature.id);
|
|
||||||
inDegree.set(feature.id, (inDegree.get(feature.id) || 0) + 1);
|
|
||||||
|
|
||||||
// Check if dependency is incomplete (blocking)
|
|
||||||
const depFeature = featureMap.get(depId)!;
|
|
||||||
if (depFeature.status !== 'completed' && depFeature.status !== 'verified') {
|
|
||||||
if (!blockedFeatures.has(feature.id)) {
|
|
||||||
blockedFeatures.set(feature.id, []);
|
|
||||||
}
|
|
||||||
blockedFeatures.get(feature.id)!.push(depId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kahn's algorithm with priority-aware selection
|
|
||||||
const queue: Feature[] = [];
|
|
||||||
const orderedFeatures: Feature[] = [];
|
|
||||||
|
|
||||||
// Helper to sort features by priority (lower number = higher priority)
|
|
||||||
const sortByPriority = (a: Feature, b: Feature) =>
|
|
||||||
(a.priority ?? 2) - (b.priority ?? 2);
|
|
||||||
|
|
||||||
// Start with features that have no dependencies (in-degree 0)
|
|
||||||
for (const [id, degree] of inDegree) {
|
|
||||||
if (degree === 0) {
|
|
||||||
queue.push(featureMap.get(id)!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort initial queue by priority
|
|
||||||
queue.sort(sortByPriority);
|
|
||||||
|
|
||||||
// Process features in topological order
|
|
||||||
while (queue.length > 0) {
|
|
||||||
// Take highest priority feature from queue
|
|
||||||
const current = queue.shift()!;
|
|
||||||
orderedFeatures.push(current);
|
|
||||||
|
|
||||||
// Process features that depend on this one
|
|
||||||
for (const dependentId of adjacencyList.get(current.id) || []) {
|
|
||||||
const currentDegree = inDegree.get(dependentId);
|
|
||||||
if (currentDegree === undefined) {
|
|
||||||
throw new Error(`In-degree not initialized for feature ${dependentId}`);
|
|
||||||
}
|
|
||||||
const newDegree = currentDegree - 1;
|
|
||||||
inDegree.set(dependentId, newDegree);
|
|
||||||
|
|
||||||
if (newDegree === 0) {
|
|
||||||
queue.push(featureMap.get(dependentId)!);
|
|
||||||
// Re-sort queue to maintain priority order
|
|
||||||
queue.sort(sortByPriority);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect circular dependencies (features not in output = part of cycle)
|
|
||||||
const circularDependencies: string[][] = [];
|
|
||||||
const processedIds = new Set(orderedFeatures.map(f => f.id));
|
|
||||||
|
|
||||||
if (orderedFeatures.length < features.length) {
|
|
||||||
// Find cycles using DFS
|
|
||||||
const remaining = features.filter(f => !processedIds.has(f.id));
|
|
||||||
const cycles = detectCycles(remaining, featureMap);
|
|
||||||
circularDependencies.push(...cycles);
|
|
||||||
|
|
||||||
// Add remaining features at end (part of cycles)
|
|
||||||
orderedFeatures.push(...remaining);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
orderedFeatures,
|
|
||||||
circularDependencies,
|
|
||||||
missingDependencies,
|
|
||||||
blockedFeatures
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detects circular dependencies using depth-first search
|
|
||||||
*
|
|
||||||
* @param features - Features that couldn't be topologically sorted (potential cycles)
|
|
||||||
* @param featureMap - Map of all features by ID
|
|
||||||
* @returns Array of cycles, where each cycle is an array of feature IDs
|
|
||||||
*/
|
|
||||||
function detectCycles(
|
|
||||||
features: Feature[],
|
|
||||||
featureMap: Map<string, Feature>
|
|
||||||
): string[][] {
|
|
||||||
const cycles: string[][] = [];
|
|
||||||
const visited = new Set<string>();
|
|
||||||
const recursionStack = new Set<string>();
|
|
||||||
const currentPath: string[] = [];
|
|
||||||
|
|
||||||
function dfs(featureId: string): boolean {
|
|
||||||
visited.add(featureId);
|
|
||||||
recursionStack.add(featureId);
|
|
||||||
currentPath.push(featureId);
|
|
||||||
|
|
||||||
const feature = featureMap.get(featureId);
|
|
||||||
if (feature) {
|
|
||||||
for (const depId of feature.dependencies || []) {
|
|
||||||
if (!visited.has(depId)) {
|
|
||||||
if (dfs(depId)) return true;
|
|
||||||
} else if (recursionStack.has(depId)) {
|
|
||||||
// Found cycle - extract it
|
|
||||||
const cycleStart = currentPath.indexOf(depId);
|
|
||||||
cycles.push(currentPath.slice(cycleStart));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentPath.pop();
|
|
||||||
recursionStack.delete(featureId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const feature of features) {
|
|
||||||
if (!visited.has(feature.id)) {
|
|
||||||
dfs(feature.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cycles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a feature's dependencies are satisfied (all complete or verified)
|
|
||||||
*
|
|
||||||
* @param feature - Feature to check
|
|
||||||
* @param allFeatures - All features in the project
|
|
||||||
* @returns true if all dependencies are satisfied, false otherwise
|
|
||||||
*/
|
|
||||||
export function areDependenciesSatisfied(
|
|
||||||
feature: Feature,
|
|
||||||
allFeatures: Feature[]
|
|
||||||
): boolean {
|
|
||||||
if (!feature.dependencies || feature.dependencies.length === 0) {
|
|
||||||
return true; // No dependencies = always ready
|
|
||||||
}
|
|
||||||
|
|
||||||
return feature.dependencies.every((depId: string) => {
|
|
||||||
const dep = allFeatures.find(f => f.id === depId);
|
|
||||||
return dep && (dep.status === 'completed' || dep.status === 'verified');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the blocking dependencies for a feature (dependencies that are incomplete)
|
|
||||||
*
|
|
||||||
* @param feature - Feature to check
|
|
||||||
* @param allFeatures - All features in the project
|
|
||||||
* @returns Array of feature IDs that are blocking this feature
|
|
||||||
*/
|
|
||||||
export function getBlockingDependencies(
|
|
||||||
feature: Feature,
|
|
||||||
allFeatures: Feature[]
|
|
||||||
): string[] {
|
|
||||||
if (!feature.dependencies || feature.dependencies.length === 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return feature.dependencies.filter((depId: string) => {
|
|
||||||
const dep = allFeatures.find(f => f.id === depId);
|
|
||||||
return dep && dep.status !== 'completed' && dep.status !== 'verified';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities for agent routes
|
* Common utilities for agent routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getErrorMessage as getErrorMessageShared,
|
getErrorMessage as getErrorMessageShared,
|
||||||
createLogError,
|
createLogError,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { AgentService } from "../../../services/agent-service.js";
|
import { AgentService } from "../../../services/agent-service.js";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
const logger = createLogger("Agent");
|
const logger = createLogger("Agent");
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { AgentService } from "../../../services/agent-service.js";
|
import { AgentService } from "../../../services/agent-service.js";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
const logger = createLogger("Agent");
|
const logger = createLogger("Agent");
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities and state management for spec regeneration
|
* Common utilities and state management for spec regeneration
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
|
|
||||||
const logger = createLogger("SpecRegeneration");
|
const logger = createLogger("SpecRegeneration");
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
import { query } from "@anthropic-ai/claude-agent-sdk";
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import type { EventEmitter } from "../../lib/events.js";
|
import type { EventEmitter } from "../../lib/events.js";
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import { createFeatureGenerationOptions } from "../../lib/sdk-options.js";
|
import { createFeatureGenerationOptions } from "../../lib/sdk-options.js";
|
||||||
import { logAuthStatus } from "./common.js";
|
import { logAuthStatus } from "./common.js";
|
||||||
import { parseAndCreateFeatures } from "./parse-and-create-features.js";
|
import { parseAndCreateFeatures } from "./parse-and-create-features.js";
|
||||||
import { getAppSpecPath } from "../../lib/automaker-paths.js";
|
import { getAppSpecPath } from "@automaker/platform";
|
||||||
|
|
||||||
const logger = createLogger("SpecRegeneration");
|
const logger = createLogger("SpecRegeneration");
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,11 @@ import {
|
|||||||
getStructuredSpecPromptInstruction,
|
getStructuredSpecPromptInstruction,
|
||||||
type SpecOutput,
|
type SpecOutput,
|
||||||
} from "../../lib/app-spec-format.js";
|
} from "../../lib/app-spec-format.js";
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import { createSpecGenerationOptions } from "../../lib/sdk-options.js";
|
import { createSpecGenerationOptions } from "../../lib/sdk-options.js";
|
||||||
import { logAuthStatus } from "./common.js";
|
import { logAuthStatus } from "./common.js";
|
||||||
import { generateFeaturesFromSpec } from "./generate-features-from-spec.js";
|
import { generateFeaturesFromSpec } from "./generate-features-from-spec.js";
|
||||||
import { ensureAutomakerDir, getAppSpecPath } from "../../lib/automaker-paths.js";
|
import { ensureAutomakerDir, getAppSpecPath } from "@automaker/platform";
|
||||||
|
|
||||||
const logger = createLogger("SpecRegeneration");
|
const logger = createLogger("SpecRegeneration");
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import type { EventEmitter } from "../../lib/events.js";
|
import type { EventEmitter } from "../../lib/events.js";
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import { getFeaturesDir } from "../../lib/automaker-paths.js";
|
import { getFeaturesDir } from "@automaker/platform";
|
||||||
|
|
||||||
const logger = createLogger("SpecRegeneration");
|
const logger = createLogger("SpecRegeneration");
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import type { EventEmitter } from "../../../lib/events.js";
|
import type { EventEmitter } from "../../../lib/events.js";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getSpecRegenerationStatus,
|
getSpecRegenerationStatus,
|
||||||
setRunningState,
|
setRunningState,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import type { EventEmitter } from "../../../lib/events.js";
|
import type { EventEmitter } from "../../../lib/events.js";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getSpecRegenerationStatus,
|
getSpecRegenerationStatus,
|
||||||
setRunningState,
|
setRunningState,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import type { EventEmitter } from "../../../lib/events.js";
|
import type { EventEmitter } from "../../../lib/events.js";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getSpecRegenerationStatus,
|
getSpecRegenerationStatus,
|
||||||
setRunningState,
|
setRunningState,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities for auto-mode routes
|
* Common utilities for auto-mode routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getErrorMessage as getErrorMessageShared,
|
getErrorMessage as getErrorMessageShared,
|
||||||
createLogError,
|
createLogError,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import type { AutoModeService } from "../../../services/auto-mode-service.js";
|
import type { AutoModeService } from "../../../services/auto-mode-service.js";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
const logger = createLogger("AutoMode");
|
const logger = createLogger("AutoMode");
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import type { AutoModeService } from "../../../services/auto-mode-service.js";
|
import type { AutoModeService } from "../../../services/auto-mode-service.js";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
const logger = createLogger("AutoMode");
|
const logger = createLogger("AutoMode");
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import type { AutoModeService } from "../../../services/auto-mode-service.js";
|
import type { AutoModeService } from "../../../services/auto-mode-service.js";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
const logger = createLogger("AutoMode");
|
const logger = createLogger("AutoMode");
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import type { AutoModeService } from "../../../services/auto-mode-service.js";
|
import type { AutoModeService } from "../../../services/auto-mode-service.js";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
const logger = createLogger("AutoMode");
|
const logger = createLogger("AutoMode");
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import type { AutoModeService } from "../../../services/auto-mode-service.js";
|
import type { AutoModeService } from "../../../services/auto-mode-service.js";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
const logger = createLogger("AutoMode");
|
const logger = createLogger("AutoMode");
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities shared across all route modules
|
* Common utilities shared across all route modules
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { exec } from "child_process";
|
import { exec } from "child_process";
|
||||||
|
|||||||
@@ -7,14 +7,15 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { query } from "@anthropic-ai/claude-agent-sdk";
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
|
import { resolveModelString } from "@automaker/model-resolver";
|
||||||
|
import { CLAUDE_MODEL_MAP } from "@automaker/types";
|
||||||
import {
|
import {
|
||||||
getSystemPrompt,
|
getSystemPrompt,
|
||||||
buildUserPrompt,
|
buildUserPrompt,
|
||||||
isValidEnhancementMode,
|
isValidEnhancementMode,
|
||||||
type EnhancementMode,
|
type EnhancementMode,
|
||||||
} from "../../../lib/enhancement-prompts.js";
|
} from "../../../lib/enhancement-prompts.js";
|
||||||
import { resolveModelString, CLAUDE_MODEL_MAP } from "../../../lib/model-resolver.js";
|
|
||||||
|
|
||||||
const logger = createLogger("EnhancePrompt");
|
const logger = createLogger("EnhancePrompt");
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities for features routes
|
* Common utilities for features routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getErrorMessage as getErrorMessageShared,
|
getErrorMessage as getErrorMessageShared,
|
||||||
createLogError,
|
createLogError,
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
FeatureLoader,
|
FeatureLoader,
|
||||||
type Feature,
|
type Feature,
|
||||||
} from "../../../services/feature-loader.js";
|
} from "../../../services/feature-loader.js";
|
||||||
import { addAllowedPath } from "../../../lib/security.js";
|
import { addAllowedPath } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
export function createCreateHandler(featureLoader: FeatureLoader) {
|
export function createCreateHandler(featureLoader: FeatureLoader) {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { FeatureLoader } from "../../../services/feature-loader.js";
|
import { FeatureLoader } from "../../../services/feature-loader.js";
|
||||||
import { addAllowedPath } from "../../../lib/security.js";
|
import { addAllowedPath } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
export function createListHandler(featureLoader: FeatureLoader) {
|
export function createListHandler(featureLoader: FeatureLoader) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities for fs routes
|
* Common utilities for fs routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getErrorMessage as getErrorMessageShared,
|
getErrorMessage as getErrorMessageShared,
|
||||||
createLogError,
|
createLogError,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import type { Request, Response } from "express";
|
|||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
import { getBoardDir } from "../../../lib/automaker-paths.js";
|
import { getBoardDir } from "@automaker/platform";
|
||||||
|
|
||||||
export function createDeleteBoardBackgroundHandler() {
|
export function createDeleteBoardBackgroundHandler() {
|
||||||
return async (req: Request, res: Response): Promise<void> => {
|
return async (req: Request, res: Response): Promise<void> => {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import { validatePath } from "../../../lib/security.js";
|
import { validatePath } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
export function createDeleteHandler() {
|
export function createDeleteHandler() {
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { addAllowedPath } from "../../../lib/security.js";
|
import { addAllowedPath } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
export function createMkdirHandler() {
|
export function createMkdirHandler() {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import { validatePath } from "../../../lib/security.js";
|
import { validatePath } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
// Optional files that are expected to not exist in new projects
|
// Optional files that are expected to not exist in new projects
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import { validatePath } from "../../../lib/security.js";
|
import { validatePath } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
export function createReaddirHandler() {
|
export function createReaddirHandler() {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { addAllowedPath } from "../../../lib/security.js";
|
import { addAllowedPath } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
export function createResolveDirectoryHandler() {
|
export function createResolveDirectoryHandler() {
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { addAllowedPath } from "../../../lib/security.js";
|
import { addAllowedPath } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
import { getBoardDir } from "../../../lib/automaker-paths.js";
|
import { getBoardDir } from "@automaker/platform";
|
||||||
|
|
||||||
export function createSaveBoardBackgroundHandler() {
|
export function createSaveBoardBackgroundHandler() {
|
||||||
return async (req: Request, res: Response): Promise<void> => {
|
return async (req: Request, res: Response): Promise<void> => {
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { addAllowedPath } from "../../../lib/security.js";
|
import { addAllowedPath } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
import { getImagesDir } from "../../../lib/automaker-paths.js";
|
import { getImagesDir } from "@automaker/platform";
|
||||||
|
|
||||||
export function createSaveImageHandler() {
|
export function createSaveImageHandler() {
|
||||||
return async (req: Request, res: Response): Promise<void> => {
|
return async (req: Request, res: Response): Promise<void> => {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import { validatePath } from "../../../lib/security.js";
|
import { validatePath } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
export function createStatHandler() {
|
export function createStatHandler() {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { addAllowedPath, isPathAllowed } from "../../../lib/security.js";
|
import { addAllowedPath, isPathAllowed } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
export function createValidatePathHandler() {
|
export function createValidatePathHandler() {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { validatePath } from "../../../lib/security.js";
|
import { validatePath } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
import { mkdirSafe } from "../../../lib/fs-utils.js";
|
import { mkdirSafe } from "../../../lib/fs-utils.js";
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities for git routes
|
* Common utilities for git routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getErrorMessage as getErrorMessageShared,
|
getErrorMessage as getErrorMessageShared,
|
||||||
createLogError,
|
createLogError,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities for health routes
|
* Common utilities for health routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getErrorMessage as getErrorMessageShared,
|
getErrorMessage as getErrorMessageShared,
|
||||||
createLogError,
|
createLogError,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities for models routes
|
* Common utilities for models routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getErrorMessage as getErrorMessageShared,
|
getErrorMessage as getErrorMessageShared,
|
||||||
createLogError,
|
createLogError,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities for running-agents routes
|
* Common utilities for running-agents routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getErrorMessage as getErrorMessageShared,
|
getErrorMessage as getErrorMessageShared,
|
||||||
createLogError,
|
createLogError,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities for sessions routes
|
* Common utilities for sessions routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getErrorMessage as getErrorMessageShared,
|
getErrorMessage as getErrorMessageShared,
|
||||||
createLogError,
|
createLogError,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities and state for setup routes
|
* Common utilities and state for setup routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
getErrorMessage,
|
getErrorMessage,
|
||||||
logError,
|
logError,
|
||||||
} from "../common.js";
|
} from "../common.js";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
|
|
||||||
const logger = createLogger("Setup");
|
const logger = createLogger("Setup");
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { query } from "@anthropic-ai/claude-agent-sdk";
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import { getApiKey } from "../common.js";
|
import { getApiKey } from "../common.js";
|
||||||
|
|
||||||
const logger = createLogger("Setup");
|
const logger = createLogger("Setup");
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities and state for suggestions routes
|
* Common utilities and state for suggestions routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getErrorMessage as getErrorMessageShared,
|
getErrorMessage as getErrorMessageShared,
|
||||||
createLogError,
|
createLogError,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import { query } from "@anthropic-ai/claude-agent-sdk";
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
||||||
import type { EventEmitter } from "../../lib/events.js";
|
import type { EventEmitter } from "../../lib/events.js";
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import { createSuggestionsOptions } from "../../lib/sdk-options.js";
|
import { createSuggestionsOptions } from "../../lib/sdk-options.js";
|
||||||
|
|
||||||
const logger = createLogger("Suggestions");
|
const logger = createLogger("Suggestions");
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import type { EventEmitter } from "../../../lib/events.js";
|
import type { EventEmitter } from "../../../lib/events.js";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getSuggestionsStatus,
|
getSuggestionsStatus,
|
||||||
setRunningState,
|
setRunningState,
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities for templates routes
|
* Common utilities for templates routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getErrorMessage as getErrorMessageShared,
|
getErrorMessage as getErrorMessageShared,
|
||||||
createLogError,
|
createLogError,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import type { Request, Response } from "express";
|
|||||||
import { spawn } from "child_process";
|
import { spawn } from "child_process";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import { addAllowedPath } from "../../../lib/security.js";
|
import { addAllowedPath } from "@automaker/platform";
|
||||||
import { logger, getErrorMessage, logError } from "../common.js";
|
import { logger, getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
export function createCloneHandler() {
|
export function createCloneHandler() {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities and state for terminal routes
|
* Common utilities and state for terminal routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import type { Request, Response, NextFunction } from "express";
|
import type { Request, Response, NextFunction } from "express";
|
||||||
import { getTerminalService } from "../../services/terminal-service.js";
|
import { getTerminalService } from "../../services/terminal-service.js";
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { getTerminalService } from "../../../services/terminal-service.js";
|
import { getTerminalService } from "../../../services/terminal-service.js";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
import { createLogger } from "../../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
|
|
||||||
const logger = createLogger("Terminal");
|
const logger = createLogger("Terminal");
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities for workspace routes
|
* Common utilities for workspace routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import {
|
import {
|
||||||
getErrorMessage as getErrorMessageShared,
|
getErrorMessage as getErrorMessageShared,
|
||||||
createLogError,
|
createLogError,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import { addAllowedPath } from "../../../lib/security.js";
|
import { addAllowedPath } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
export function createConfigHandler() {
|
export function createConfigHandler() {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { addAllowedPath } from "../../../lib/security.js";
|
import { addAllowedPath } from "@automaker/platform";
|
||||||
import { getErrorMessage, logError } from "../common.js";
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
export function createDirectoriesHandler() {
|
export function createDirectoriesHandler() {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Common utilities for worktree routes
|
* Common utilities for worktree routes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { createLogger } from "../../lib/logger.js";
|
import { createLogger } from "@automaker/utils";
|
||||||
import { exec } from "child_process";
|
import { exec } from "child_process";
|
||||||
import { promisify } from "util";
|
import { promisify } from "util";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import path from "path";
|
|||||||
import {
|
import {
|
||||||
getBranchTrackingPath,
|
getBranchTrackingPath,
|
||||||
ensureAutomakerDir,
|
ensureAutomakerDir,
|
||||||
} from "../../../lib/automaker-paths.js";
|
} from "@automaker/platform";
|
||||||
|
|
||||||
export interface TrackedBranch {
|
export interface TrackedBranch {
|
||||||
name: string;
|
name: string;
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { exec } from "child_process";
|
import { exec } from "child_process";
|
||||||
import { promisify } from "util";
|
import { promisify } from "util";
|
||||||
import { isGitRepo, getErrorMessage, logError } from "../common.js";
|
import { isGitRepo } from "@automaker/git-utils";
|
||||||
|
import { getErrorMessage, logError } from "../common.js";
|
||||||
|
|
||||||
const execAsync = promisify(exec);
|
const execAsync = promisify(exec);
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,8 @@ import type { Request, Response } from "express";
|
|||||||
import { exec } from "child_process";
|
import { exec } from "child_process";
|
||||||
import { promisify } from "util";
|
import { promisify } from "util";
|
||||||
import { existsSync } from "fs";
|
import { existsSync } from "fs";
|
||||||
import { isGitRepo, getErrorMessage, logError, normalizePath } from "../common.js";
|
import { isGitRepo } from "@automaker/git-utils";
|
||||||
|
import { getErrorMessage, logError, normalizePath } from "../common.js";
|
||||||
|
|
||||||
const execAsync = promisify(exec);
|
const execAsync = promisify(exec);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { getAutomakerDir } from "../../../lib/automaker-paths.js";
|
import { getAutomakerDir } from "@automaker/platform";
|
||||||
|
|
||||||
export function createMigrateHandler() {
|
export function createMigrateHandler() {
|
||||||
return async (req: Request, res: Response): Promise<void> => {
|
return async (req: Request, res: Response): Promise<void> => {
|
||||||
|
|||||||
@@ -7,12 +7,10 @@ import { AbortError } from "@anthropic-ai/claude-agent-sdk";
|
|||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import type { EventEmitter } from "../lib/events.js";
|
import type { EventEmitter } from "../lib/events.js";
|
||||||
|
import type { ExecuteOptions } from "@automaker/types";
|
||||||
|
import { readImageAsBase64, buildPromptWithImages, isAbortError } from "@automaker/utils";
|
||||||
import { ProviderFactory } from "../providers/provider-factory.js";
|
import { ProviderFactory } from "../providers/provider-factory.js";
|
||||||
import type { ExecuteOptions } from "../providers/types.js";
|
|
||||||
import { readImageAsBase64 } from "../lib/image-handler.js";
|
|
||||||
import { buildPromptWithImages } from "../lib/prompt-builder.js";
|
|
||||||
import { createChatOptions } from "../lib/sdk-options.js";
|
import { createChatOptions } from "../lib/sdk-options.js";
|
||||||
import { isAbortError } from "../lib/error-handler.js";
|
|
||||||
|
|
||||||
interface Message {
|
interface Message {
|
||||||
id: string;
|
id: string;
|
||||||
|
|||||||
@@ -10,20 +10,18 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { ProviderFactory } from "../providers/provider-factory.js";
|
import { ProviderFactory } from "../providers/provider-factory.js";
|
||||||
import type { ExecuteOptions } from "../providers/types.js";
|
import type { ExecuteOptions, Feature } from "@automaker/types";
|
||||||
|
import { buildPromptWithImages, isAbortError, classifyError } from "@automaker/utils";
|
||||||
|
import { resolveModelString, DEFAULT_MODELS } from "@automaker/model-resolver";
|
||||||
|
import { resolveDependencies, areDependenciesSatisfied } from "@automaker/dependency-resolver";
|
||||||
|
import { getFeatureDir, getAutomakerDir, getFeaturesDir, getContextDir } from "@automaker/platform";
|
||||||
import { exec } from "child_process";
|
import { exec } from "child_process";
|
||||||
import { promisify } from "util";
|
import { promisify } from "util";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import type { EventEmitter } from "../lib/events.js";
|
import type { EventEmitter } from "../lib/events.js";
|
||||||
import { buildPromptWithImages } from "../lib/prompt-builder.js";
|
|
||||||
import { resolveModelString, DEFAULT_MODELS } from "../lib/model-resolver.js";
|
|
||||||
import { createAutoModeOptions } from "../lib/sdk-options.js";
|
import { createAutoModeOptions } from "../lib/sdk-options.js";
|
||||||
import { isAbortError, classifyError } from "../lib/error-handler.js";
|
|
||||||
import { resolveDependencies, areDependenciesSatisfied } from "../lib/dependency-resolver.js";
|
|
||||||
import type { Feature } from "./feature-loader.js";
|
|
||||||
import { FeatureLoader } from "./feature-loader.js";
|
import { FeatureLoader } from "./feature-loader.js";
|
||||||
import { getFeatureDir, getAutomakerDir, getFeaturesDir, getContextDir } from "../lib/automaker-paths.js";
|
|
||||||
|
|
||||||
const execAsync = promisify(exec);
|
const execAsync = promisify(exec);
|
||||||
|
|
||||||
@@ -1606,7 +1604,7 @@ Format your response as a structured markdown document.`;
|
|||||||
const { orderedFeatures } = resolveDependencies(pendingFeatures);
|
const { orderedFeatures } = resolveDependencies(pendingFeatures);
|
||||||
|
|
||||||
// Filter to only features with satisfied dependencies
|
// Filter to only features with satisfied dependencies
|
||||||
const readyFeatures = orderedFeatures.filter(feature =>
|
const readyFeatures = orderedFeatures.filter((feature: Feature) =>
|
||||||
areDependenciesSatisfied(feature, allFeatures)
|
areDependenciesSatisfied(feature, allFeatures)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -5,46 +5,16 @@
|
|||||||
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
|
import type { Feature } from "@automaker/types";
|
||||||
import {
|
import {
|
||||||
getFeaturesDir,
|
getFeaturesDir,
|
||||||
getFeatureDir,
|
getFeatureDir,
|
||||||
getFeatureImagesDir,
|
getFeatureImagesDir,
|
||||||
ensureAutomakerDir,
|
ensureAutomakerDir,
|
||||||
} from "../lib/automaker-paths.js";
|
} from "@automaker/platform";
|
||||||
|
|
||||||
export interface Feature {
|
// Re-export Feature type for convenience
|
||||||
id: string;
|
export type { Feature };
|
||||||
category: string;
|
|
||||||
description: string;
|
|
||||||
steps?: string[];
|
|
||||||
passes?: boolean;
|
|
||||||
priority?: number;
|
|
||||||
status?: string;
|
|
||||||
dependencies?: string[];
|
|
||||||
spec?: string;
|
|
||||||
model?: string;
|
|
||||||
imagePaths?: Array<string | { path: string; [key: string]: unknown }>;
|
|
||||||
// Branch info - worktree path is derived at runtime from branchName
|
|
||||||
branchName?: string; // Name of the feature branch (undefined = use current worktree)
|
|
||||||
skipTests?: boolean;
|
|
||||||
thinkingLevel?: string;
|
|
||||||
planningMode?: 'skip' | 'lite' | 'spec' | 'full';
|
|
||||||
requirePlanApproval?: boolean;
|
|
||||||
planSpec?: {
|
|
||||||
status: 'pending' | 'generating' | 'generated' | 'approved' | 'rejected';
|
|
||||||
content?: string;
|
|
||||||
version: number;
|
|
||||||
generatedAt?: string;
|
|
||||||
approvedAt?: string;
|
|
||||||
reviewedByUser: boolean;
|
|
||||||
tasksCompleted?: number;
|
|
||||||
tasksTotal?: number;
|
|
||||||
};
|
|
||||||
error?: string;
|
|
||||||
summary?: string;
|
|
||||||
startedAt?: string;
|
|
||||||
[key: string]: unknown; // Keep catch-all for extensibility
|
|
||||||
}
|
|
||||||
|
|
||||||
export class FeatureLoader {
|
export class FeatureLoader {
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -38,6 +38,8 @@
|
|||||||
"dev:electron:wsl:gpu": "cross-env MESA_D3D12_DEFAULT_ADAPTER_NAME=NVIDIA vite"
|
"dev:electron:wsl:gpu": "cross-env MESA_D3D12_DEFAULT_ADAPTER_NAME=NVIDIA vite"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@automaker/dependency-resolver": "^1.0.0",
|
||||||
|
"@automaker/types": "^1.0.0",
|
||||||
"@codemirror/lang-xml": "^6.1.0",
|
"@codemirror/lang-xml": "^6.1.0",
|
||||||
"@codemirror/theme-one-dark": "^6.1.3",
|
"@codemirror/theme-one-dark": "^6.1.3",
|
||||||
"@dnd-kit/core": "^6.3.1",
|
"@dnd-kit/core": "^6.3.1",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { useAppStore, Feature } from "@/store/app-store";
|
|||||||
import { getElectronAPI } from "@/lib/electron";
|
import { getElectronAPI } from "@/lib/electron";
|
||||||
import type { AutoModeEvent } from "@/types/electron";
|
import type { AutoModeEvent } from "@/types/electron";
|
||||||
import { pathsEqual } from "@/lib/utils";
|
import { pathsEqual } from "@/lib/utils";
|
||||||
import { getBlockingDependencies } from "@/lib/dependency-resolver";
|
import { getBlockingDependencies } from "@automaker/dependency-resolver";
|
||||||
import { BoardBackgroundModal } from "@/components/dialogs/board-background-modal";
|
import { BoardBackgroundModal } from "@/components/dialogs/board-background-modal";
|
||||||
import { RefreshCw } from "lucide-react";
|
import { RefreshCw } from "lucide-react";
|
||||||
import { useAutoMode } from "@/hooks/use-auto-mode";
|
import { useAutoMode } from "@/hooks/use-auto-mode";
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ import {
|
|||||||
} from "lucide-react";
|
} from "lucide-react";
|
||||||
import { CountUpTimer } from "@/components/ui/count-up-timer";
|
import { CountUpTimer } from "@/components/ui/count-up-timer";
|
||||||
import { getElectronAPI } from "@/lib/electron";
|
import { getElectronAPI } from "@/lib/electron";
|
||||||
import { getBlockingDependencies } from "@/lib/dependency-resolver";
|
import { getBlockingDependencies } from "@automaker/dependency-resolver";
|
||||||
import {
|
import {
|
||||||
parseAgentContext,
|
parseAgentContext,
|
||||||
AgentTaskInfo,
|
AgentTaskInfo,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { getElectronAPI } from "@/lib/electron";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { useAutoMode } from "@/hooks/use-auto-mode";
|
import { useAutoMode } from "@/hooks/use-auto-mode";
|
||||||
import { truncateDescription } from "@/lib/utils";
|
import { truncateDescription } from "@/lib/utils";
|
||||||
import { getBlockingDependencies } from "@/lib/dependency-resolver";
|
import { getBlockingDependencies } from "@automaker/dependency-resolver";
|
||||||
|
|
||||||
interface UseBoardActionsProps {
|
interface UseBoardActionsProps {
|
||||||
currentProject: { path: string; id: string } | null;
|
currentProject: { path: string; id: string } | null;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { useMemo, useCallback } from "react";
|
import { useMemo, useCallback } from "react";
|
||||||
import { Feature, useAppStore } from "@/store/app-store";
|
import { Feature, useAppStore } from "@/store/app-store";
|
||||||
import { resolveDependencies, getBlockingDependencies } from "@/lib/dependency-resolver";
|
import { resolveDependencies, getBlockingDependencies } from "@automaker/dependency-resolver";
|
||||||
|
|
||||||
type ColumnId = Feature["status"];
|
type ColumnId = Feature["status"];
|
||||||
|
|
||||||
|
|||||||
@@ -1,221 +0,0 @@
|
|||||||
/**
|
|
||||||
* Dependency Resolution Utility
|
|
||||||
*
|
|
||||||
* Provides topological sorting and dependency analysis for features.
|
|
||||||
* Uses a modified Kahn's algorithm that respects both dependencies and priorities.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import type { Feature } from "@/store/app-store";
|
|
||||||
|
|
||||||
export interface DependencyResolutionResult {
|
|
||||||
orderedFeatures: Feature[]; // Features in dependency-aware order
|
|
||||||
circularDependencies: string[][]; // Groups of IDs forming cycles
|
|
||||||
missingDependencies: Map<string, string[]>; // featureId -> missing dep IDs
|
|
||||||
blockedFeatures: Map<string, string[]>; // featureId -> blocking dep IDs (incomplete dependencies)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resolves feature dependencies using topological sort with priority-aware ordering.
|
|
||||||
*
|
|
||||||
* Algorithm:
|
|
||||||
* 1. Build dependency graph and detect missing/blocked dependencies
|
|
||||||
* 2. Apply Kahn's algorithm for topological sort
|
|
||||||
* 3. Within same dependency level, sort by priority (1=high, 2=medium, 3=low)
|
|
||||||
* 4. Detect circular dependencies for features that can't be ordered
|
|
||||||
*
|
|
||||||
* @param features - Array of features to order
|
|
||||||
* @returns Resolution result with ordered features and dependency metadata
|
|
||||||
*/
|
|
||||||
export function resolveDependencies(features: Feature[]): DependencyResolutionResult {
|
|
||||||
const featureMap = new Map<string, Feature>(features.map(f => [f.id, f]));
|
|
||||||
const inDegree = new Map<string, number>();
|
|
||||||
const adjacencyList = new Map<string, string[]>(); // dependencyId -> [dependentIds]
|
|
||||||
const missingDependencies = new Map<string, string[]>();
|
|
||||||
const blockedFeatures = new Map<string, string[]>();
|
|
||||||
|
|
||||||
// Initialize graph structures
|
|
||||||
for (const feature of features) {
|
|
||||||
inDegree.set(feature.id, 0);
|
|
||||||
adjacencyList.set(feature.id, []);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build dependency graph and detect missing/blocked dependencies
|
|
||||||
for (const feature of features) {
|
|
||||||
const deps = feature.dependencies || [];
|
|
||||||
for (const depId of deps) {
|
|
||||||
if (!featureMap.has(depId)) {
|
|
||||||
// Missing dependency - track it
|
|
||||||
if (!missingDependencies.has(feature.id)) {
|
|
||||||
missingDependencies.set(feature.id, []);
|
|
||||||
}
|
|
||||||
missingDependencies.get(feature.id)!.push(depId);
|
|
||||||
} else {
|
|
||||||
// Valid dependency - add edge to graph
|
|
||||||
adjacencyList.get(depId)!.push(feature.id);
|
|
||||||
inDegree.set(feature.id, (inDegree.get(feature.id) || 0) + 1);
|
|
||||||
|
|
||||||
// Check if dependency is incomplete (blocking)
|
|
||||||
const depFeature = featureMap.get(depId)!;
|
|
||||||
if (depFeature.status !== 'completed' && depFeature.status !== 'verified') {
|
|
||||||
if (!blockedFeatures.has(feature.id)) {
|
|
||||||
blockedFeatures.set(feature.id, []);
|
|
||||||
}
|
|
||||||
blockedFeatures.get(feature.id)!.push(depId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kahn's algorithm with priority-aware selection
|
|
||||||
const queue: Feature[] = [];
|
|
||||||
const orderedFeatures: Feature[] = [];
|
|
||||||
|
|
||||||
// Helper to sort features by priority (lower number = higher priority)
|
|
||||||
const sortByPriority = (a: Feature, b: Feature) =>
|
|
||||||
(a.priority ?? 2) - (b.priority ?? 2);
|
|
||||||
|
|
||||||
// Start with features that have no dependencies (in-degree 0)
|
|
||||||
for (const [id, degree] of inDegree) {
|
|
||||||
if (degree === 0) {
|
|
||||||
queue.push(featureMap.get(id)!);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort initial queue by priority
|
|
||||||
queue.sort(sortByPriority);
|
|
||||||
|
|
||||||
// Process features in topological order
|
|
||||||
while (queue.length > 0) {
|
|
||||||
// Take highest priority feature from queue
|
|
||||||
const current = queue.shift()!;
|
|
||||||
orderedFeatures.push(current);
|
|
||||||
|
|
||||||
// Process features that depend on this one
|
|
||||||
for (const dependentId of adjacencyList.get(current.id) || []) {
|
|
||||||
const currentDegree = inDegree.get(dependentId);
|
|
||||||
if (currentDegree === undefined) {
|
|
||||||
throw new Error(`In-degree not initialized for feature ${dependentId}`);
|
|
||||||
}
|
|
||||||
const newDegree = currentDegree - 1;
|
|
||||||
inDegree.set(dependentId, newDegree);
|
|
||||||
|
|
||||||
if (newDegree === 0) {
|
|
||||||
queue.push(featureMap.get(dependentId)!);
|
|
||||||
// Re-sort queue to maintain priority order
|
|
||||||
queue.sort(sortByPriority);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect circular dependencies (features not in output = part of cycle)
|
|
||||||
const circularDependencies: string[][] = [];
|
|
||||||
const processedIds = new Set(orderedFeatures.map(f => f.id));
|
|
||||||
|
|
||||||
if (orderedFeatures.length < features.length) {
|
|
||||||
// Find cycles using DFS
|
|
||||||
const remaining = features.filter(f => !processedIds.has(f.id));
|
|
||||||
const cycles = detectCycles(remaining, featureMap);
|
|
||||||
circularDependencies.push(...cycles);
|
|
||||||
|
|
||||||
// Add remaining features at end (part of cycles)
|
|
||||||
orderedFeatures.push(...remaining);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
orderedFeatures,
|
|
||||||
circularDependencies,
|
|
||||||
missingDependencies,
|
|
||||||
blockedFeatures
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Detects circular dependencies using depth-first search
|
|
||||||
*
|
|
||||||
* @param features - Features that couldn't be topologically sorted (potential cycles)
|
|
||||||
* @param featureMap - Map of all features by ID
|
|
||||||
* @returns Array of cycles, where each cycle is an array of feature IDs
|
|
||||||
*/
|
|
||||||
function detectCycles(
|
|
||||||
features: Feature[],
|
|
||||||
featureMap: Map<string, Feature>
|
|
||||||
): string[][] {
|
|
||||||
const cycles: string[][] = [];
|
|
||||||
const visited = new Set<string>();
|
|
||||||
const recursionStack = new Set<string>();
|
|
||||||
const currentPath: string[] = [];
|
|
||||||
|
|
||||||
function dfs(featureId: string): boolean {
|
|
||||||
visited.add(featureId);
|
|
||||||
recursionStack.add(featureId);
|
|
||||||
currentPath.push(featureId);
|
|
||||||
|
|
||||||
const feature = featureMap.get(featureId);
|
|
||||||
if (feature) {
|
|
||||||
for (const depId of feature.dependencies || []) {
|
|
||||||
if (!visited.has(depId)) {
|
|
||||||
if (dfs(depId)) return true;
|
|
||||||
} else if (recursionStack.has(depId)) {
|
|
||||||
// Found cycle - extract it
|
|
||||||
const cycleStart = currentPath.indexOf(depId);
|
|
||||||
cycles.push(currentPath.slice(cycleStart));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
currentPath.pop();
|
|
||||||
recursionStack.delete(featureId);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const feature of features) {
|
|
||||||
if (!visited.has(feature.id)) {
|
|
||||||
dfs(feature.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return cycles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a feature's dependencies are satisfied (all complete or verified)
|
|
||||||
*
|
|
||||||
* @param feature - Feature to check
|
|
||||||
* @param allFeatures - All features in the project
|
|
||||||
* @returns true if all dependencies are satisfied, false otherwise
|
|
||||||
*/
|
|
||||||
export function areDependenciesSatisfied(
|
|
||||||
feature: Feature,
|
|
||||||
allFeatures: Feature[]
|
|
||||||
): boolean {
|
|
||||||
if (!feature.dependencies || feature.dependencies.length === 0) {
|
|
||||||
return true; // No dependencies = always ready
|
|
||||||
}
|
|
||||||
|
|
||||||
return feature.dependencies.every(depId => {
|
|
||||||
const dep = allFeatures.find(f => f.id === depId);
|
|
||||||
return dep && (dep.status === 'completed' || dep.status === 'verified');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the blocking dependencies for a feature (dependencies that are incomplete)
|
|
||||||
*
|
|
||||||
* @param feature - Feature to check
|
|
||||||
* @param allFeatures - All features in the project
|
|
||||||
* @returns Array of feature IDs that are blocking this feature
|
|
||||||
*/
|
|
||||||
export function getBlockingDependencies(
|
|
||||||
feature: Feature,
|
|
||||||
allFeatures: Feature[]
|
|
||||||
): string[] {
|
|
||||||
if (!feature.dependencies || feature.dependencies.length === 0) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return feature.dependencies.filter(depId => {
|
|
||||||
const dep = allFeatures.find(f => f.id === depId);
|
|
||||||
return dep && dep.status !== 'completed' && dep.status !== 'verified';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
"name": "@automaker/dependency-resolver",
|
"name": "@automaker/dependency-resolver",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Feature dependency resolution for AutoMaker",
|
"description": "Feature dependency resolution for AutoMaker",
|
||||||
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "dist/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ES2020",
|
"target": "ES2020",
|
||||||
"module": "commonjs",
|
"module": "ESNext",
|
||||||
"lib": ["ES2020"],
|
"lib": ["ES2020"],
|
||||||
"types": ["node"],
|
"types": ["node"],
|
||||||
"declaration": true,
|
"declaration": true,
|
||||||
|
|||||||
8
package-lock.json
generated
8
package-lock.json
generated
@@ -22,6 +22,12 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@anthropic-ai/claude-agent-sdk": "^0.1.72",
|
"@anthropic-ai/claude-agent-sdk": "^0.1.72",
|
||||||
|
"@automaker/dependency-resolver": "^1.0.0",
|
||||||
|
"@automaker/git-utils": "^1.0.0",
|
||||||
|
"@automaker/model-resolver": "^1.0.0",
|
||||||
|
"@automaker/platform": "^1.0.0",
|
||||||
|
"@automaker/types": "^1.0.0",
|
||||||
|
"@automaker/utils": "^1.0.0",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"dotenv": "^17.2.3",
|
"dotenv": "^17.2.3",
|
||||||
"express": "^5.2.1",
|
"express": "^5.2.1",
|
||||||
@@ -1568,6 +1574,8 @@
|
|||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "Unlicense",
|
"license": "Unlicense",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@automaker/dependency-resolver": "^1.0.0",
|
||||||
|
"@automaker/types": "^1.0.0",
|
||||||
"@codemirror/lang-xml": "^6.1.0",
|
"@codemirror/lang-xml": "^6.1.0",
|
||||||
"@codemirror/theme-one-dark": "^6.1.3",
|
"@codemirror/theme-one-dark": "^6.1.3",
|
||||||
"@dnd-kit/core": "^6.3.1",
|
"@dnd-kit/core": "^6.3.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user