UNPKG

aiwg

Version:

Deployment tool and support utility for AI context. Copies agents, skills, commands, rules, and behaviors into the paths each AI platform reads (Claude Code, Codex, Copilot, Cursor, Warp, OpenClaw, and 6 more) so one source of truth works across 10 platfo

94 lines 3.28 kB
/** * OrchestratorOverride — Operator HITL (Human-in-the-Loop) handoff * * Manages the override lifecycle for an orchestrator session. When a human * operator needs to take direct control of a PTY session, they call override() * to pause the orchestrator, interact with the PTY directly, then call release() * to hand control back to the orchestrator. * * Flow: * Orchestrator running → override() → * orchestrator.pause() → * PTY stdin routed to operator (caller manages routing) → * operator interacts directly → * release() → * orchestrator.resume() with updated screen context * * Safety guarantees: * - override() is idempotent — calling it when already overridden is a no-op * - release() is idempotent — calling it when not overridden is a no-op * - Both methods are no-ops when the orchestrator is in done state * - All override events are recorded for audit trail * * Future enhancement: inject a 'wait' action with operator-override reasoning * into the orchestrator's history once OrchestratorPTY exposes addHistory(). * * @issue #758 * @see src/serve/orchestrator-pty.ts — OrchestratorPTY with pause()/resume() */ // ============================================================ // OrchestratorOverride // ============================================================ export class OrchestratorOverride { orchestrator; _active = false; _events = []; _overrideCount = 0; constructor(orchestrator) { this.orchestrator = orchestrator; } /** * Take manual control. Pauses the orchestrator and records an override-start * event. The caller is responsible for routing PTY stdin to operator input * while the override is active. * * No-op if already overridden or if the orchestrator is done. */ override() { if (this.orchestrator.done) return; if (this._active) return; this.orchestrator.pause(); this._active = true; this._events.push({ type: 'override-start', timestamp: Date.now(), source: 'operator', }); } /** * Release manual control. Resumes the orchestrator and records an * override-end event. The orchestrator will read the current screen state * on its next cycle and continue from there. * * No-op if no override is active or if the orchestrator is done. */ async release() { if (this.orchestrator.done) return; if (!this._active) return; this._active = false; this._overrideCount++; this._events.push({ type: 'override-end', timestamp: Date.now(), source: 'operator', }); await this.orchestrator.resume(); } /** Whether an override is currently active */ get active() { return this._active; } /** Get all override events (returns a copy for audit trail safety) */ getEvents() { return [...this._events]; } /** Number of override cycles that have completed (override + release pairs) */ get overrideCount() { return this._overrideCount; } } //# sourceMappingURL=orchestrator-override.js.map