From 7566197269a4a1767df1ce4d39f8fad6844ec587 Mon Sep 17 00:00:00 2001 From: Jackson Moore Date: Fri, 4 Sep 2026 14:32:23 +0200 Subject: Expose diagnostic full reset --- lua/clever_f/action_facade.lua | 10 ++++++++++ lua/clever_f/composition_root.lua | 4 ++++ lua/clever_f/sequence_coordinator.lua | 16 ++++++++++++++++ tests/run.lua | 26 ++++++++++++++++++++++++++ 4 files changed, 56 insertions(+) diff --git a/lua/clever_f/action_facade.lua b/lua/clever_f/action_facade.lua index b732ca6..a3fe173 100644 --- a/lua/clever_f/action_facade.lua +++ b/lua/clever_f/action_facade.lua @@ -91,6 +91,16 @@ end ActionFacade.Reset = ActionFacade.reset +function ActionFacade:diagnostic_full_reset() + local outcome = self:coordinator():diagnostic_full_reset() + if not domain.ActionOutcome.is(outcome) then + fail("SequenceCoordinator must return an ActionOutcome", 2) + end + return outcome +end + +ActionFacade.DiagnosticFullReset = ActionFacade.diagnostic_full_reset + local function explicit_outcome(facade, method_name) local coordinator = facade:coordinator() local outcome = coordinator[method_name](coordinator) diff --git a/lua/clever_f/composition_root.lua b/lua/clever_f/composition_root.lua index f9c7a4c..35aaf1f 100644 --- a/lua/clever_f/composition_root.lua +++ b/lua/clever_f/composition_root.lua @@ -215,6 +215,10 @@ function CompositionRoot:invoke_descriptor(value) return self:facade():invoke_descriptor(value) end +function CompositionRoot:diagnostic_full_reset() + return self:facade():diagnostic_full_reset() +end + function M.new(options) return CompositionRoot.new(options) end diff --git a/lua/clever_f/sequence_coordinator.lua b/lua/clever_f/sequence_coordinator.lua index 6d2d31b..d8cf7f0 100644 --- a/lua/clever_f/sequence_coordinator.lua +++ b/lua/clever_f/sequence_coordinator.lua @@ -510,6 +510,22 @@ end SequenceCoordinator.Reset = SequenceCoordinator.reset +function SequenceCoordinator:diagnostic_full_reset() + local record = coordinator_records[self] + local position = domain.Position.coerce(record.host:read_cursor()) + local cleanup = record.transitions:DiagnosticFullReset( + record.host:read_window() + ) + if type(record.feedback.release_transition_cleanup) ~= "function" then + fail("FeedbackService must release diagnostic cleanup", 2) + end + record.feedback:release_transition_cleanup(cleanup) + return domain.ActionOutcome.neutral(position) +end + +SequenceCoordinator.DiagnosticFullReset = + SequenceCoordinator.diagnostic_full_reset + function SequenceCoordinator:read_explicit_invocation() local host = coordinator_records[self].host if type(host) ~= "table" diff --git a/tests/run.lua b/tests/run.lua index e00f694..d4535ef 100644 --- a/tests/run.lua +++ b/tests/run.lua @@ -8415,6 +8415,32 @@ test("ActionFacade Reset applies public cleanup and returns neutral", function() falsy(host:timers()[timer].active) end) +test("Diagnostic full reset is available only through diagnostic API", function() + local state, transitions = fresh_sequence_state() + transitions:BeginAcquisition("n", "f") + transitions:CommitAcquiredTarget("n", target("a"), 10) + transitions:CommitCommandSuccess( + "n", + domain.Position.new(1, 2), + domain.Direction.FORWARD + ) + local host = MemoryHost.new({ cursor = { line = 1, byte_column = 2 } }) + local root = composition_root.new({ host = host }) + local activation = root:activate() + + same(nil, activation.actions.DiagnosticFullReset) + local outcome = root:diagnostic_full_reset() + same(domain.ActionKind.NEUTRAL, outcome.kind) + same(nil, state:get_previous_descriptor("n")) + same(nil, state:get_previous_target("n")) + same(nil, state.last_input_context) + falsy(state.moved_forward) + falsy(state.moved_forward_initialized) + fails(function() + host:invoke_action("DiagnosticFullReset") + end, "not registered") +end) + test("Same-direction explicit coordination reads current-context state", function() local _, transitions = fresh_sequence_state() local normal_target = target("a") -- cgit v1.2.3