Files
cleveragents-core/features/repl_input_modes.feature
T
aditya d9e51d98f8 fix(tui,cli,tests): harden persona/input modes and stabilize parallel test execution
- Add shell safety controls for REPL/TUI (`looks_dangerous`, confirmation gate, timeout handling, and env-based shell disable guard).
- Secure persona workflows with strict name/path validation, safe import/export resolution, atomic+locked registry writes, and malformed YAML resilience.
- Unify persona models and wiring by reusing canonical TUI schema/registry, adding DI providers, and lazy-loading TUI exports to avoid circular imports.
- Improve reference discovery with ignored-directory filtering, symlink-safe walking, and TTL caching for CLI/TUI reference catalogs.
- Expand Behave/Robot coverage for safety/error paths and parallel-isolation behavior; add shared `features/mocks/fake_repl_input.py` helper.
- Fix parallel-run flakiness via deterministic cleanup/reload patterns and watchdog polling fallback when inotify limits are reached.

ISSUES CLOSED: #695
2026-03-18 10:09:06 +00:00

143 lines
7.2 KiB
Gherkin

Feature: REPL input modes and persona controls
The interactive REPL supports slash commands, shell passthrough, and
inline @ reference expansion.
Scenario: Slash persona commands create and activate personas
Given a temporary REPL config directory
When I run the REPL with input lines
| line |
| /persona create dev --actor local/mock-default |
| /persona list |
| /persona set dev |
| /persona list |
Then the REPL mode output should contain "Created persona: dev"
And the REPL mode output should contain "Active persona: dev"
And the REPL mode output should contain "dev -> local/mock-default"
Scenario: Shell mode runs host shell commands
Given a temporary REPL config directory
When I run the REPL with input lines
| line |
| !echo hello |
Then the REPL mode output should contain "hello"
Scenario: Shell mode blocks dangerous commands without confirmation
Given a temporary REPL config directory
When I run the REPL with input lines
| line |
| !rm -rf / |
| n |
Then the REPL mode output should contain "Blocked dangerous shell command."
Scenario: @ references are expanded with canonical category prefixes
Given a deterministic REPL reference catalog fixture
When I expand REPL references for "info @README.md"
Then the expanded REPL line should contain "@file:README.md"
Scenario: Slash persona shorthand switches active persona
Given a temporary REPL config directory
When I run the REPL with input lines
| line |
| /persona create reviewer --actor local/mock-default |
| /persona reviewer |
Then the REPL mode output should contain "Active persona: reviewer"
Scenario: CLI persona model rejects ANSI/control characters in names
When I validate CLI persona name "bad\\x1bname"
Then CLI persona validation should fail with "path/control"
Scenario: CLI persona model preserves color field
When I validate CLI persona payload with color "red"
Then CLI persona color should be "red"
Scenario: Persona export import and delete workflow
Given a temporary REPL config directory
And a temporary persona export path
When I run the REPL with input lines
| line |
| /persona create dev --actor local/mock-default |
| /persona export dev {export_path} |
| /persona delete dev |
| /persona import {export_path} |
| /persona set dev |
Then the REPL mode output should contain "Exported persona:"
And the REPL mode output should contain "Deleted persona: dev"
And the REPL mode output should contain "Imported persona: dev"
And the REPL mode output should contain "Active persona: dev"
Scenario: Persona create rejects path traversal names
Given a temporary REPL config directory
When I run the REPL with input lines
| line |
| /persona create ../../etc/cron.d/evil --actor local/mock-default |
Then the REPL mode output should contain "name must not contain path/control separators"
Scenario: Persona export rejects absolute path targets
Given a temporary REPL config directory
And an absolute persona export path
When I run the REPL with input lines
| line |
| /persona create dev --actor local/mock-default |
| /persona export dev {export_path} |
Then the REPL mode output should contain "Export path must be relative to current working directory"
Scenario: Persona export rejects parent directory escape
Given a temporary REPL config directory
When I run the REPL with input lines
| line |
| /persona create dev --actor local/mock-default |
| /persona export dev ../outside.yaml |
Then the REPL mode output should contain "Export path must stay within working directory"
Scenario: Persona import rejects absolute path targets
Given a temporary REPL config directory
And an absolute persona import file path
When I run the REPL with input lines
| line |
| /persona import {absolute_import_path} |
Then the REPL mode output should contain "Import path must be relative to current working directory"
Scenario: Persona binding is independent per REPL session
Given a temporary REPL config directory
When I run the REPL with input lines
| line |
| /persona create dev --actor local/mock-default |
| /persona create reviewer --actor local/mock-default |
| /session new work |
| /session switch work |
| /persona set dev |
| /session switch default |
| /persona set reviewer |
| /session list |
Then the REPL mode output should contain "work (persona=dev)"
And the REPL mode output should contain "default (persona=reviewer)"
Scenario: Deleting persona resets all sessions using it
Given a temporary REPL config directory
When I run the REPL with input lines
| line |
| /persona create dev --actor local/mock-default |
| /session new work |
| /session switch work |
| /persona set dev |
| /session switch default |
| /persona set dev |
| /persona delete dev |
| /session list |
Then the REPL mode output should contain "work (persona=default)"
And the REPL mode output should contain "default (persona=default)"
Scenario: Slash persona commands surface validation and usage errors
Given a temporary REPL config directory
And an invalid persona import file path
When I run the REPL with input lines
| line |
| /persona set missing |
| /persona create dev |
| /persona delete default |
| /persona import {invalid_import_path} |
Then the REPL mode output should contain "Persona not found: missing"
And the REPL mode output should contain "Usage: /persona create <name> --actor <namespace/name>"
And the REPL mode output should contain "Cannot delete default persona."
And the REPL mode output should contain "Invalid persona YAML."