diff --git a/src/inner-loop-tracker.ts b/src/inner-loop-tracker.ts index 4b25c035..f1ea15ee 100644 --- a/src/inner-loop-tracker.ts +++ b/src/inner-loop-tracker.ts @@ -280,6 +280,9 @@ export class InnerLoopTracker extends EventEmitter { /** Flag indicating pending loopUpdate emission */ private _loopUpdatePending: boolean = false; + /** When true, prevents auto-enable on pattern detection */ + private _autoEnableDisabled: boolean = false; + /** * Creates a new InnerLoopTracker instance. * Starts in disabled state until Ralph patterns are detected. @@ -289,6 +292,28 @@ export class InnerLoopTracker extends EventEmitter { this._loopState = createInitialInnerLoopState(); } + /** + * Prevent auto-enable from pattern detection. + * Use this when the user has explicitly disabled the Ralph tracker. + */ + disableAutoEnable(): void { + this._autoEnableDisabled = true; + } + + /** + * Allow auto-enable from pattern detection. + */ + enableAutoEnable(): void { + this._autoEnableDisabled = false; + } + + /** + * Whether auto-enable is disabled. + */ + get autoEnableDisabled(): boolean { + return this._autoEnableDisabled; + } + /** * Whether the tracker is enabled and actively monitoring output. * Disabled by default; auto-enables when Ralph patterns detected. @@ -500,6 +525,10 @@ export class InnerLoopTracker extends EventEmitter { // If tracker is disabled, only check for patterns that should auto-enable it if (!this._loopState.enabled) { + // Don't auto-enable if explicitly disabled by user setting + if (this._autoEnableDisabled) { + return; + } if (this.shouldAutoEnable(cleanData)) { this.enable(); // Continue processing now that we're enabled diff --git a/src/web/server.ts b/src/web/server.ts index adef1575..30d1791f 100644 --- a/src/web/server.ts +++ b/src/web/server.ts @@ -262,13 +262,14 @@ export class WebServer extends EventEmitter { // Configure inner loop (Ralph Wiggum) settings this.app.post('/api/sessions/:id/inner-config', async (req) => { const { id } = req.params as { id: string }; - const { enabled, completionPhrase, maxIterations, maxTodos, todoExpirationMinutes, reset } = req.body as { + const { enabled, completionPhrase, maxIterations, maxTodos, todoExpirationMinutes, reset, disableAutoEnable } = req.body as { enabled?: boolean; completionPhrase?: string; maxIterations?: number; maxTodos?: number; todoExpirationMinutes?: number; reset?: boolean | 'full'; // true = soft reset (keep enabled), 'full' = complete reset + disableAutoEnable?: boolean; // Prevent auto-enable on pattern detection }; const session = this.sessions.get(id); @@ -285,6 +286,15 @@ export class WebServer extends EventEmitter { } } + // Configure auto-enable behavior + if (disableAutoEnable !== undefined) { + if (disableAutoEnable) { + session.innerLoopTracker.disableAutoEnable(); + } else { + session.innerLoopTracker.enableAutoEnable(); + } + } + // Enable/disable the tracker if (enabled !== undefined) { if (enabled) {