forked from cleveragents/cleveragents-core
d9e51d98f8
- 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
143 lines
7.2 KiB
Gherkin
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."
|