mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-02 20:43:36 +00:00
Merge branch 'AutoMaker-Org:main' into feat/claude-usage-clean
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* Common utilities for agent routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getErrorMessage as getErrorMessageShared,
|
||||
createLogError,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import { AgentService } from "../../../services/agent-service.js";
|
||||
import { createLogger } from "../../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
const logger = createLogger("Agent");
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import { AgentService } from "../../../services/agent-service.js";
|
||||
import { createLogger } from "../../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
const logger = createLogger("Agent");
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities and state management for spec regeneration
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
|
||||
const logger = createLogger("SpecRegeneration");
|
||||
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
import { query } from "@anthropic-ai/claude-agent-sdk";
|
||||
import fs from "fs/promises";
|
||||
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 { logAuthStatus } from "./common.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");
|
||||
|
||||
|
||||
@@ -12,11 +12,11 @@ import {
|
||||
getStructuredSpecPromptInstruction,
|
||||
type SpecOutput,
|
||||
} 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 { logAuthStatus } from "./common.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");
|
||||
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
import path from "path";
|
||||
import fs from "fs/promises";
|
||||
import type { EventEmitter } from "../../lib/events.js";
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { getFeaturesDir } from "../../lib/automaker-paths.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import { getFeaturesDir } from "@automaker/platform";
|
||||
|
||||
const logger = createLogger("SpecRegeneration");
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import type { EventEmitter } from "../../../lib/events.js";
|
||||
import { createLogger } from "../../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getSpecRegenerationStatus,
|
||||
setRunningState,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import type { EventEmitter } from "../../../lib/events.js";
|
||||
import { createLogger } from "../../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getSpecRegenerationStatus,
|
||||
setRunningState,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import type { EventEmitter } from "../../../lib/events.js";
|
||||
import { createLogger } from "../../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getSpecRegenerationStatus,
|
||||
setRunningState,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities for auto-mode routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getErrorMessage as getErrorMessageShared,
|
||||
createLogError,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
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";
|
||||
|
||||
const logger = createLogger("AutoMode");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
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";
|
||||
|
||||
const logger = createLogger("AutoMode");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
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";
|
||||
|
||||
const logger = createLogger("AutoMode");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
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";
|
||||
|
||||
const logger = createLogger("AutoMode");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
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";
|
||||
|
||||
const logger = createLogger("AutoMode");
|
||||
|
||||
@@ -2,368 +2,24 @@
|
||||
* Common utilities shared across all route modules
|
||||
*/
|
||||
|
||||
import { createLogger } from "../lib/logger.js";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import { exec } from "child_process";
|
||||
import { promisify } from "util";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
|
||||
// Re-export git utilities from shared package
|
||||
export {
|
||||
BINARY_EXTENSIONS,
|
||||
GIT_STATUS_MAP,
|
||||
type FileStatus,
|
||||
isGitRepo,
|
||||
parseGitStatus,
|
||||
generateSyntheticDiffForNewFile,
|
||||
appendUntrackedFileDiffs,
|
||||
listAllFilesInDirectory,
|
||||
generateDiffsForNonGitDirectory,
|
||||
getGitRepositoryDiffs,
|
||||
} from "@automaker/git-utils";
|
||||
|
||||
type Logger = ReturnType<typeof createLogger>;
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
const logger = createLogger("Common");
|
||||
|
||||
// Max file size for generating synthetic diffs (1MB)
|
||||
const MAX_SYNTHETIC_DIFF_SIZE = 1024 * 1024;
|
||||
|
||||
// Binary file extensions to skip
|
||||
const BINARY_EXTENSIONS = new Set([
|
||||
".png", ".jpg", ".jpeg", ".gif", ".bmp", ".ico", ".webp", ".svg",
|
||||
".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx",
|
||||
".zip", ".tar", ".gz", ".rar", ".7z",
|
||||
".exe", ".dll", ".so", ".dylib",
|
||||
".mp3", ".mp4", ".wav", ".avi", ".mov", ".mkv",
|
||||
".ttf", ".otf", ".woff", ".woff2", ".eot",
|
||||
".db", ".sqlite", ".sqlite3",
|
||||
".pyc", ".pyo", ".class", ".o", ".obj",
|
||||
]);
|
||||
|
||||
// Status map for git status codes
|
||||
// Git porcelain format uses XY where X=staging area, Y=working tree
|
||||
const GIT_STATUS_MAP: Record<string, string> = {
|
||||
M: "Modified",
|
||||
A: "Added",
|
||||
D: "Deleted",
|
||||
R: "Renamed",
|
||||
C: "Copied",
|
||||
U: "Updated",
|
||||
"?": "Untracked",
|
||||
"!": "Ignored",
|
||||
" ": "Unmodified",
|
||||
};
|
||||
|
||||
/**
|
||||
* Get a readable status text from git status codes
|
||||
* Handles both single character and XY format status codes
|
||||
*/
|
||||
function getStatusText(indexStatus: string, workTreeStatus: string): string {
|
||||
// Untracked files
|
||||
if (indexStatus === "?" && workTreeStatus === "?") {
|
||||
return "Untracked";
|
||||
}
|
||||
|
||||
// Ignored files
|
||||
if (indexStatus === "!" && workTreeStatus === "!") {
|
||||
return "Ignored";
|
||||
}
|
||||
|
||||
// Prioritize staging area status, then working tree
|
||||
const primaryStatus = indexStatus !== " " && indexStatus !== "?" ? indexStatus : workTreeStatus;
|
||||
|
||||
// Handle combined statuses
|
||||
if (indexStatus !== " " && indexStatus !== "?" && workTreeStatus !== " " && workTreeStatus !== "?") {
|
||||
// Both staging and working tree have changes
|
||||
const indexText = GIT_STATUS_MAP[indexStatus] || "Changed";
|
||||
const workText = GIT_STATUS_MAP[workTreeStatus] || "Changed";
|
||||
if (indexText === workText) {
|
||||
return indexText;
|
||||
}
|
||||
return `${indexText} (staged), ${workText} (unstaged)`;
|
||||
}
|
||||
|
||||
return GIT_STATUS_MAP[primaryStatus] || "Changed";
|
||||
}
|
||||
|
||||
/**
|
||||
* File status interface for git status results
|
||||
*/
|
||||
export interface FileStatus {
|
||||
status: string;
|
||||
path: string;
|
||||
statusText: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is likely binary based on extension
|
||||
*/
|
||||
function isBinaryFile(filePath: string): boolean {
|
||||
const ext = path.extname(filePath).toLowerCase();
|
||||
return BINARY_EXTENSIONS.has(ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a path is a git repository
|
||||
*/
|
||||
export async function isGitRepo(repoPath: string): Promise<boolean> {
|
||||
try {
|
||||
await execAsync("git rev-parse --is-inside-work-tree", { cwd: repoPath });
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse the output of `git status --porcelain` into FileStatus array
|
||||
* Git porcelain format: XY PATH where X=staging area status, Y=working tree status
|
||||
* For renamed files: XY ORIG_PATH -> NEW_PATH
|
||||
*/
|
||||
export function parseGitStatus(statusOutput: string): FileStatus[] {
|
||||
return statusOutput
|
||||
.split("\n")
|
||||
.filter(Boolean)
|
||||
.map((line) => {
|
||||
// Git porcelain format uses two status characters: XY
|
||||
// X = status in staging area (index)
|
||||
// Y = status in working tree
|
||||
const indexStatus = line[0] || " ";
|
||||
const workTreeStatus = line[1] || " ";
|
||||
|
||||
// File path starts at position 3 (after "XY ")
|
||||
let filePath = line.slice(3);
|
||||
|
||||
// Handle renamed files (format: "R old_path -> new_path")
|
||||
if (indexStatus === "R" || workTreeStatus === "R") {
|
||||
const arrowIndex = filePath.indexOf(" -> ");
|
||||
if (arrowIndex !== -1) {
|
||||
filePath = filePath.slice(arrowIndex + 4); // Use new path
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the primary status character for backwards compatibility
|
||||
// Prioritize staging area status, then working tree
|
||||
let primaryStatus: string;
|
||||
if (indexStatus === "?" && workTreeStatus === "?") {
|
||||
primaryStatus = "?"; // Untracked
|
||||
} else if (indexStatus !== " " && indexStatus !== "?") {
|
||||
primaryStatus = indexStatus; // Staged change
|
||||
} else {
|
||||
primaryStatus = workTreeStatus; // Working tree change
|
||||
}
|
||||
|
||||
return {
|
||||
status: primaryStatus,
|
||||
path: filePath,
|
||||
statusText: getStatusText(indexStatus, workTreeStatus),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a synthetic unified diff for an untracked (new) file
|
||||
* This is needed because `git diff HEAD` doesn't include untracked files
|
||||
*/
|
||||
export async function generateSyntheticDiffForNewFile(
|
||||
basePath: string,
|
||||
relativePath: string
|
||||
): Promise<string> {
|
||||
const fullPath = path.join(basePath, relativePath);
|
||||
|
||||
try {
|
||||
// Check if it's a binary file
|
||||
if (isBinaryFile(relativePath)) {
|
||||
return `diff --git a/${relativePath} b/${relativePath}
|
||||
new file mode 100644
|
||||
index 0000000..0000000
|
||||
Binary file ${relativePath} added
|
||||
`;
|
||||
}
|
||||
|
||||
// Get file stats to check size
|
||||
const stats = await fs.stat(fullPath);
|
||||
if (stats.size > MAX_SYNTHETIC_DIFF_SIZE) {
|
||||
const sizeKB = Math.round(stats.size / 1024);
|
||||
return `diff --git a/${relativePath} b/${relativePath}
|
||||
new file mode 100644
|
||||
index 0000000..0000000
|
||||
--- /dev/null
|
||||
+++ b/${relativePath}
|
||||
@@ -0,0 +1 @@
|
||||
+[File too large to display: ${sizeKB}KB]
|
||||
`;
|
||||
}
|
||||
|
||||
// Read file content
|
||||
const content = await fs.readFile(fullPath, "utf-8");
|
||||
const hasTrailingNewline = content.endsWith("\n");
|
||||
const lines = content.split("\n");
|
||||
|
||||
// Remove trailing empty line if the file ends with newline
|
||||
if (lines.length > 0 && lines.at(-1) === "") {
|
||||
lines.pop();
|
||||
}
|
||||
|
||||
// Generate diff format
|
||||
const lineCount = lines.length;
|
||||
const addedLines = lines.map(line => `+${line}`).join("\n");
|
||||
|
||||
let diff = `diff --git a/${relativePath} b/${relativePath}
|
||||
new file mode 100644
|
||||
index 0000000..0000000
|
||||
--- /dev/null
|
||||
+++ b/${relativePath}
|
||||
@@ -0,0 +1,${lineCount} @@
|
||||
${addedLines}`;
|
||||
|
||||
// Add "No newline at end of file" indicator if needed
|
||||
if (!hasTrailingNewline && content.length > 0) {
|
||||
diff += "\n\\ No newline at end of file";
|
||||
}
|
||||
|
||||
return diff + "\n";
|
||||
} catch (error) {
|
||||
// Log the error for debugging
|
||||
logger.error(`Failed to generate synthetic diff for ${fullPath}:`, error);
|
||||
// Return a placeholder diff
|
||||
return `diff --git a/${relativePath} b/${relativePath}
|
||||
new file mode 100644
|
||||
index 0000000..0000000
|
||||
--- /dev/null
|
||||
+++ b/${relativePath}
|
||||
@@ -0,0 +1 @@
|
||||
+[Unable to read file content]
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate synthetic diffs for all untracked files and combine with existing diff
|
||||
*/
|
||||
export async function appendUntrackedFileDiffs(
|
||||
basePath: string,
|
||||
existingDiff: string,
|
||||
files: Array<{ status: string; path: string }>
|
||||
): Promise<string> {
|
||||
// Find untracked files (status "?")
|
||||
const untrackedFiles = files.filter(f => f.status === "?");
|
||||
|
||||
if (untrackedFiles.length === 0) {
|
||||
return existingDiff;
|
||||
}
|
||||
|
||||
// Generate synthetic diffs for each untracked file
|
||||
const syntheticDiffs = await Promise.all(
|
||||
untrackedFiles.map(f => generateSyntheticDiffForNewFile(basePath, f.path))
|
||||
);
|
||||
|
||||
// Combine existing diff with synthetic diffs
|
||||
const combinedDiff = existingDiff + syntheticDiffs.join("");
|
||||
|
||||
return combinedDiff;
|
||||
}
|
||||
|
||||
/**
|
||||
* List all files in a directory recursively (for non-git repositories)
|
||||
* Excludes hidden files/folders and common build artifacts
|
||||
*/
|
||||
export async function listAllFilesInDirectory(
|
||||
basePath: string,
|
||||
relativePath: string = ""
|
||||
): Promise<string[]> {
|
||||
const files: string[] = [];
|
||||
const fullPath = path.join(basePath, relativePath);
|
||||
|
||||
// Directories to skip
|
||||
const skipDirs = new Set([
|
||||
"node_modules", ".git", ".automaker", "dist", "build",
|
||||
".next", ".nuxt", "__pycache__", ".cache", "coverage"
|
||||
]);
|
||||
|
||||
try {
|
||||
const entries = await fs.readdir(fullPath, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
// Skip hidden files/folders (except we want to allow some)
|
||||
if (entry.name.startsWith(".") && entry.name !== ".env") {
|
||||
continue;
|
||||
}
|
||||
|
||||
const entryRelPath = relativePath ? `${relativePath}/${entry.name}` : entry.name;
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
if (!skipDirs.has(entry.name)) {
|
||||
const subFiles = await listAllFilesInDirectory(basePath, entryRelPath);
|
||||
files.push(...subFiles);
|
||||
}
|
||||
} else if (entry.isFile()) {
|
||||
files.push(entryRelPath);
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
// Log the error to help diagnose file system issues
|
||||
logger.error(`Error reading directory ${fullPath}:`, error);
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate diffs for all files in a non-git directory
|
||||
* Treats all files as "new" files
|
||||
*/
|
||||
export async function generateDiffsForNonGitDirectory(
|
||||
basePath: string
|
||||
): Promise<{ diff: string; files: FileStatus[] }> {
|
||||
const allFiles = await listAllFilesInDirectory(basePath);
|
||||
|
||||
const files: FileStatus[] = allFiles.map(filePath => ({
|
||||
status: "?",
|
||||
path: filePath,
|
||||
statusText: "New",
|
||||
}));
|
||||
|
||||
// Generate synthetic diffs for all files
|
||||
const syntheticDiffs = await Promise.all(
|
||||
files.map(f => generateSyntheticDiffForNewFile(basePath, f.path))
|
||||
);
|
||||
|
||||
return {
|
||||
diff: syntheticDiffs.join(""),
|
||||
files,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get git repository diffs for a given path
|
||||
* Handles both git repos and non-git directories
|
||||
*/
|
||||
export async function getGitRepositoryDiffs(
|
||||
repoPath: string
|
||||
): Promise<{ diff: string; files: FileStatus[]; hasChanges: boolean }> {
|
||||
// Check if it's a git repository
|
||||
const isRepo = await isGitRepo(repoPath);
|
||||
|
||||
if (!isRepo) {
|
||||
// Not a git repo - list all files and treat them as new
|
||||
const result = await generateDiffsForNonGitDirectory(repoPath);
|
||||
return {
|
||||
diff: result.diff,
|
||||
files: result.files,
|
||||
hasChanges: result.files.length > 0,
|
||||
};
|
||||
}
|
||||
|
||||
// Get git diff and status
|
||||
const { stdout: diff } = await execAsync("git diff HEAD", {
|
||||
cwd: repoPath,
|
||||
maxBuffer: 10 * 1024 * 1024,
|
||||
});
|
||||
const { stdout: status } = await execAsync("git status --porcelain", {
|
||||
cwd: repoPath,
|
||||
});
|
||||
|
||||
const files = parseGitStatus(status);
|
||||
|
||||
// Generate synthetic diffs for untracked (new) files
|
||||
const combinedDiff = await appendUntrackedFileDiffs(repoPath, diff, files);
|
||||
|
||||
return {
|
||||
diff: combinedDiff,
|
||||
files,
|
||||
hasChanges: files.length > 0,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get error message from error object
|
||||
*/
|
||||
|
||||
@@ -7,14 +7,15 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
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 {
|
||||
getSystemPrompt,
|
||||
buildUserPrompt,
|
||||
isValidEnhancementMode,
|
||||
type EnhancementMode,
|
||||
} from "../../../lib/enhancement-prompts.js";
|
||||
import { resolveModelString, CLAUDE_MODEL_MAP } from "../../../lib/model-resolver.js";
|
||||
|
||||
const logger = createLogger("EnhancePrompt");
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities for features routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getErrorMessage as getErrorMessageShared,
|
||||
createLogError,
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
*/
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import {
|
||||
FeatureLoader,
|
||||
type Feature,
|
||||
} from "../../../services/feature-loader.js";
|
||||
import { FeatureLoader } from "../../../services/feature-loader.js";
|
||||
import type { Feature } from "@automaker/types";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
|
||||
export function createCreateHandler(featureLoader: FeatureLoader) {
|
||||
@@ -18,12 +16,10 @@ export function createCreateHandler(featureLoader: FeatureLoader) {
|
||||
};
|
||||
|
||||
if (!projectPath || !feature) {
|
||||
res
|
||||
.status(400)
|
||||
.json({
|
||||
success: false,
|
||||
error: "projectPath and feature are required",
|
||||
});
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
error: "projectPath and feature are required",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import { query } from "@anthropic-ai/claude-agent-sdk";
|
||||
import { createLogger } from "../../../lib/logger.js";
|
||||
import { CLAUDE_MODEL_MAP } from "../../../lib/model-resolver.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import { CLAUDE_MODEL_MAP } from "@automaker/model-resolver";
|
||||
|
||||
const logger = createLogger("GenerateTitle");
|
||||
|
||||
|
||||
@@ -3,10 +3,8 @@
|
||||
*/
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import {
|
||||
FeatureLoader,
|
||||
type Feature,
|
||||
} from "../../../services/feature-loader.js";
|
||||
import { FeatureLoader } from "../../../services/feature-loader.js";
|
||||
import type { Feature } from "@automaker/types";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
|
||||
export function createUpdateHandler(featureLoader: FeatureLoader) {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities for fs routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getErrorMessage as getErrorMessageShared,
|
||||
createLogError,
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
getAllowedRootDirectory,
|
||||
isPathAllowed,
|
||||
PathNotAllowedError,
|
||||
} from "../../../lib/security.js";
|
||||
} from "@automaker/platform";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
|
||||
export function createBrowseHandler() {
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { Request, Response } from "express";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
import { getBoardDir } from "../../../lib/automaker-paths.js";
|
||||
import { getBoardDir } from "@automaker/platform";
|
||||
|
||||
export function createDeleteBoardBackgroundHandler() {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import fs from "fs/promises";
|
||||
import { validatePath, PathNotAllowedError } from "../../../lib/security.js";
|
||||
import { validatePath, PathNotAllowedError } from "@automaker/platform";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
|
||||
export function createDeleteHandler() {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import type { Request, Response } from "express";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import { isPathAllowed, PathNotAllowedError } from "../../../lib/security.js";
|
||||
import { isPathAllowed, PathNotAllowedError } from "@automaker/platform";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
|
||||
export function createExistsHandler() {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import type { Request, Response } from "express";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import { isPathAllowed, PathNotAllowedError } from "../../../lib/security.js";
|
||||
import { isPathAllowed, PathNotAllowedError } from "@automaker/platform";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
|
||||
export function createMkdirHandler() {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import fs from "fs/promises";
|
||||
import { validatePath, PathNotAllowedError } from "../../../lib/security.js";
|
||||
import { validatePath, PathNotAllowedError } from "@automaker/platform";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
|
||||
// Optional files that are expected to not exist in new projects
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import fs from "fs/promises";
|
||||
import { validatePath, PathNotAllowedError } from "../../../lib/security.js";
|
||||
import { validatePath, PathNotAllowedError } from "@automaker/platform";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
|
||||
export function createReaddirHandler() {
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { Request, Response } from "express";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
import { getBoardDir } from "../../../lib/automaker-paths.js";
|
||||
import { getBoardDir } from "@automaker/platform";
|
||||
|
||||
export function createSaveBoardBackgroundHandler() {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { Request, Response } from "express";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
import { getImagesDir } from "../../../lib/automaker-paths.js";
|
||||
import { getImagesDir } from "@automaker/platform";
|
||||
|
||||
export function createSaveImageHandler() {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import fs from "fs/promises";
|
||||
import { validatePath, PathNotAllowedError } from "../../../lib/security.js";
|
||||
import { validatePath, PathNotAllowedError } from "@automaker/platform";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
|
||||
export function createStatHandler() {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import type { Request, Response } from "express";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import { isPathAllowed } from "../../../lib/security.js";
|
||||
import { isPathAllowed } from "@automaker/platform";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
|
||||
export function createValidatePathHandler() {
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
import type { Request, Response } from "express";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import { validatePath, PathNotAllowedError } from "../../../lib/security.js";
|
||||
import { validatePath, PathNotAllowedError } from "@automaker/platform";
|
||||
import { mkdirSafe } from "@automaker/utils";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
import { mkdirSafe } from "../../../lib/fs-utils.js";
|
||||
|
||||
export function createWriteHandler() {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities for git routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getErrorMessage as getErrorMessageShared,
|
||||
createLogError,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities for health routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getErrorMessage as getErrorMessageShared,
|
||||
createLogError,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities for models routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getErrorMessage as getErrorMessageShared,
|
||||
createLogError,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities for running-agents routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getErrorMessage as getErrorMessageShared,
|
||||
createLogError,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities for sessions routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getErrorMessage as getErrorMessageShared,
|
||||
createLogError,
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Re-exports error handling helpers from the parent routes module.
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getErrorMessage as getErrorMessageShared,
|
||||
createLogError,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities and state for setup routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import path from "path";
|
||||
import fs from "fs/promises";
|
||||
import {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
*/
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import { createLogger } from "../../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import path from "path";
|
||||
import fs from "fs/promises";
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
getErrorMessage,
|
||||
logError,
|
||||
} from "../common.js";
|
||||
import { createLogger } from "../../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
|
||||
const logger = createLogger("Setup");
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import { query } from "@anthropic-ai/claude-agent-sdk";
|
||||
import { createLogger } from "../../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import { getApiKey } from "../common.js";
|
||||
|
||||
const logger = createLogger("Setup");
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities and state for suggestions routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getErrorMessage as getErrorMessageShared,
|
||||
createLogError,
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import { query } from "@anthropic-ai/claude-agent-sdk";
|
||||
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";
|
||||
|
||||
const logger = createLogger("Suggestions");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import type { EventEmitter } from "../../../lib/events.js";
|
||||
import { createLogger } from "../../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getSuggestionsStatus,
|
||||
setRunningState,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities for templates routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getErrorMessage as getErrorMessageShared,
|
||||
createLogError,
|
||||
|
||||
@@ -6,7 +6,7 @@ import type { Request, Response } from "express";
|
||||
import { spawn } from "child_process";
|
||||
import path from "path";
|
||||
import fs from "fs/promises";
|
||||
import { isPathAllowed, PathNotAllowedError } from "../../../lib/security.js";
|
||||
import { isPathAllowed } from "@automaker/platform";
|
||||
import { logger, getErrorMessage, logError } from "../common.js";
|
||||
|
||||
export function createCloneHandler() {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* 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 { getTerminalService } from "../../services/terminal-service.js";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import type { Request, Response } from "express";
|
||||
import { getTerminalService } from "../../../services/terminal-service.js";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
import { createLogger } from "../../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
|
||||
const logger = createLogger("Terminal");
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities for workspace routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import {
|
||||
getErrorMessage as getErrorMessageShared,
|
||||
createLogError,
|
||||
|
||||
@@ -8,7 +8,7 @@ import path from "path";
|
||||
import {
|
||||
getAllowedRootDirectory,
|
||||
getDataDirectory,
|
||||
} from "../../../lib/security.js";
|
||||
} from "@automaker/platform";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
|
||||
export function createConfigHandler() {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import type { Request, Response } from "express";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import { getAllowedRootDirectory } from "../../../lib/security.js";
|
||||
import { getAllowedRootDirectory } from "@automaker/platform";
|
||||
import { getErrorMessage, logError } from "../common.js";
|
||||
|
||||
export function createDirectoriesHandler() {
|
||||
@@ -35,7 +35,9 @@ export function createDirectoriesHandler() {
|
||||
}
|
||||
|
||||
// Read directory contents
|
||||
const entries = await fs.readdir(resolvedWorkspaceDir, { withFileTypes: true });
|
||||
const entries = await fs.readdir(resolvedWorkspaceDir, {
|
||||
withFileTypes: true,
|
||||
});
|
||||
|
||||
// Filter to directories only and map to result format
|
||||
const directories = entries
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Common utilities for worktree routes
|
||||
*/
|
||||
|
||||
import { createLogger } from "../../lib/logger.js";
|
||||
import { createLogger } from "@automaker/utils";
|
||||
import { exec } from "child_process";
|
||||
import { promisify } from "util";
|
||||
import path from "path";
|
||||
|
||||
@@ -10,7 +10,7 @@ import path from "path";
|
||||
import {
|
||||
getBranchTrackingPath,
|
||||
ensureAutomakerDir,
|
||||
} from "../../../lib/automaker-paths.js";
|
||||
} from "@automaker/platform";
|
||||
|
||||
export interface TrackedBranch {
|
||||
name: string;
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
import type { Request, Response } from "express";
|
||||
import { exec } from "child_process";
|
||||
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);
|
||||
|
||||
|
||||
@@ -9,7 +9,8 @@ import type { Request, Response } from "express";
|
||||
import { exec } from "child_process";
|
||||
import { promisify } from "util";
|
||||
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";
|
||||
import { readAllWorktreeMetadata, type WorktreePRInfo } from "../../../lib/worktree-metadata.js";
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
*/
|
||||
|
||||
import type { Request, Response } from "express";
|
||||
import { getAutomakerDir } from "../../../lib/automaker-paths.js";
|
||||
import { getAutomakerDir } from "@automaker/platform";
|
||||
|
||||
export function createMigrateHandler() {
|
||||
return async (req: Request, res: Response): Promise<void> => {
|
||||
|
||||
Reference in New Issue
Block a user