features/lsp_actor_service_wiring.feature scenarios "handles multiple
LSP servers" and "tool specs have correct schema": add an explicit
`| CAPABILITIES |` header to the capability tables. Behave treats the
first table row as the heading, so `| DIAGNOSTICS |` (the only row)
was being silently dropped, leaving the registered server with zero
capabilities and the adapter generating no tool specs.
features/steps/lsp_actor_service_steps.py: strip surrounding double
quotes from each entry in the comma-separated `fields` placeholder of
the `requires "..."` Then step so a feature line like `requires
"file_path", "line", "column"` resolves to the three unquoted field
names rather than `file_path"`, `"line"`, `"column"`.
features/steps/tui_persona_cycle_steps.py: include the surrounding
double quotes in the step pattern for "the registry last persona
should be set to ..." so the feature literal `"p2"` matches as `p2`
(without the quotes the placeholder captured `"p2"` and the equality
check against the registry value failed).
src/cleveragents/tui/persona/registry.py: reject absolute paths from
`resolve_export_path` and `resolve_import_path` with the messages the
"Persona export/import rejects absolute path targets" scenarios in
features/repl_input_modes.feature expect. The previous behaviour
silently accepted absolute paths, defeating the working-directory
sandboxing intent.
ISSUES CLOSED: #5663
LspRuntime.__init__ and LspActorService.__init__ used ``x or Y()`` to
default the registry/runtime kwargs. LspRegistry defines __len__, so an
empty instance is falsy, and the OR silently discarded a caller-supplied
empty registry — making the constructor parameter unusable. Replace with
explicit ``is None`` checks so callers can inject collaborators at
construction time. The previous workaround in lsp_actor_service_steps.py
reached into ``service._runtime._registry`` to compensate; the steps now
inject via the public LspRuntime + LspActorService constructors, no
private-attribute access.
Also deconflict three behave AmbiguousStep collisions in the bundled TUI
persona work that prevented behave-parallel from registering any step
definitions (the unit_tests gate was aborting at load time):
* tui_persona_cycle_steps.py duplicated the registry-setup and active-
persona steps already defined in tui_persona_system_steps.py — drop
the duplicates and let the system file own them.
* tui_persona_state_coverage_steps.py / .feature shared
``the registry last persona should be set to "X"`` with
tui_persona_cycle_steps.py while asserting on a different mock —
rename the coverage step to ``the mock registry set_last_persona
should have been called with "X"``.
* lsp_actor_service_steps.py registered the "actor bindings are
activated" step under @when only; the deactivate scenario uses it
after a ``Given/And`` chain, so behave inherited Given and the step
was undefined. Register the same handler under both @given and
@when.
Reformat three files that ``ruff format --check`` flagged
(tui_persona_cycle_steps.py, tui_persona_state_coverage_steps.py via
the rename, tui/persona/state.py) so the lint gate goes green.
ISSUES CLOSED: #5663
- Replace standard logging with structlog in LspActorService to fix typecheck errors (structlog uses keyword arguments for structured logging, not positional like stdlib logging)
- Fix LspServerConfig command field: use str not list[str] in test step definitions
- Add _MockLifecycleManager stub to prevent real LSP server process spawning during unit tests
- Rename duplicate step "a clean LSP registry" to "a clean LSP actor service registry" to avoid conflict with lsp_registry_steps.py
- Fix B904 lint error: raise ValueError from None in except clause
- Add LspActorService to manage LSP server lifecycle for actors
- Implement activate_actor_bindings() to start servers and generate tool specs
- Implement deactivate_actor_bindings() to release server references
- Add BDD tests for LSP actor service wiring
- Add step definitions for LSP actor service tests
Fixes#5663