mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-03-18 22:33:08 +00:00
Fix: Dev server detection bug fixes. Settings sync bug fixes. Cli provider fixes. Terminal background/foreground colors (#791)
* Changes from fix/dev-server-state-bug * feat: Add configurable max turns setting with user overrides. Address pr comments * fix: Update default behaviors and improve state management across server and UI * feat: Extract branch sync logic to separate service. Fix settings sync bug. Address pr comments * refactor: Extract magic numbers to named constants and improve branch tracking logic - Add DEFAULT_MAX_TURNS (1000) and MAX_ALLOWED_TURNS (2000) constants to settings-helpers - Replace hardcoded 1000 values with DEFAULT_MAX_TURNS constant throughout codebase - Improve max turns validation with explicit Number.isFinite check - Update getTrackingBranch to split on first slash instead of last for better remote parsing - Change isBranchCheckedOut return type from boolean to string|null to return worktree path - Add comments explaining skipFetch parameter in worktree creation - Fix cleanup order in AgentExecutor finally block to run before logging ``` * feat: Add comment refresh and improve model sync in PR dialog
This commit is contained in:
@@ -175,7 +175,10 @@ describe('execution-service.ts', () => {
|
||||
} as unknown as TypedEventBus;
|
||||
|
||||
mockConcurrencyManager = {
|
||||
acquire: vi.fn().mockImplementation(({ featureId }) => createRunningFeature(featureId)),
|
||||
acquire: vi.fn().mockImplementation(({ featureId, isAutoMode }) => ({
|
||||
...createRunningFeature(featureId),
|
||||
isAutoMode: isAutoMode ?? false,
|
||||
})),
|
||||
release: vi.fn(),
|
||||
getRunningFeature: vi.fn(),
|
||||
isRunning: vi.fn(),
|
||||
@@ -550,8 +553,8 @@ describe('execution-service.ts', () => {
|
||||
expect(mockRunAgentFn).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('emits feature_complete event on success', async () => {
|
||||
await service.executeFeature('/test/project', 'feature-1');
|
||||
it('emits feature_complete event on success when isAutoMode is true', async () => {
|
||||
await service.executeFeature('/test/project', 'feature-1', false, true);
|
||||
|
||||
expect(mockEventBus.emitAutoModeEvent).toHaveBeenCalledWith(
|
||||
'auto_mode_feature_complete',
|
||||
@@ -561,6 +564,15 @@ describe('execution-service.ts', () => {
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('does not emit feature_complete event on success when isAutoMode is false', async () => {
|
||||
await service.executeFeature('/test/project', 'feature-1', false, false);
|
||||
|
||||
const completeCalls = vi
|
||||
.mocked(mockEventBus.emitAutoModeEvent)
|
||||
.mock.calls.filter((call) => call[0] === 'auto_mode_feature_complete');
|
||||
expect(completeCalls.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('executeFeature - approved plan handling', () => {
|
||||
@@ -1110,7 +1122,7 @@ describe('execution-service.ts', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('handles abort signal without error event', async () => {
|
||||
it('handles abort signal without error event (emits feature_complete when isAutoMode=true)', async () => {
|
||||
const abortError = new Error('abort');
|
||||
abortError.name = 'AbortError';
|
||||
mockRunAgentFn = vi.fn().mockRejectedValue(abortError);
|
||||
@@ -1136,7 +1148,7 @@ describe('execution-service.ts', () => {
|
||||
mockLoadContextFilesFn
|
||||
);
|
||||
|
||||
await svc.executeFeature('/test/project', 'feature-1');
|
||||
await svc.executeFeature('/test/project', 'feature-1', false, true);
|
||||
|
||||
// Should emit feature_complete with stopped by user
|
||||
expect(mockEventBus.emitAutoModeEvent).toHaveBeenCalledWith(
|
||||
@@ -1155,6 +1167,47 @@ describe('execution-service.ts', () => {
|
||||
expect(errorCalls.length).toBe(0);
|
||||
});
|
||||
|
||||
it('handles abort signal without emitting feature_complete when isAutoMode=false', async () => {
|
||||
const abortError = new Error('abort');
|
||||
abortError.name = 'AbortError';
|
||||
mockRunAgentFn = vi.fn().mockRejectedValue(abortError);
|
||||
|
||||
const svc = new ExecutionService(
|
||||
mockEventBus,
|
||||
mockConcurrencyManager,
|
||||
mockWorktreeResolver,
|
||||
mockSettingsService,
|
||||
mockRunAgentFn,
|
||||
mockExecutePipelineFn,
|
||||
mockUpdateFeatureStatusFn,
|
||||
mockLoadFeatureFn,
|
||||
mockGetPlanningPromptPrefixFn,
|
||||
mockSaveFeatureSummaryFn,
|
||||
mockRecordLearningsFn,
|
||||
mockContextExistsFn,
|
||||
mockResumeFeatureFn,
|
||||
mockTrackFailureFn,
|
||||
mockSignalPauseFn,
|
||||
mockRecordSuccessFn,
|
||||
mockSaveExecutionStateFn,
|
||||
mockLoadContextFilesFn
|
||||
);
|
||||
|
||||
await svc.executeFeature('/test/project', 'feature-1', false, false);
|
||||
|
||||
// Should NOT emit feature_complete when isAutoMode is false
|
||||
const completeCalls = vi
|
||||
.mocked(mockEventBus.emitAutoModeEvent)
|
||||
.mock.calls.filter((call) => call[0] === 'auto_mode_feature_complete');
|
||||
expect(completeCalls.length).toBe(0);
|
||||
|
||||
// Should NOT emit error event (abort is not an error)
|
||||
const errorCalls = vi
|
||||
.mocked(mockEventBus.emitAutoModeEvent)
|
||||
.mock.calls.filter((call) => call[0] === 'auto_mode_error');
|
||||
expect(errorCalls.length).toBe(0);
|
||||
});
|
||||
|
||||
it('releases running feature even on error', async () => {
|
||||
const testError = new Error('Test error');
|
||||
mockRunAgentFn = vi.fn().mockRejectedValue(testError);
|
||||
@@ -1339,8 +1392,8 @@ describe('execution-service.ts', () => {
|
||||
it('handles missing agent output gracefully', async () => {
|
||||
vi.mocked(secureFs.readFile).mockRejectedValue(new Error('ENOENT'));
|
||||
|
||||
// Should not throw
|
||||
await service.executeFeature('/test/project', 'feature-1');
|
||||
// Should not throw (isAutoMode=true so event is emitted)
|
||||
await service.executeFeature('/test/project', 'feature-1', false, true);
|
||||
|
||||
// Feature should still complete successfully
|
||||
expect(mockEventBus.emitAutoModeEvent).toHaveBeenCalledWith(
|
||||
|
||||
Reference in New Issue
Block a user