mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-02-03 21:03:08 +00:00
further gemini reviews and fixes
This commit is contained in:
@@ -391,8 +391,7 @@ class AutoModeService {
|
|||||||
featureId,
|
featureId,
|
||||||
"waiting_approval",
|
"waiting_approval",
|
||||||
projectPath,
|
projectPath,
|
||||||
null, // no summary
|
{ error: error.message }
|
||||||
error.message // pass error message
|
|
||||||
);
|
);
|
||||||
} catch (statusError) {
|
} catch (statusError) {
|
||||||
console.error("[AutoMode] Failed to update feature status after error:", statusError);
|
console.error("[AutoMode] Failed to update feature status after error:", statusError);
|
||||||
@@ -495,8 +494,7 @@ class AutoModeService {
|
|||||||
featureId,
|
featureId,
|
||||||
"waiting_approval",
|
"waiting_approval",
|
||||||
projectPath,
|
projectPath,
|
||||||
null, // no summary
|
{ error: error.message }
|
||||||
error.message // pass error message
|
|
||||||
);
|
);
|
||||||
} catch (statusError) {
|
} catch (statusError) {
|
||||||
console.error("[AutoMode] Failed to update feature status after error:", statusError);
|
console.error("[AutoMode] Failed to update feature status after error:", statusError);
|
||||||
@@ -662,8 +660,7 @@ class AutoModeService {
|
|||||||
featureId,
|
featureId,
|
||||||
"waiting_approval",
|
"waiting_approval",
|
||||||
projectPath,
|
projectPath,
|
||||||
null, // no summary
|
{ error: error.message }
|
||||||
error.message // pass error message
|
|
||||||
);
|
);
|
||||||
} catch (statusError) {
|
} catch (statusError) {
|
||||||
console.error("[AutoMode] Failed to update feature status after error:", statusError);
|
console.error("[AutoMode] Failed to update feature status after error:", statusError);
|
||||||
@@ -859,8 +856,7 @@ class AutoModeService {
|
|||||||
featureId,
|
featureId,
|
||||||
"waiting_approval",
|
"waiting_approval",
|
||||||
projectPath,
|
projectPath,
|
||||||
null, // no summary
|
{ error: error.message }
|
||||||
error.message // pass error message
|
|
||||||
);
|
);
|
||||||
} catch (statusError) {
|
} catch (statusError) {
|
||||||
console.error("[AutoMode] Failed to update feature status after error:", statusError);
|
console.error("[AutoMode] Failed to update feature status after error:", statusError);
|
||||||
@@ -1102,8 +1098,7 @@ class AutoModeService {
|
|||||||
featureId,
|
featureId,
|
||||||
"waiting_approval",
|
"waiting_approval",
|
||||||
projectPath,
|
projectPath,
|
||||||
null, // no summary
|
{ error: error.message }
|
||||||
error.message // pass error message
|
|
||||||
);
|
);
|
||||||
} catch (statusError) {
|
} catch (statusError) {
|
||||||
console.error("[AutoMode] Failed to update feature status after error:", statusError);
|
console.error("[AutoMode] Failed to update feature status after error:", statusError);
|
||||||
|
|||||||
@@ -898,7 +898,7 @@ ipcMain.handle(
|
|||||||
featureId,
|
featureId,
|
||||||
status,
|
status,
|
||||||
projectPath,
|
projectPath,
|
||||||
summary
|
{ summary }
|
||||||
);
|
);
|
||||||
|
|
||||||
// Notify renderer if window is available
|
// Notify renderer if window is available
|
||||||
@@ -1170,6 +1170,7 @@ ipcMain.handle("spec-regeneration:status", () => {
|
|||||||
isRunning:
|
isRunning:
|
||||||
specRegenerationExecution !== null &&
|
specRegenerationExecution !== null &&
|
||||||
specRegenerationExecution.isActive(),
|
specRegenerationExecution.isActive(),
|
||||||
|
currentPhase: specRegenerationService.getCurrentPhase(),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -382,13 +382,15 @@ class FeatureLoader {
|
|||||||
* @param {string} featureId - The ID of the feature to update
|
* @param {string} featureId - The ID of the feature to update
|
||||||
* @param {string} status - The new status
|
* @param {string} status - The new status
|
||||||
* @param {string} projectPath - Path to the project
|
* @param {string} projectPath - Path to the project
|
||||||
* @param {string} [summary] - Optional summary of what was done
|
* @param {Object} options - Options object for optional parameters
|
||||||
* @param {string} [error] - Optional error message if feature errored
|
* @param {string} [options.summary] - Optional summary of what was done
|
||||||
* @param {string} [description] - Optional detailed description
|
* @param {string} [options.error] - Optional error message if feature errored
|
||||||
* @param {string} [category] - Optional category/phase
|
* @param {string} [options.description] - Optional detailed description
|
||||||
* @param {string[]} [steps] - Optional array of implementation steps
|
* @param {string} [options.category] - Optional category/phase
|
||||||
|
* @param {string[]} [options.steps] - Optional array of implementation steps
|
||||||
*/
|
*/
|
||||||
async updateFeatureStatus(featureId, status, projectPath, summary, error, description, category, steps) {
|
async updateFeatureStatus(featureId, status, projectPath, options = {}) {
|
||||||
|
const { summary, error, description, category, steps } = options;
|
||||||
// Check if feature exists
|
// Check if feature exists
|
||||||
const existingFeature = await this.get(projectPath, featureId);
|
const existingFeature = await this.get(projectPath, featureId);
|
||||||
|
|
||||||
|
|||||||
@@ -53,16 +53,17 @@ class McpServerFactory {
|
|||||||
finalStatus = "waiting_approval";
|
finalStatus = "waiting_approval";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Call the provided callback to update feature status with all parameters
|
// Call the provided callback to update feature status
|
||||||
await updateFeatureStatusCallback(
|
await updateFeatureStatusCallback(
|
||||||
args.featureId,
|
args.featureId,
|
||||||
finalStatus,
|
finalStatus,
|
||||||
projectPath,
|
projectPath,
|
||||||
args.summary,
|
{
|
||||||
undefined, // error
|
summary: args.summary,
|
||||||
args.description,
|
description: args.description,
|
||||||
args.category,
|
category: args.category,
|
||||||
args.steps
|
steps: args.steps,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const statusMessage = finalStatus !== args.status
|
const statusMessage = finalStatus !== args.status
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ async function handleToolsCall(params, id) {
|
|||||||
// Call the update callback via IPC or direct call
|
// Call the update callback via IPC or direct call
|
||||||
// Since we're in a separate process, we need to use IPC to communicate back
|
// Since we're in a separate process, we need to use IPC to communicate back
|
||||||
// For now, we'll call the feature loader directly since it has the update method
|
// For now, we'll call the feature loader directly since it has the update method
|
||||||
await featureLoader.updateFeatureStatus(featureId, finalStatus, projectPath, summary);
|
await featureLoader.updateFeatureStatus(featureId, finalStatus, projectPath, { summary });
|
||||||
|
|
||||||
const statusMessage = finalStatus !== status
|
const statusMessage = finalStatus !== status
|
||||||
? `Successfully updated feature ${featureId} to status "${finalStatus}" (converted from "${status}" because skipTests=true)${summary ? ` with summary: "${summary}"` : ''}`
|
? `Successfully updated feature ${featureId} to status "${finalStatus}" (converted from "${status}" because skipTests=true)${summary ? ` with summary: "${summary}"` : ''}`
|
||||||
|
|||||||
@@ -86,6 +86,15 @@ const APP_SPEC_XML_TEMPLATE = `<project_specification>
|
|||||||
class SpecRegenerationService {
|
class SpecRegenerationService {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.runningRegeneration = null;
|
this.runningRegeneration = null;
|
||||||
|
this.currentPhase = ""; // Tracks current phase for status queries
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current phase of the regeneration process
|
||||||
|
* @returns {string} Current phase or empty string if not running
|
||||||
|
*/
|
||||||
|
getCurrentPhase() {
|
||||||
|
return this.currentPhase;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -107,14 +116,14 @@ class SpecRegenerationService {
|
|||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
execution.abortController = abortController;
|
execution.abortController = abortController;
|
||||||
|
|
||||||
// Phase tracking
|
// Phase tracking - use instance property for status queries
|
||||||
let currentPhase = "initialization";
|
this.currentPhase = "initialization";
|
||||||
|
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: `[Phase: ${currentPhase}] Initializing spec generation process...\n`,
|
content: `[Phase: ${this.currentPhase}] Initializing spec generation process...\n`,
|
||||||
});
|
});
|
||||||
console.log(`[SpecRegeneration] Phase: ${currentPhase}`);
|
console.log(`[SpecRegeneration] Phase: ${this.currentPhase}`);
|
||||||
|
|
||||||
// Create custom MCP server with UpdateFeatureStatus tool if generating features
|
// Create custom MCP server with UpdateFeatureStatus tool if generating features
|
||||||
if (generateFeatures) {
|
if (generateFeatures) {
|
||||||
@@ -135,12 +144,12 @@ class SpecRegenerationService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
currentPhase = "setup";
|
this.currentPhase = "setup";
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: `[Phase: ${currentPhase}] Configuring AI agent and tools...\n`,
|
content: `[Phase: ${this.currentPhase}] Configuring AI agent and tools...\n`,
|
||||||
});
|
});
|
||||||
console.log(`[SpecRegeneration] Phase: ${currentPhase}`);
|
console.log(`[SpecRegeneration] Phase: ${this.currentPhase}`);
|
||||||
|
|
||||||
// Phase 1: Generate spec WITHOUT UpdateFeatureStatus tool
|
// Phase 1: Generate spec WITHOUT UpdateFeatureStatus tool
|
||||||
// This prevents features from being created before the spec is complete
|
// This prevents features from being created before the spec is complete
|
||||||
@@ -160,17 +169,17 @@ class SpecRegenerationService {
|
|||||||
|
|
||||||
const prompt = this.buildInitialCreationPrompt(projectOverview); // No feature generation during spec creation
|
const prompt = this.buildInitialCreationPrompt(projectOverview); // No feature generation during spec creation
|
||||||
|
|
||||||
currentPhase = "analysis";
|
this.currentPhase = "analysis";
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: `[Phase: ${currentPhase}] Starting project analysis and spec creation...\n`,
|
content: `[Phase: ${this.currentPhase}] Starting project analysis and spec creation...\n`,
|
||||||
});
|
});
|
||||||
console.log(`[SpecRegeneration] Phase: ${currentPhase} - Starting AI agent query`);
|
console.log(`[SpecRegeneration] Phase: ${this.currentPhase} - Starting AI agent query`);
|
||||||
|
|
||||||
if (generateFeatures) {
|
if (generateFeatures) {
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: `[Phase: ${currentPhase}] Feature generation is enabled - features will be created after spec is complete.\n`,
|
content: `[Phase: ${this.currentPhase}] Feature generation is enabled - features will be created after spec is complete.\n`,
|
||||||
});
|
});
|
||||||
console.log("[SpecRegeneration] Feature generation enabled - will create features after spec");
|
console.log("[SpecRegeneration] Feature generation enabled - will create features after spec");
|
||||||
}
|
}
|
||||||
@@ -253,11 +262,11 @@ class SpecRegenerationService {
|
|||||||
execution.abortController = null;
|
execution.abortController = null;
|
||||||
|
|
||||||
const elapsedTime = ((Date.now() - startTime) / 1000).toFixed(1);
|
const elapsedTime = ((Date.now() - startTime) / 1000).toFixed(1);
|
||||||
currentPhase = "spec_complete";
|
this.currentPhase = "spec_complete";
|
||||||
console.log(`[SpecRegeneration] Phase: ${currentPhase} - Spec creation completed in ${elapsedTime}s`);
|
console.log(`[SpecRegeneration] Phase: ${this.currentPhase} - Spec creation completed in ${elapsedTime}s`);
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: `\n[Phase: ${currentPhase}] ✓ App specification created successfully! (${elapsedTime}s)\n`,
|
content: `\n[Phase: ${this.currentPhase}] ✓ App specification created successfully! (${elapsedTime}s)\n`,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (generateFeatures) {
|
if (generateFeatures) {
|
||||||
@@ -282,10 +291,10 @@ class SpecRegenerationService {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
currentPhase = "complete";
|
this.currentPhase = "complete";
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: `[Phase: ${currentPhase}] All tasks completed!\n`,
|
content: `[Phase: ${this.currentPhase}] All tasks completed!\n`,
|
||||||
});
|
});
|
||||||
|
|
||||||
// Send final completion event
|
// Send final completion event
|
||||||
@@ -344,16 +353,16 @@ class SpecRegenerationService {
|
|||||||
*/
|
*/
|
||||||
async generateFeaturesFromSpec(projectPath, sendToRenderer, execution, startTime) {
|
async generateFeaturesFromSpec(projectPath, sendToRenderer, execution, startTime) {
|
||||||
const featureStartTime = Date.now();
|
const featureStartTime = Date.now();
|
||||||
let currentPhase = "feature_generation";
|
this.currentPhase = "feature_generation";
|
||||||
|
|
||||||
console.log(`[SpecRegeneration] ===== Starting Phase 2: Feature Generation =====`);
|
console.log(`[SpecRegeneration] ===== Starting Phase 2: Feature Generation =====`);
|
||||||
console.log(`[SpecRegeneration] Project path: ${projectPath}`);
|
console.log(`[SpecRegeneration] Project path: ${projectPath}`);
|
||||||
|
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: `\n[Phase: ${currentPhase}] Starting feature creation from implementation roadmap...\n`,
|
content: `\n[Phase: ${this.currentPhase}] Starting feature creation from implementation roadmap...\n`,
|
||||||
});
|
});
|
||||||
console.log(`[SpecRegeneration] Phase: ${currentPhase} - Starting feature generation query`);
|
console.log(`[SpecRegeneration] Phase: ${this.currentPhase} - Starting feature generation query`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Create feature tools server
|
// Create feature tools server
|
||||||
@@ -492,12 +501,12 @@ Use the UpdateFeatureStatus tool to create features with ALL the fields above.`,
|
|||||||
execution.query = null;
|
execution.query = null;
|
||||||
execution.abortController = null;
|
execution.abortController = null;
|
||||||
|
|
||||||
currentPhase = "complete";
|
this.currentPhase = "complete";
|
||||||
const featureElapsedTime = ((Date.now() - featureStartTime) / 1000).toFixed(1);
|
const featureElapsedTime = ((Date.now() - featureStartTime) / 1000).toFixed(1);
|
||||||
const totalElapsedTime = ((Date.now() - startTime) / 1000).toFixed(1);
|
const totalElapsedTime = ((Date.now() - startTime) / 1000).toFixed(1);
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: `\n[Phase: ${currentPhase}] ✓ All tasks completed! (${totalElapsedTime}s total, ${featureElapsedTime}s for features)\n`,
|
content: `\n[Phase: ${this.currentPhase}] ✓ All tasks completed! (${totalElapsedTime}s total, ${featureElapsedTime}s for features)\n`,
|
||||||
});
|
});
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_complete",
|
type: "spec_regeneration_complete",
|
||||||
@@ -653,22 +662,22 @@ Begin by exploring the project structure.`;
|
|||||||
console.log(`[SpecRegeneration] Project definition length: ${projectDefinition.length} characters`);
|
console.log(`[SpecRegeneration] Project definition length: ${projectDefinition.length} characters`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let currentPhase = "initialization";
|
this.currentPhase = "initialization";
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: `[Phase: ${currentPhase}] Initializing spec regeneration process...\n`,
|
content: `[Phase: ${this.currentPhase}] Initializing spec regeneration process...\n`,
|
||||||
});
|
});
|
||||||
console.log(`[SpecRegeneration] Phase: ${currentPhase}`);
|
console.log(`[SpecRegeneration] Phase: ${this.currentPhase}`);
|
||||||
|
|
||||||
const abortController = new AbortController();
|
const abortController = new AbortController();
|
||||||
execution.abortController = abortController;
|
execution.abortController = abortController;
|
||||||
|
|
||||||
currentPhase = "setup";
|
this.currentPhase = "setup";
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: `[Phase: ${currentPhase}] Configuring AI agent and tools...\n`,
|
content: `[Phase: ${this.currentPhase}] Configuring AI agent and tools...\n`,
|
||||||
});
|
});
|
||||||
console.log(`[SpecRegeneration] Phase: ${currentPhase}`);
|
console.log(`[SpecRegeneration] Phase: ${this.currentPhase}`);
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
model: "claude-sonnet-4-20250514",
|
model: "claude-sonnet-4-20250514",
|
||||||
@@ -686,12 +695,12 @@ Begin by exploring the project structure.`;
|
|||||||
|
|
||||||
const prompt = this.buildRegenerationPrompt(projectDefinition);
|
const prompt = this.buildRegenerationPrompt(projectDefinition);
|
||||||
|
|
||||||
currentPhase = "regeneration";
|
this.currentPhase = "regeneration";
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: `[Phase: ${currentPhase}] Starting spec regeneration...\n`,
|
content: `[Phase: ${this.currentPhase}] Starting spec regeneration...\n`,
|
||||||
});
|
});
|
||||||
console.log(`[SpecRegeneration] Phase: ${currentPhase} - Starting AI agent query`);
|
console.log(`[SpecRegeneration] Phase: ${this.currentPhase} - Starting AI agent query`);
|
||||||
|
|
||||||
const currentQuery = query({ prompt, options });
|
const currentQuery = query({ prompt, options });
|
||||||
execution.query = currentQuery;
|
execution.query = currentQuery;
|
||||||
@@ -725,21 +734,10 @@ Begin by exploring the project structure.`;
|
|||||||
console.log(`[SpecRegeneration] Tool call #${toolCallCount}: ${toolName}`);
|
console.log(`[SpecRegeneration] Tool call #${toolCallCount}: ${toolName}`);
|
||||||
console.log(`[SpecRegeneration] Tool input: ${JSON.stringify(toolInput).substring(0, 200)}...`);
|
console.log(`[SpecRegeneration] Tool input: ${JSON.stringify(toolInput).substring(0, 200)}...`);
|
||||||
|
|
||||||
// Special handling for UpdateFeatureStatus to show feature creation
|
sendToRenderer({
|
||||||
if (toolName === "mcp__automaker-tools__UpdateFeatureStatus" || toolName === "UpdateFeatureStatus") {
|
type: "spec_regeneration_progress",
|
||||||
const featureId = toolInput?.featureId || "unknown";
|
content: `\n[Tool] Using ${toolName}...\n`,
|
||||||
const status = toolInput?.status || "unknown";
|
});
|
||||||
const summary = toolInput?.summary || "";
|
|
||||||
sendToRenderer({
|
|
||||||
type: "spec_regeneration_progress",
|
|
||||||
content: `\n[Feature Creation] Creating feature "${featureId}" with status "${status}"${summary ? `\n Summary: ${summary}` : ""}\n`,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
sendToRenderer({
|
|
||||||
type: "spec_regeneration_progress",
|
|
||||||
content: `\n[Tool] Using ${toolName}...\n`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_tool",
|
type: "spec_regeneration_tool",
|
||||||
@@ -755,18 +753,10 @@ Begin by exploring the project structure.`;
|
|||||||
const resultPreview = result.substring(0, 200).replace(/\n/g, " ");
|
const resultPreview = result.substring(0, 200).replace(/\n/g, " ");
|
||||||
console.log(`[SpecRegeneration] Tool result (${toolName}): ${resultPreview}...`);
|
console.log(`[SpecRegeneration] Tool result (${toolName}): ${resultPreview}...`);
|
||||||
|
|
||||||
// Special handling for UpdateFeatureStatus results
|
sendToRenderer({
|
||||||
if (toolName === "mcp__automaker-tools__UpdateFeatureStatus" || toolName === "UpdateFeatureStatus") {
|
type: "spec_regeneration_progress",
|
||||||
sendToRenderer({
|
content: `[Tool Result] ${toolName} completed successfully\n`,
|
||||||
type: "spec_regeneration_progress",
|
});
|
||||||
content: `[Feature Creation] ${result}\n`,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
sendToRenderer({
|
|
||||||
type: "spec_regeneration_progress",
|
|
||||||
content: `[Tool Result] ${toolName} completed successfully\n`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else if (msg.type === "error") {
|
} else if (msg.type === "error") {
|
||||||
const errorMsg = msg.error?.message || JSON.stringify(msg.error);
|
const errorMsg = msg.error?.message || JSON.stringify(msg.error);
|
||||||
console.error(`[SpecRegeneration] ERROR in query stream: ${errorMsg}`);
|
console.error(`[SpecRegeneration] ERROR in query stream: ${errorMsg}`);
|
||||||
@@ -791,11 +781,11 @@ Begin by exploring the project structure.`;
|
|||||||
execution.abortController = null;
|
execution.abortController = null;
|
||||||
|
|
||||||
const elapsedTime = ((Date.now() - startTime) / 1000).toFixed(1);
|
const elapsedTime = ((Date.now() - startTime) / 1000).toFixed(1);
|
||||||
currentPhase = "complete";
|
this.currentPhase = "complete";
|
||||||
console.log(`[SpecRegeneration] Phase: ${currentPhase} - Spec regeneration completed in ${elapsedTime}s`);
|
console.log(`[SpecRegeneration] Phase: ${this.currentPhase} - Spec regeneration completed in ${elapsedTime}s`);
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: `\n[Phase: ${currentPhase}] ✓ Spec regeneration complete! (${elapsedTime}s)\n`,
|
content: `\n[Phase: ${this.currentPhase}] ✓ Spec regeneration complete! (${elapsedTime}s)\n`,
|
||||||
});
|
});
|
||||||
|
|
||||||
sendToRenderer({
|
sendToRenderer({
|
||||||
@@ -867,9 +857,8 @@ When analyzing, look at:
|
|||||||
- Database configurations and schemas
|
- Database configurations and schemas
|
||||||
- API structures and patterns
|
- API structures and patterns
|
||||||
|
|
||||||
**Feature Storage:**
|
**Note:** Feature files are stored separately in .automaker/features/{id}/feature.json.
|
||||||
Features are stored in .automaker/features/{id}/feature.json - each feature has its own folder.
|
Your task is ONLY to update the app_spec.txt file - feature files will be managed separately.
|
||||||
Do NOT manually create feature files. Use the UpdateFeatureStatus tool to manage features.
|
|
||||||
|
|
||||||
You CAN and SHOULD modify:
|
You CAN and SHOULD modify:
|
||||||
- .automaker/app_spec.txt (this is your primary target)
|
- .automaker/app_spec.txt (this is your primary target)
|
||||||
@@ -1042,6 +1031,7 @@ Begin by exploring the project structure.`;
|
|||||||
this.runningRegeneration.abortController.abort();
|
this.runningRegeneration.abortController.abort();
|
||||||
}
|
}
|
||||||
this.runningRegeneration = null;
|
this.runningRegeneration = null;
|
||||||
|
this.currentPhase = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -105,93 +105,38 @@ export function SpecView() {
|
|||||||
console.log("[SpecView] Status check on mount:", status);
|
console.log("[SpecView] Status check on mount:", status);
|
||||||
|
|
||||||
if (status.success && status.isRunning) {
|
if (status.success && status.isRunning) {
|
||||||
// Something is running - restore state
|
// Something is running - restore state using backend's authoritative phase
|
||||||
console.log("[SpecView] Spec generation is running - restoring state");
|
console.log("[SpecView] Spec generation is running - restoring state", { phase: status.currentPhase });
|
||||||
|
|
||||||
// Only restore state if we haven't already done so for this project
|
|
||||||
// This prevents resetting state when switching tabs
|
|
||||||
if (!stateRestoredRef.current) {
|
if (!stateRestoredRef.current) {
|
||||||
setIsCreating(true);
|
setIsCreating(true);
|
||||||
setIsRegenerating(true);
|
setIsRegenerating(true);
|
||||||
stateRestoredRef.current = true;
|
stateRestoredRef.current = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to extract the current phase from existing logs
|
// Use the backend's currentPhase directly - single source of truth
|
||||||
let detectedPhase = "";
|
if (status.currentPhase) {
|
||||||
if (logsRef.current) {
|
setCurrentPhase(status.currentPhase);
|
||||||
// Look for the most recent phase in the logs
|
} else {
|
||||||
const phaseMatches = logsRef.current.matchAll(/\[Phase:\s*([^\]]+)\]/g);
|
|
||||||
const phases = Array.from(phaseMatches);
|
|
||||||
if (phases.length > 0) {
|
|
||||||
// Get the last phase mentioned in the logs
|
|
||||||
detectedPhase = phases[phases.length - 1][1];
|
|
||||||
console.log(`[SpecView] Detected phase from logs: ${detectedPhase}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also check for feature generation indicators in logs
|
|
||||||
const hasFeatureGeneration = logsRef.current.includes("Feature Generation") ||
|
|
||||||
logsRef.current.includes("Feature Creation") ||
|
|
||||||
logsRef.current.includes("Creating feature") ||
|
|
||||||
logsRef.current.includes("feature_generation");
|
|
||||||
|
|
||||||
if (hasFeatureGeneration && !detectedPhase) {
|
|
||||||
detectedPhase = "feature_generation";
|
|
||||||
console.log("[SpecView] Detected feature generation from logs");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update phase from logs if we found one and don't have a specific phase set
|
|
||||||
// This allows the phase to update as new events come in
|
|
||||||
if (detectedPhase) {
|
|
||||||
setCurrentPhase((prevPhase) => {
|
|
||||||
// Only update if we don't have a phase or if the detected phase is more recent
|
|
||||||
if (!prevPhase || prevPhase === "unknown" || prevPhase === "in progress") {
|
|
||||||
return detectedPhase;
|
|
||||||
}
|
|
||||||
return prevPhase;
|
|
||||||
});
|
|
||||||
} else if (!currentPhase) {
|
|
||||||
// Use a more descriptive default instead of "unknown"
|
|
||||||
setCurrentPhase("in progress");
|
setCurrentPhase("in progress");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't clear logs - they may have been persisted
|
// Add resume message to logs if needed
|
||||||
if (!logsRef.current) {
|
if (!logsRef.current) {
|
||||||
const resumeMessage = "[Status] Resumed monitoring existing spec generation process...\n";
|
const resumeMessage = "[Status] Resumed monitoring existing spec generation process...\n";
|
||||||
logsRef.current = resumeMessage;
|
logsRef.current = resumeMessage;
|
||||||
setLogs(resumeMessage);
|
setLogs(resumeMessage);
|
||||||
} else if (!logsRef.current.includes("Resumed monitoring")) {
|
} else if (!logsRef.current.includes("Resumed monitoring")) {
|
||||||
// Add a resume message to existing logs only if not already present
|
|
||||||
const resumeMessage = "\n[Status] Resumed monitoring existing spec generation process...\n";
|
const resumeMessage = "\n[Status] Resumed monitoring existing spec generation process...\n";
|
||||||
logsRef.current = logsRef.current + resumeMessage;
|
logsRef.current = logsRef.current + resumeMessage;
|
||||||
setLogs(logsRef.current);
|
setLogs(logsRef.current);
|
||||||
}
|
}
|
||||||
} else if (status.success && !status.isRunning) {
|
} else if (status.success && !status.isRunning) {
|
||||||
// Check if we might still be in feature generation phase based on logs
|
// Not running - clear all state
|
||||||
const mightBeGeneratingFeatures = logsRef.current && (
|
setIsCreating(false);
|
||||||
logsRef.current.includes("Feature Generation") ||
|
setIsRegenerating(false);
|
||||||
logsRef.current.includes("Feature Creation") ||
|
setCurrentPhase("");
|
||||||
logsRef.current.includes("Creating feature") ||
|
stateRestoredRef.current = false;
|
||||||
logsRef.current.includes("feature_generation") ||
|
|
||||||
currentPhase === "feature_generation"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (mightBeGeneratingFeatures && specExists) {
|
|
||||||
// Spec exists and we might still be generating features - keep state active
|
|
||||||
console.log("[SpecView] Detected potential feature generation - keeping state active");
|
|
||||||
if (!isCreating && !isRegenerating) {
|
|
||||||
setIsCreating(true);
|
|
||||||
}
|
|
||||||
if (currentPhase !== "feature_generation") {
|
|
||||||
setCurrentPhase("feature_generation");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Not running - clear running state
|
|
||||||
setIsCreating(false);
|
|
||||||
setIsRegenerating(false);
|
|
||||||
setCurrentPhase("");
|
|
||||||
stateRestoredRef.current = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[SpecView] Failed to check status:", error);
|
console.error("[SpecView] Failed to check status:", error);
|
||||||
@@ -209,7 +154,7 @@ export function SpecView() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const handleVisibilityChange = async () => {
|
const handleVisibilityChange = async () => {
|
||||||
if (!document.hidden && currentProject && (isCreating || isRegenerating || isGeneratingFeatures)) {
|
if (!document.hidden && currentProject && (isCreating || isRegenerating || isGeneratingFeatures)) {
|
||||||
// Tab became visible and we think we're still generating - verify status
|
// Tab became visible and we think we're still generating - verify status from backend
|
||||||
try {
|
try {
|
||||||
const api = getElectronAPI();
|
const api = getElectronAPI();
|
||||||
if (!api.specRegeneration) return;
|
if (!api.specRegeneration) return;
|
||||||
@@ -218,45 +163,17 @@ export function SpecView() {
|
|||||||
console.log("[SpecView] Visibility change - status check:", status);
|
console.log("[SpecView] Visibility change - status check:", status);
|
||||||
|
|
||||||
if (!status.isRunning) {
|
if (!status.isRunning) {
|
||||||
// Not running but we think we are - check if we're truly done
|
// Backend says not running - clear state
|
||||||
// Look for recent activity in logs (within last 30 seconds worth of content)
|
console.log("[SpecView] Visibility change: Backend indicates generation complete - clearing state");
|
||||||
const recentLogs = logsRef.current.slice(-5000); // Last ~5000 chars
|
setIsCreating(false);
|
||||||
const hasRecentFeatureActivity = recentLogs.includes("Feature Creation") ||
|
setIsRegenerating(false);
|
||||||
recentLogs.includes("Creating feature") ||
|
setIsGeneratingFeatures(false);
|
||||||
recentLogs.match(/\[Feature Creation\].*$/m);
|
setCurrentPhase("");
|
||||||
|
stateRestoredRef.current = false;
|
||||||
// Check if we have a completion message or complete phase
|
loadSpec();
|
||||||
const hasCompletion = logsRef.current.includes("All tasks completed") ||
|
} else if (status.currentPhase) {
|
||||||
logsRef.current.includes("[Complete] All tasks completed") ||
|
// Still running - update phase from backend
|
||||||
logsRef.current.includes("[Phase: complete]");
|
setCurrentPhase(status.currentPhase);
|
||||||
|
|
||||||
if (hasCompletion || (!hasRecentFeatureActivity && currentPhase !== "feature_generation")) {
|
|
||||||
// No recent activity and not running - we're done
|
|
||||||
console.log("[SpecView] Visibility change: Generation appears complete - clearing state");
|
|
||||||
setIsCreating(false);
|
|
||||||
setIsRegenerating(false);
|
|
||||||
setIsGeneratingFeatures(false);
|
|
||||||
setCurrentPhase("");
|
|
||||||
stateRestoredRef.current = false;
|
|
||||||
loadSpec();
|
|
||||||
} else if (currentPhase === "feature_generation" && !hasRecentFeatureActivity) {
|
|
||||||
// We were in feature generation but no recent activity - might be done
|
|
||||||
// Wait a moment and check again
|
|
||||||
setTimeout(async () => {
|
|
||||||
if (api.specRegeneration) {
|
|
||||||
const recheckStatus = await api.specRegeneration.status();
|
|
||||||
if (!recheckStatus.isRunning) {
|
|
||||||
console.log("[SpecView] Re-check after visibility: Still not running - clearing state");
|
|
||||||
setIsCreating(false);
|
|
||||||
setIsRegenerating(false);
|
|
||||||
setIsGeneratingFeatures(false);
|
|
||||||
setCurrentPhase("");
|
|
||||||
stateRestoredRef.current = false;
|
|
||||||
loadSpec();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, STATUS_CHECK_INTERVAL_MS);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[SpecView] Failed to check status on visibility change:", error);
|
console.error("[SpecView] Failed to check status on visibility change:", error);
|
||||||
@@ -268,7 +185,7 @@ export function SpecView() {
|
|||||||
return () => {
|
return () => {
|
||||||
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
||||||
};
|
};
|
||||||
}, [currentProject, isCreating, isRegenerating, isGeneratingFeatures, currentPhase, loadSpec]);
|
}, [currentProject, isCreating, isRegenerating, isGeneratingFeatures, loadSpec]);
|
||||||
|
|
||||||
// Periodic status check to ensure state stays in sync (only when we think we're running)
|
// Periodic status check to ensure state stays in sync (only when we think we're running)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -281,40 +198,22 @@ export function SpecView() {
|
|||||||
|
|
||||||
const status = await api.specRegeneration.status();
|
const status = await api.specRegeneration.status();
|
||||||
|
|
||||||
// If not running but we think we are, verify we're truly done
|
if (!status.isRunning) {
|
||||||
if (!status.isRunning && (isCreating || isRegenerating || isGeneratingFeatures)) {
|
// Backend says not running - clear state
|
||||||
// Check logs for completion indicators
|
console.log("[SpecView] Periodic check: Backend indicates generation complete - clearing state");
|
||||||
const hasCompletion = logsRef.current.includes("All tasks completed") ||
|
setIsCreating(false);
|
||||||
logsRef.current.includes("[Complete] All tasks completed") ||
|
setIsRegenerating(false);
|
||||||
logsRef.current.includes("[Phase: complete]") ||
|
setIsGeneratingFeatures(false);
|
||||||
currentPhase === "complete";
|
setCurrentPhase("");
|
||||||
|
stateRestoredRef.current = false;
|
||||||
// Also check if we haven't seen feature activity recently
|
loadSpec();
|
||||||
const recentLogs = logsRef.current.slice(-3000); // Last 3000 chars (more context)
|
} else if (status.currentPhase && status.currentPhase !== currentPhase) {
|
||||||
const hasRecentFeatureActivity = recentLogs.includes("Feature Creation") ||
|
// Still running but phase changed - update from backend
|
||||||
recentLogs.includes("Creating feature") ||
|
console.log("[SpecView] Periodic check: Phase updated from backend", {
|
||||||
recentLogs.includes("UpdateFeatureStatus") ||
|
old: currentPhase,
|
||||||
recentLogs.includes("[Tool]") && recentLogs.includes("UpdateFeatureStatus");
|
new: status.currentPhase
|
||||||
|
});
|
||||||
// If we're in feature_generation phase and not running, we're likely done
|
setCurrentPhase(status.currentPhase);
|
||||||
// (features are created via tool calls, so when stream ends, they're done)
|
|
||||||
const isFeatureGenComplete = currentPhase === "feature_generation" &&
|
|
||||||
!hasRecentFeatureActivity;
|
|
||||||
|
|
||||||
if (hasCompletion || isFeatureGenComplete) {
|
|
||||||
console.log("[SpecView] Periodic check: Generation complete - clearing state", {
|
|
||||||
hasCompletion,
|
|
||||||
hasRecentFeatureActivity,
|
|
||||||
currentPhase,
|
|
||||||
isFeatureGenComplete
|
|
||||||
});
|
|
||||||
setIsCreating(false);
|
|
||||||
setIsRegenerating(false);
|
|
||||||
setIsGeneratingFeatures(false);
|
|
||||||
setCurrentPhase("");
|
|
||||||
stateRestoredRef.current = false;
|
|
||||||
loadSpec();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("[SpecView] Periodic status check error:", error);
|
console.error("[SpecView] Periodic status check error:", error);
|
||||||
|
|||||||
@@ -1800,6 +1800,7 @@ async function simulateSuggestionsGeneration(
|
|||||||
|
|
||||||
// Mock Spec Regeneration state and implementation
|
// Mock Spec Regeneration state and implementation
|
||||||
let mockSpecRegenerationRunning = false;
|
let mockSpecRegenerationRunning = false;
|
||||||
|
let mockSpecRegenerationPhase = "";
|
||||||
let mockSpecRegenerationCallbacks: ((event: SpecRegenerationEvent) => void)[] =
|
let mockSpecRegenerationCallbacks: ((event: SpecRegenerationEvent) => void)[] =
|
||||||
[];
|
[];
|
||||||
let mockSpecRegenerationTimeout: NodeJS.Timeout | null = null;
|
let mockSpecRegenerationTimeout: NodeJS.Timeout | null = null;
|
||||||
@@ -1862,6 +1863,7 @@ function createMockSpecRegenerationAPI(): SpecRegenerationAPI {
|
|||||||
|
|
||||||
stop: async () => {
|
stop: async () => {
|
||||||
mockSpecRegenerationRunning = false;
|
mockSpecRegenerationRunning = false;
|
||||||
|
mockSpecRegenerationPhase = "";
|
||||||
if (mockSpecRegenerationTimeout) {
|
if (mockSpecRegenerationTimeout) {
|
||||||
clearTimeout(mockSpecRegenerationTimeout);
|
clearTimeout(mockSpecRegenerationTimeout);
|
||||||
mockSpecRegenerationTimeout = null;
|
mockSpecRegenerationTimeout = null;
|
||||||
@@ -1873,6 +1875,7 @@ function createMockSpecRegenerationAPI(): SpecRegenerationAPI {
|
|||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
isRunning: mockSpecRegenerationRunning,
|
isRunning: mockSpecRegenerationRunning,
|
||||||
|
currentPhase: mockSpecRegenerationPhase,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1896,9 +1899,10 @@ async function simulateSpecCreation(
|
|||||||
projectOverview: string,
|
projectOverview: string,
|
||||||
generateFeatures = true
|
generateFeatures = true
|
||||||
) {
|
) {
|
||||||
|
mockSpecRegenerationPhase = "initialization";
|
||||||
emitSpecRegenerationEvent({
|
emitSpecRegenerationEvent({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: "Starting project analysis...\n",
|
content: "[Phase: initialization] Starting project analysis...\n",
|
||||||
});
|
});
|
||||||
|
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
@@ -1906,6 +1910,7 @@ async function simulateSpecCreation(
|
|||||||
});
|
});
|
||||||
if (!mockSpecRegenerationRunning) return;
|
if (!mockSpecRegenerationRunning) return;
|
||||||
|
|
||||||
|
mockSpecRegenerationPhase = "setup";
|
||||||
emitSpecRegenerationEvent({
|
emitSpecRegenerationEvent({
|
||||||
type: "spec_regeneration_tool",
|
type: "spec_regeneration_tool",
|
||||||
tool: "Glob",
|
tool: "Glob",
|
||||||
@@ -1917,9 +1922,10 @@ async function simulateSpecCreation(
|
|||||||
});
|
});
|
||||||
if (!mockSpecRegenerationRunning) return;
|
if (!mockSpecRegenerationRunning) return;
|
||||||
|
|
||||||
|
mockSpecRegenerationPhase = "analysis";
|
||||||
emitSpecRegenerationEvent({
|
emitSpecRegenerationEvent({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: "Detecting tech stack...\n",
|
content: "[Phase: analysis] Detecting tech stack...\n",
|
||||||
});
|
});
|
||||||
|
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
@@ -1959,12 +1965,14 @@ async function simulateSpecCreation(
|
|||||||
// The generateFeatures parameter is kept for API compatibility but features
|
// The generateFeatures parameter is kept for API compatibility but features
|
||||||
// should be created through the features API
|
// should be created through the features API
|
||||||
|
|
||||||
|
mockSpecRegenerationPhase = "complete";
|
||||||
emitSpecRegenerationEvent({
|
emitSpecRegenerationEvent({
|
||||||
type: "spec_regeneration_complete",
|
type: "spec_regeneration_complete",
|
||||||
message: "Initial spec creation complete!",
|
message: "All tasks completed!",
|
||||||
});
|
});
|
||||||
|
|
||||||
mockSpecRegenerationRunning = false;
|
mockSpecRegenerationRunning = false;
|
||||||
|
mockSpecRegenerationPhase = "";
|
||||||
mockSpecRegenerationTimeout = null;
|
mockSpecRegenerationTimeout = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1972,9 +1980,10 @@ async function simulateSpecRegeneration(
|
|||||||
projectPath: string,
|
projectPath: string,
|
||||||
projectDefinition: string
|
projectDefinition: string
|
||||||
) {
|
) {
|
||||||
|
mockSpecRegenerationPhase = "initialization";
|
||||||
emitSpecRegenerationEvent({
|
emitSpecRegenerationEvent({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: "Starting spec regeneration...\n",
|
content: "[Phase: initialization] Starting spec regeneration...\n",
|
||||||
});
|
});
|
||||||
|
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
@@ -1982,9 +1991,10 @@ async function simulateSpecRegeneration(
|
|||||||
});
|
});
|
||||||
if (!mockSpecRegenerationRunning) return;
|
if (!mockSpecRegenerationRunning) return;
|
||||||
|
|
||||||
|
mockSpecRegenerationPhase = "analysis";
|
||||||
emitSpecRegenerationEvent({
|
emitSpecRegenerationEvent({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: "Analyzing codebase...\n",
|
content: "[Phase: analysis] Analyzing codebase...\n",
|
||||||
});
|
});
|
||||||
|
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
@@ -2015,16 +2025,19 @@ async function simulateSpecRegeneration(
|
|||||||
</core_capabilities>
|
</core_capabilities>
|
||||||
</project_specification>`;
|
</project_specification>`;
|
||||||
|
|
||||||
|
mockSpecRegenerationPhase = "complete";
|
||||||
emitSpecRegenerationEvent({
|
emitSpecRegenerationEvent({
|
||||||
type: "spec_regeneration_complete",
|
type: "spec_regeneration_complete",
|
||||||
message: "Spec regeneration complete!",
|
message: "All tasks completed!",
|
||||||
});
|
});
|
||||||
|
|
||||||
mockSpecRegenerationRunning = false;
|
mockSpecRegenerationRunning = false;
|
||||||
|
mockSpecRegenerationPhase = "";
|
||||||
mockSpecRegenerationTimeout = null;
|
mockSpecRegenerationTimeout = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function simulateFeatureGeneration(projectPath: string) {
|
async function simulateFeatureGeneration(projectPath: string) {
|
||||||
|
mockSpecRegenerationPhase = "initialization";
|
||||||
emitSpecRegenerationEvent({
|
emitSpecRegenerationEvent({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: "[Phase: initialization] Starting feature generation from existing app_spec.txt...\n",
|
content: "[Phase: initialization] Starting feature generation from existing app_spec.txt...\n",
|
||||||
@@ -2045,9 +2058,10 @@ async function simulateFeatureGeneration(projectPath: string) {
|
|||||||
});
|
});
|
||||||
if (!mockSpecRegenerationRunning) return;
|
if (!mockSpecRegenerationRunning) return;
|
||||||
|
|
||||||
|
mockSpecRegenerationPhase = "feature_generation";
|
||||||
emitSpecRegenerationEvent({
|
emitSpecRegenerationEvent({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: "[Feature Creation] Creating features from roadmap...\n",
|
content: "[Phase: feature_generation] Creating features from roadmap...\n",
|
||||||
});
|
});
|
||||||
|
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
@@ -2055,6 +2069,7 @@ async function simulateFeatureGeneration(projectPath: string) {
|
|||||||
});
|
});
|
||||||
if (!mockSpecRegenerationRunning) return;
|
if (!mockSpecRegenerationRunning) return;
|
||||||
|
|
||||||
|
mockSpecRegenerationPhase = "complete";
|
||||||
emitSpecRegenerationEvent({
|
emitSpecRegenerationEvent({
|
||||||
type: "spec_regeneration_progress",
|
type: "spec_regeneration_progress",
|
||||||
content: "[Phase: complete] All tasks completed!\n",
|
content: "[Phase: complete] All tasks completed!\n",
|
||||||
@@ -2066,6 +2081,7 @@ async function simulateFeatureGeneration(projectPath: string) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
mockSpecRegenerationRunning = false;
|
mockSpecRegenerationRunning = false;
|
||||||
|
mockSpecRegenerationPhase = "";
|
||||||
mockSpecRegenerationTimeout = null;
|
mockSpecRegenerationTimeout = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
1
app/src/types/electron.d.ts
vendored
1
app/src/types/electron.d.ts
vendored
@@ -270,6 +270,7 @@ export interface SpecRegenerationAPI {
|
|||||||
status: () => Promise<{
|
status: () => Promise<{
|
||||||
success: boolean;
|
success: boolean;
|
||||||
isRunning?: boolean;
|
isRunning?: boolean;
|
||||||
|
currentPhase?: string;
|
||||||
error?: string;
|
error?: string;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user