shellmate-cli 3.0.1__tar.gz → 3.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {shellmate_cli-3.0.1/shellmate_cli.egg-info → shellmate_cli-3.0.2}/PKG-INFO +16 -16
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/README.md +15 -15
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/pyproject.toml +1 -1
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/adapters/ble_adapter.sh +7 -3
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/adapters/powershell_adapter.ps1 +7 -3
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/adapters/powershell_predictor.ps1 +3 -0
- shellmate_cli-3.0.2/shellmate/cli/version.py +1 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/annotations.py +24 -5
- shellmate_cli-3.0.2/shellmate/ui/colors.py +109 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2/shellmate_cli.egg-info}/PKG-INFO +16 -16
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate_cli.egg-info/SOURCES.txt +3 -1
- shellmate_cli-3.0.2/tests/test_colors.py +69 -0
- shellmate_cli-3.0.1/shellmate/cli/version.py +0 -1
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/LICENSE +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/MANIFEST.in +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/setup.cfg +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/adapters/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/adapters/bash_adapter.sh +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/adapters/zsh_adapter.zsh +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/agents/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/agents/base.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/agents/chain_patterns.yaml +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/agents/command_chain.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/agents/context_gatherer.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/agents/environment.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/agents/librarian.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/agents/query.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/agents/repomix_backend.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/agents/watcher.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cache/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cache/semantic_cache.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/commands/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/commands/analyze.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/commands/config.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/commands/configure.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/commands/disable.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/commands/enable.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/commands/init.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/commands/install.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/commands/migrate.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/commands/status.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/commands/uninstall.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/main.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/cli/parser.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/completion/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/completion/bash_adapter.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/config/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/config/credentials.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/config/defaults.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/config/manager.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/config/paths.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/config/secrets.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/daemon/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/daemon/lifecycle.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/daemon/observability.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/daemon/pipeline.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/daemon/server.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/daemon/session.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/daemon/startup_ui.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/environment/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/environment/detector.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ipc/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ipc/client.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ipc/ps_client.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/orchestration/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/orchestration/analysis_graph.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/orchestration/state.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/parser/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/parser/command_parser.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/plugins/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/plugins/base.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/plugins/loader.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/providers/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/providers/base.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/providers/groq_command_guide.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/providers/groq_provider.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/providers/groq_supervisor.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/providers/openrouter_provider.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/providers/router.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/providers/validate_keys.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/providers/xai_provider.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/catastrophic.yaml +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/catastrophic_matcher.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/definitions/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/definitions/file_deletion.yaml +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/definitions/filesystem.yaml +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/definitions/network_execution.yaml +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/definitions/permissions.yaml +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/definitions/process_control.yaml +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/definitions/system_destruction.yaml +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/engine.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/sanitizer/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/sanitizer/typo_detector.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/analysis.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/banner.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/progress.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/runtime/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/runtime/console_factory.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/runtime/live_scene.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/runtime/motion_policy.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/runtime/tokens.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/scenes/__init__.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/scenes/enable.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/scenes/help.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/scenes/stages.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/scenes/status.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/ui/status.py +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate_cli.egg-info/dependency_links.txt +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate_cli.egg-info/entry_points.txt +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate_cli.egg-info/requires.txt +0 -0
- {shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate_cli.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shellmate-cli
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.2
|
|
4
4
|
Summary: Intelligent shell autocomplete with consequence preview
|
|
5
5
|
Author: ShellMate Contributors
|
|
6
6
|
License: MIT
|
|
@@ -39,7 +39,7 @@ Requires-Dist: pywinpty>=2.0.0; sys_platform == "win32" and extra == "windows-te
|
|
|
39
39
|
Requires-Dist: pyte>=0.8.1; extra == "windows-test"
|
|
40
40
|
Dynamic: license-file
|
|
41
41
|
|
|
42
|
-
#
|
|
42
|
+
# ShellMate
|
|
43
43
|
|
|
44
44
|
**A friendly safety net for your terminal.**
|
|
45
45
|
|
|
@@ -67,22 +67,22 @@ $ git push --force
|
|
|
67
67
|
|
|
68
68
|
---
|
|
69
69
|
|
|
70
|
-
##
|
|
70
|
+
## Why you'll like it
|
|
71
71
|
|
|
72
|
-
-
|
|
72
|
+
- **Stops the scary stuff.** Genuinely dangerous commands (like `rm -rf /`) are
|
|
73
73
|
caught instantly and ask you to confirm before they run.
|
|
74
|
-
-
|
|
74
|
+
- **Explains commands in plain English.** No more guessing what a command does —
|
|
75
75
|
ShellMate tells you what will happen and whether you can undo it.
|
|
76
|
-
-
|
|
76
|
+
- **Suggests safer alternatives.** When there's a gentler way to do the same thing,
|
|
77
77
|
it offers it.
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
78
|
+
- **Autocomplete that helps you learn.** Press Tab for suggestions as you type.
|
|
79
|
+
- **Stays out of your way.** Safe commands run normally — no pop-ups, no nagging.
|
|
80
|
+
- **You stay in control.** ShellMate only *shows* you things. It never executes
|
|
81
81
|
commands on its own.
|
|
82
82
|
|
|
83
83
|
---
|
|
84
84
|
|
|
85
|
-
##
|
|
85
|
+
## Get started in 3 steps
|
|
86
86
|
|
|
87
87
|
### 1. Install it
|
|
88
88
|
|
|
@@ -112,7 +112,7 @@ sm enable # starts the helper in the background
|
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
Now just **use your terminal normally.** Little notes will appear under your
|
|
115
|
-
commands as you type.
|
|
115
|
+
commands as you type.
|
|
116
116
|
|
|
117
117
|
> **What you need:** Python 3.10+, and either **Windows PowerShell** or, on
|
|
118
118
|
> **Linux/WSL**, [ble.sh](https://github.com/akinomyoga/ble.sh). ShellMate sets up
|
|
@@ -120,7 +120,7 @@ commands as you type. 🎉
|
|
|
120
120
|
|
|
121
121
|
---
|
|
122
122
|
|
|
123
|
-
##
|
|
123
|
+
## What it feels like to use
|
|
124
124
|
|
|
125
125
|
As you type, ShellMate shows a tiny note under your command:
|
|
126
126
|
|
|
@@ -139,7 +139,7 @@ many people from a bad day.
|
|
|
139
139
|
|
|
140
140
|
---
|
|
141
141
|
|
|
142
|
-
##
|
|
142
|
+
## Everyday commands
|
|
143
143
|
|
|
144
144
|
These are the only commands you need day to day:
|
|
145
145
|
|
|
@@ -154,7 +154,7 @@ These are the only commands you need day to day:
|
|
|
154
154
|
|
|
155
155
|
---
|
|
156
156
|
|
|
157
|
-
##
|
|
157
|
+
## A note on your privacy
|
|
158
158
|
|
|
159
159
|
Being honest about how it works:
|
|
160
160
|
|
|
@@ -168,7 +168,7 @@ Being honest about how it works:
|
|
|
168
168
|
|
|
169
169
|
---
|
|
170
170
|
|
|
171
|
-
##
|
|
171
|
+
## Troubleshooting
|
|
172
172
|
|
|
173
173
|
- **"I don't see any notes."** Run `sm status` to confirm the daemon is running, and
|
|
174
174
|
make sure you ran `sm enable`. On a brand-new install, open a fresh terminal so the
|
|
@@ -182,7 +182,7 @@ Being honest about how it works:
|
|
|
182
182
|
---
|
|
183
183
|
|
|
184
184
|
<details>
|
|
185
|
-
<summary
|
|
185
|
+
<summary><b>Under the hood</b> (for the curious / power users)</summary>
|
|
186
186
|
|
|
187
187
|
### How it works
|
|
188
188
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# ShellMate
|
|
2
2
|
|
|
3
3
|
**A friendly safety net for your terminal.**
|
|
4
4
|
|
|
@@ -26,22 +26,22 @@ $ git push --force
|
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
-
##
|
|
29
|
+
## Why you'll like it
|
|
30
30
|
|
|
31
|
-
-
|
|
31
|
+
- **Stops the scary stuff.** Genuinely dangerous commands (like `rm -rf /`) are
|
|
32
32
|
caught instantly and ask you to confirm before they run.
|
|
33
|
-
-
|
|
33
|
+
- **Explains commands in plain English.** No more guessing what a command does —
|
|
34
34
|
ShellMate tells you what will happen and whether you can undo it.
|
|
35
|
-
-
|
|
35
|
+
- **Suggests safer alternatives.** When there's a gentler way to do the same thing,
|
|
36
36
|
it offers it.
|
|
37
|
-
-
|
|
38
|
-
-
|
|
39
|
-
-
|
|
37
|
+
- **Autocomplete that helps you learn.** Press Tab for suggestions as you type.
|
|
38
|
+
- **Stays out of your way.** Safe commands run normally — no pop-ups, no nagging.
|
|
39
|
+
- **You stay in control.** ShellMate only *shows* you things. It never executes
|
|
40
40
|
commands on its own.
|
|
41
41
|
|
|
42
42
|
---
|
|
43
43
|
|
|
44
|
-
##
|
|
44
|
+
## Get started in 3 steps
|
|
45
45
|
|
|
46
46
|
### 1. Install it
|
|
47
47
|
|
|
@@ -71,7 +71,7 @@ sm enable # starts the helper in the background
|
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
Now just **use your terminal normally.** Little notes will appear under your
|
|
74
|
-
commands as you type.
|
|
74
|
+
commands as you type.
|
|
75
75
|
|
|
76
76
|
> **What you need:** Python 3.10+, and either **Windows PowerShell** or, on
|
|
77
77
|
> **Linux/WSL**, [ble.sh](https://github.com/akinomyoga/ble.sh). ShellMate sets up
|
|
@@ -79,7 +79,7 @@ commands as you type. 🎉
|
|
|
79
79
|
|
|
80
80
|
---
|
|
81
81
|
|
|
82
|
-
##
|
|
82
|
+
## What it feels like to use
|
|
83
83
|
|
|
84
84
|
As you type, ShellMate shows a tiny note under your command:
|
|
85
85
|
|
|
@@ -98,7 +98,7 @@ many people from a bad day.
|
|
|
98
98
|
|
|
99
99
|
---
|
|
100
100
|
|
|
101
|
-
##
|
|
101
|
+
## Everyday commands
|
|
102
102
|
|
|
103
103
|
These are the only commands you need day to day:
|
|
104
104
|
|
|
@@ -113,7 +113,7 @@ These are the only commands you need day to day:
|
|
|
113
113
|
|
|
114
114
|
---
|
|
115
115
|
|
|
116
|
-
##
|
|
116
|
+
## A note on your privacy
|
|
117
117
|
|
|
118
118
|
Being honest about how it works:
|
|
119
119
|
|
|
@@ -127,7 +127,7 @@ Being honest about how it works:
|
|
|
127
127
|
|
|
128
128
|
---
|
|
129
129
|
|
|
130
|
-
##
|
|
130
|
+
## Troubleshooting
|
|
131
131
|
|
|
132
132
|
- **"I don't see any notes."** Run `sm status` to confirm the daemon is running, and
|
|
133
133
|
make sure you ran `sm enable`. On a brand-new install, open a fresh terminal so the
|
|
@@ -141,7 +141,7 @@ Being honest about how it works:
|
|
|
141
141
|
---
|
|
142
142
|
|
|
143
143
|
<details>
|
|
144
|
-
<summary
|
|
144
|
+
<summary><b>Under the hood</b> (for the curious / power users)</summary>
|
|
145
145
|
|
|
146
146
|
### How it works
|
|
147
147
|
|
|
@@ -107,6 +107,8 @@ print(json.dumps({
|
|
|
107
107
|
suggested_fix=$(python3 -c "import sys,json; d=json.loads(sys.argv[1]); print(d.get('suggested_fix',''))" "$raw" 2>/dev/null)
|
|
108
108
|
severity=$(python3 -c "import sys,json; d=json.loads(sys.argv[1]); print(d.get('severity','MEDIUM'))" "$raw" 2>/dev/null)
|
|
109
109
|
|
|
110
|
+
# Color scheme mirrors shellmate/ui/colors.py: caution=91 red, warning=93
|
|
111
|
+
# yellow, suggestion/safe=92 green.
|
|
110
112
|
local color="\e[93m"
|
|
111
113
|
[[ "$severity" == "HIGH" || "$severity" == "CRITICAL" || "$severity" == "blocking" ]] && color="\e[91m"
|
|
112
114
|
[[ "$severity" == "SAFE" || "$severity" == "LOW" ]] && color="\e[92m"
|
|
@@ -114,7 +116,8 @@ print(json.dumps({
|
|
|
114
116
|
local line1 line2 line3=""
|
|
115
117
|
line1="${color} → ${what_happens}\e[m"
|
|
116
118
|
line2="${color} → Reversible: ${reversible} | ${scope}\e[m"
|
|
117
|
-
|
|
119
|
+
# A suggested fix is a suggestion -> green (92), not dim.
|
|
120
|
+
[[ -n "$suggested_fix" ]] && line3="\e[92m → Safe alt: ${suggested_fix}\e[m"
|
|
118
121
|
|
|
119
122
|
# Gate HIGH/CRITICAL on second Enter
|
|
120
123
|
if [[ "$severity" == "HIGH" || "$severity" == "CRITICAL" || "$severity" == "blocking" ]]; then
|
|
@@ -328,10 +331,11 @@ print('\n'.join(get_completions(sys.argv[1])))
|
|
|
328
331
|
_SHELLMATE_TAB_CMD="$first"
|
|
329
332
|
_SHELLMATE_TAB_STATE="suggested"
|
|
330
333
|
local suffix="${first#$line}"
|
|
334
|
+
# Autocomplete ghost-text is a suggestion -> green (92), per shellmate/ui/colors.py.
|
|
331
335
|
if [[ -n "$suffix" ]] && type ble/canvas/put.draw &>/dev/null; then
|
|
332
|
-
ble/canvas/put.draw "\e[
|
|
336
|
+
ble/canvas/put.draw "\e[92m${suffix}\e[m"
|
|
333
337
|
elif [[ -n "$suffix" ]]; then
|
|
334
|
-
printf '\e[
|
|
338
|
+
printf '\e[92m%s\e[m' "$suffix" >/dev/tty
|
|
335
339
|
printf '\e[%dD' "${#suffix}" >/dev/tty
|
|
336
340
|
fi
|
|
337
341
|
fi
|
|
@@ -70,11 +70,13 @@ function Show-ShellMateConsequence {
|
|
|
70
70
|
elseif ($Severity -in @("SAFE","LOW")) { "${ESC}[92m" } `
|
|
71
71
|
else { "${ESC}[93m" }
|
|
72
72
|
$reset = "${ESC}[0m"
|
|
73
|
-
|
|
73
|
+
# Color scheme mirrors shellmate/ui/colors.py: caution=91 red, warning=93
|
|
74
|
+
# yellow, suggestion/safe=92 green. A suggested fix is a suggestion -> green.
|
|
75
|
+
$green = "${ESC}[92m"
|
|
74
76
|
|
|
75
77
|
$line1 = "${color} -> ${WhatHappens}${reset}"
|
|
76
78
|
$line2 = "${color} -> Reversible: ${Reversible} | ${Scope}${reset}"
|
|
77
|
-
$line3 = if ($SuggestedFix) { "${
|
|
79
|
+
$line3 = if ($SuggestedFix) { "${green} -> Safe alt: ${SuggestedFix}${reset}" } else { "" }
|
|
78
80
|
|
|
79
81
|
# Save cursor, write 3 lines below prompt, restore
|
|
80
82
|
[Console]::Write("${ESC}[s")
|
|
@@ -368,7 +370,9 @@ if (-not $script:ShellMatePredictorRegistered) {
|
|
|
368
370
|
$ESC = [char]27
|
|
369
371
|
$suffix = ([string]$suggestion).Substring([Math]::Min($prefix.Length, ([string]$suggestion).Length))
|
|
370
372
|
if ($suffix) {
|
|
371
|
-
|
|
373
|
+
# Autocomplete ghost-text is a suggestion -> green (92),
|
|
374
|
+
# matching shellmate/ui/colors.py.
|
|
375
|
+
[Console]::Write("${ESC}[92m${suffix}${ESC}[0m")
|
|
372
376
|
[Console]::Write("${ESC}[$($suffix.Length)D")
|
|
373
377
|
}
|
|
374
378
|
return
|
|
@@ -89,6 +89,9 @@ if ($py -and (Test-Path $client)) {
|
|
|
89
89
|
$predictor
|
|
90
90
|
)
|
|
91
91
|
Set-PSReadLineOption -PredictionSource Plugin -PredictionViewStyle InlineView -ErrorAction SilentlyContinue
|
|
92
|
+
# Render predictions green — they are suggestions (mirrors shellmate/ui/colors.py).
|
|
93
|
+
$smEsc = [char]27
|
|
94
|
+
Set-PSReadLineOption -Colors @{ InlinePrediction = "${smEsc}[92m" } -ErrorAction SilentlyContinue
|
|
92
95
|
$script:ShellMatePredictorRegistered = $true
|
|
93
96
|
} catch {
|
|
94
97
|
Write-Verbose "ShellMate: predictor registration failed: $_"
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VERSION = "3.0.2"
|
|
@@ -4,6 +4,8 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from typing import Any, Dict, Optional
|
|
6
6
|
|
|
7
|
+
from shellmate.ui import colors
|
|
8
|
+
|
|
7
9
|
# Emoji mappings for risk levels (short inline / Unix terminals)
|
|
8
10
|
RISK_ICONS = {
|
|
9
11
|
"SAFE": "✅",
|
|
@@ -105,6 +107,7 @@ def format_consequence_annotation(
|
|
|
105
107
|
risk: str = "MEDIUM",
|
|
106
108
|
*,
|
|
107
109
|
ascii_safe: bool = False,
|
|
110
|
+
color: bool = False,
|
|
108
111
|
) -> str:
|
|
109
112
|
"""Format annotation using structured consequence preview + badges."""
|
|
110
113
|
env_context = env_context or {}
|
|
@@ -137,7 +140,12 @@ def format_consequence_annotation(
|
|
|
137
140
|
if not consequence.get("reversible", True):
|
|
138
141
|
parts.append("[IRREVERSIBLE]")
|
|
139
142
|
|
|
140
|
-
|
|
143
|
+
if len(parts) <= 1:
|
|
144
|
+
return ""
|
|
145
|
+
text = " ".join(parts)
|
|
146
|
+
# Consequence severity ("blocking"/"warning"/"info") or risk level both map
|
|
147
|
+
# through SEVERITY_ROLE -> caution=red / warning=yellow / safe=green.
|
|
148
|
+
return colors.by_severity(text, severity if severity in colors.SEVERITY_ROLE else risk) if color else text
|
|
141
149
|
|
|
142
150
|
|
|
143
151
|
def format_legacy_pipeline_annotation(
|
|
@@ -146,6 +154,7 @@ def format_legacy_pipeline_annotation(
|
|
|
146
154
|
chain_patterns: Optional[Dict[str, Any]] = None,
|
|
147
155
|
*,
|
|
148
156
|
ascii_safe: bool = False,
|
|
157
|
+
color: bool = False,
|
|
149
158
|
) -> str:
|
|
150
159
|
"""Format annotation from pipeline result without consequence_preview."""
|
|
151
160
|
env_context = env_context or {}
|
|
@@ -186,7 +195,10 @@ def format_legacy_pipeline_annotation(
|
|
|
186
195
|
msg = msg[:37] + "..."
|
|
187
196
|
parts.append(msg)
|
|
188
197
|
|
|
189
|
-
|
|
198
|
+
if len(parts) <= 1:
|
|
199
|
+
return ""
|
|
200
|
+
text = " ".join(parts)
|
|
201
|
+
return colors.by_severity(text, risk) if color else text
|
|
190
202
|
|
|
191
203
|
|
|
192
204
|
def format_pipeline_annotation(
|
|
@@ -195,6 +207,7 @@ def format_pipeline_annotation(
|
|
|
195
207
|
chain_patterns: Optional[Dict[str, Any]] = None,
|
|
196
208
|
*,
|
|
197
209
|
ascii_safe: bool = False,
|
|
210
|
+
color: bool = False,
|
|
198
211
|
) -> str:
|
|
199
212
|
"""Prefer consequence_preview; fall back to legacy pipeline formatting."""
|
|
200
213
|
consequence = risk_result.get("consequence_preview") or {}
|
|
@@ -205,13 +218,16 @@ def format_pipeline_annotation(
|
|
|
205
218
|
chain_patterns,
|
|
206
219
|
risk_result.get("risk", "MEDIUM"),
|
|
207
220
|
ascii_safe=ascii_safe,
|
|
221
|
+
color=color,
|
|
208
222
|
)
|
|
209
223
|
return format_legacy_pipeline_annotation(
|
|
210
|
-
risk_result, env_context, chain_patterns, ascii_safe=ascii_safe
|
|
224
|
+
risk_result, env_context, chain_patterns, ascii_safe=ascii_safe, color=color
|
|
211
225
|
)
|
|
212
226
|
|
|
213
227
|
|
|
214
|
-
def format_cached_annotation(
|
|
228
|
+
def format_cached_annotation(
|
|
229
|
+
cached_result: Dict[str, Any], *, ascii_safe: bool = False, color: bool = False
|
|
230
|
+
) -> str:
|
|
215
231
|
"""Format a simple annotation from a cache hit payload."""
|
|
216
232
|
msg = cached_result.get("explanation", "") or ""
|
|
217
233
|
risk = cached_result.get("risk", "MEDIUM")
|
|
@@ -229,4 +245,7 @@ def format_cached_annotation(cached_result: Dict[str, Any], *, ascii_safe: bool
|
|
|
229
245
|
|
|
230
246
|
if len(msg) > 50:
|
|
231
247
|
msg = msg[:47] + "..."
|
|
232
|
-
|
|
248
|
+
if not msg:
|
|
249
|
+
return ""
|
|
250
|
+
text = f"{icon} {msg}"
|
|
251
|
+
return colors.by_severity(text, risk) if color else text
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"""Semantic terminal colors for suggestions and cautions.
|
|
2
|
+
|
|
3
|
+
Single source of truth for ShellMate's inline color scheme so every surface
|
|
4
|
+
agrees on what red / yellow / green mean:
|
|
5
|
+
|
|
6
|
+
caution -> red (dangerous: HIGH / CRITICAL / blocking)
|
|
7
|
+
warning -> yellow (proceed with care: MEDIUM)
|
|
8
|
+
suggestion -> green (a safer alternative / "Safe alt")
|
|
9
|
+
safe -> green (SAFE / LOW — nothing to worry about)
|
|
10
|
+
info -> cyan (neutral information)
|
|
11
|
+
dim -> grey (de-emphasized)
|
|
12
|
+
|
|
13
|
+
The shell adapters (``powershell_adapter.ps1`` / ``ble_adapter.sh``) mirror these
|
|
14
|
+
SGR codes directly since they render ANSI themselves; keep them in sync with
|
|
15
|
+
``ROLE_SGR`` below. Python-side rendering should use this module.
|
|
16
|
+
|
|
17
|
+
Honors the https://no-color.org convention: if the ``NO_COLOR`` environment
|
|
18
|
+
variable is set (to anything), colorizing becomes a no-op.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import os
|
|
24
|
+
from typing import Optional
|
|
25
|
+
|
|
26
|
+
ESC = "\033"
|
|
27
|
+
RESET = f"{ESC}[0m"
|
|
28
|
+
|
|
29
|
+
# Role -> SGR (Select Graphic Rendition) code. Bright variants read well on both
|
|
30
|
+
# dark and light terminals. Mirror these in the shell adapters.
|
|
31
|
+
ROLE_SGR = {
|
|
32
|
+
"caution": 91, # bright red
|
|
33
|
+
"warning": 93, # bright yellow
|
|
34
|
+
"suggestion": 92, # bright green
|
|
35
|
+
"safe": 92, # bright green
|
|
36
|
+
"info": 96, # bright cyan
|
|
37
|
+
"dim": 90, # grey
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# Role -> rich style name, for Console/Text rendering in the CLI scenes.
|
|
41
|
+
ROLE_RICH = {
|
|
42
|
+
"caution": "bold red",
|
|
43
|
+
"warning": "yellow",
|
|
44
|
+
"suggestion": "green",
|
|
45
|
+
"safe": "green",
|
|
46
|
+
"info": "cyan",
|
|
47
|
+
"dim": "bright_black",
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
# Risk/severity label -> semantic role.
|
|
51
|
+
SEVERITY_ROLE = {
|
|
52
|
+
"CRITICAL": "caution",
|
|
53
|
+
"HIGH": "caution",
|
|
54
|
+
"blocking": "caution",
|
|
55
|
+
"MEDIUM": "warning",
|
|
56
|
+
"warning": "warning",
|
|
57
|
+
"LOW": "safe",
|
|
58
|
+
"SAFE": "safe",
|
|
59
|
+
"info": "info",
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def color_enabled(no_color: Optional[bool] = None) -> bool:
|
|
64
|
+
"""Whether color should be emitted.
|
|
65
|
+
|
|
66
|
+
Explicit ``no_color`` wins; otherwise honor the ``NO_COLOR`` env var.
|
|
67
|
+
"""
|
|
68
|
+
if no_color is not None:
|
|
69
|
+
return not no_color
|
|
70
|
+
return os.environ.get("NO_COLOR") is None
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def role_for_severity(severity: Optional[str]) -> str:
|
|
74
|
+
"""Map a risk/severity label to a semantic role (defaults to ``warning``)."""
|
|
75
|
+
return SEVERITY_ROLE.get(severity or "", "warning")
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def colorize(text: str, role: str, *, no_color: Optional[bool] = None) -> str:
|
|
79
|
+
"""Wrap ``text`` in the ANSI color for ``role``.
|
|
80
|
+
|
|
81
|
+
Returns ``text`` unchanged when color is disabled, the text is empty, or the
|
|
82
|
+
role is unknown — so it is always safe to call.
|
|
83
|
+
"""
|
|
84
|
+
if not text or not color_enabled(no_color):
|
|
85
|
+
return text
|
|
86
|
+
sgr = ROLE_SGR.get(role)
|
|
87
|
+
if sgr is None:
|
|
88
|
+
return text
|
|
89
|
+
return f"{ESC}[{sgr}m{text}{RESET}"
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def caution(text: str, *, no_color: Optional[bool] = None) -> str:
|
|
93
|
+
"""Red — a dangerous command or consequence."""
|
|
94
|
+
return colorize(text, "caution", no_color=no_color)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def warning(text: str, *, no_color: Optional[bool] = None) -> str:
|
|
98
|
+
"""Yellow — proceed with care."""
|
|
99
|
+
return colorize(text, "warning", no_color=no_color)
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
def suggestion(text: str, *, no_color: Optional[bool] = None) -> str:
|
|
103
|
+
"""Green — a safer alternative to offer."""
|
|
104
|
+
return colorize(text, "suggestion", no_color=no_color)
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def by_severity(text: str, severity: Optional[str], *, no_color: Optional[bool] = None) -> str:
|
|
108
|
+
"""Colorize ``text`` using the role implied by a risk/severity label."""
|
|
109
|
+
return colorize(text, role_for_severity(severity), no_color=no_color)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shellmate-cli
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.2
|
|
4
4
|
Summary: Intelligent shell autocomplete with consequence preview
|
|
5
5
|
Author: ShellMate Contributors
|
|
6
6
|
License: MIT
|
|
@@ -39,7 +39,7 @@ Requires-Dist: pywinpty>=2.0.0; sys_platform == "win32" and extra == "windows-te
|
|
|
39
39
|
Requires-Dist: pyte>=0.8.1; extra == "windows-test"
|
|
40
40
|
Dynamic: license-file
|
|
41
41
|
|
|
42
|
-
#
|
|
42
|
+
# ShellMate
|
|
43
43
|
|
|
44
44
|
**A friendly safety net for your terminal.**
|
|
45
45
|
|
|
@@ -67,22 +67,22 @@ $ git push --force
|
|
|
67
67
|
|
|
68
68
|
---
|
|
69
69
|
|
|
70
|
-
##
|
|
70
|
+
## Why you'll like it
|
|
71
71
|
|
|
72
|
-
-
|
|
72
|
+
- **Stops the scary stuff.** Genuinely dangerous commands (like `rm -rf /`) are
|
|
73
73
|
caught instantly and ask you to confirm before they run.
|
|
74
|
-
-
|
|
74
|
+
- **Explains commands in plain English.** No more guessing what a command does —
|
|
75
75
|
ShellMate tells you what will happen and whether you can undo it.
|
|
76
|
-
-
|
|
76
|
+
- **Suggests safer alternatives.** When there's a gentler way to do the same thing,
|
|
77
77
|
it offers it.
|
|
78
|
-
-
|
|
79
|
-
-
|
|
80
|
-
-
|
|
78
|
+
- **Autocomplete that helps you learn.** Press Tab for suggestions as you type.
|
|
79
|
+
- **Stays out of your way.** Safe commands run normally — no pop-ups, no nagging.
|
|
80
|
+
- **You stay in control.** ShellMate only *shows* you things. It never executes
|
|
81
81
|
commands on its own.
|
|
82
82
|
|
|
83
83
|
---
|
|
84
84
|
|
|
85
|
-
##
|
|
85
|
+
## Get started in 3 steps
|
|
86
86
|
|
|
87
87
|
### 1. Install it
|
|
88
88
|
|
|
@@ -112,7 +112,7 @@ sm enable # starts the helper in the background
|
|
|
112
112
|
```
|
|
113
113
|
|
|
114
114
|
Now just **use your terminal normally.** Little notes will appear under your
|
|
115
|
-
commands as you type.
|
|
115
|
+
commands as you type.
|
|
116
116
|
|
|
117
117
|
> **What you need:** Python 3.10+, and either **Windows PowerShell** or, on
|
|
118
118
|
> **Linux/WSL**, [ble.sh](https://github.com/akinomyoga/ble.sh). ShellMate sets up
|
|
@@ -120,7 +120,7 @@ commands as you type. 🎉
|
|
|
120
120
|
|
|
121
121
|
---
|
|
122
122
|
|
|
123
|
-
##
|
|
123
|
+
## What it feels like to use
|
|
124
124
|
|
|
125
125
|
As you type, ShellMate shows a tiny note under your command:
|
|
126
126
|
|
|
@@ -139,7 +139,7 @@ many people from a bad day.
|
|
|
139
139
|
|
|
140
140
|
---
|
|
141
141
|
|
|
142
|
-
##
|
|
142
|
+
## Everyday commands
|
|
143
143
|
|
|
144
144
|
These are the only commands you need day to day:
|
|
145
145
|
|
|
@@ -154,7 +154,7 @@ These are the only commands you need day to day:
|
|
|
154
154
|
|
|
155
155
|
---
|
|
156
156
|
|
|
157
|
-
##
|
|
157
|
+
## A note on your privacy
|
|
158
158
|
|
|
159
159
|
Being honest about how it works:
|
|
160
160
|
|
|
@@ -168,7 +168,7 @@ Being honest about how it works:
|
|
|
168
168
|
|
|
169
169
|
---
|
|
170
170
|
|
|
171
|
-
##
|
|
171
|
+
## Troubleshooting
|
|
172
172
|
|
|
173
173
|
- **"I don't see any notes."** Run `sm status` to confirm the daemon is running, and
|
|
174
174
|
make sure you ran `sm enable`. On a brand-new install, open a fresh terminal so the
|
|
@@ -182,7 +182,7 @@ Being honest about how it works:
|
|
|
182
182
|
---
|
|
183
183
|
|
|
184
184
|
<details>
|
|
185
|
-
<summary
|
|
185
|
+
<summary><b>Under the hood</b> (for the curious / power users)</summary>
|
|
186
186
|
|
|
187
187
|
### How it works
|
|
188
188
|
|
|
@@ -90,6 +90,7 @@ shellmate/ui/__init__.py
|
|
|
90
90
|
shellmate/ui/analysis.py
|
|
91
91
|
shellmate/ui/annotations.py
|
|
92
92
|
shellmate/ui/banner.py
|
|
93
|
+
shellmate/ui/colors.py
|
|
93
94
|
shellmate/ui/progress.py
|
|
94
95
|
shellmate/ui/status.py
|
|
95
96
|
shellmate/ui/runtime/__init__.py
|
|
@@ -107,4 +108,5 @@ shellmate_cli.egg-info/SOURCES.txt
|
|
|
107
108
|
shellmate_cli.egg-info/dependency_links.txt
|
|
108
109
|
shellmate_cli.egg-info/entry_points.txt
|
|
109
110
|
shellmate_cli.egg-info/requires.txt
|
|
110
|
-
shellmate_cli.egg-info/top_level.txt
|
|
111
|
+
shellmate_cli.egg-info/top_level.txt
|
|
112
|
+
tests/test_colors.py
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Tests for the semantic color module and its annotation integration."""
|
|
2
|
+
|
|
3
|
+
import importlib
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from shellmate.ui import colors
|
|
8
|
+
from shellmate.ui import annotations
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def test_roles_map_to_expected_ansi():
|
|
12
|
+
assert colors.ROLE_SGR["caution"] == 91 # red
|
|
13
|
+
assert colors.ROLE_SGR["warning"] == 93 # yellow
|
|
14
|
+
assert colors.ROLE_SGR["suggestion"] == 92 # green
|
|
15
|
+
assert colors.ROLE_SGR["safe"] == 92 # green
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@pytest.mark.parametrize("sev,role", [
|
|
19
|
+
("CRITICAL", "caution"), ("HIGH", "caution"), ("blocking", "caution"),
|
|
20
|
+
("MEDIUM", "warning"), ("LOW", "safe"), ("SAFE", "safe"),
|
|
21
|
+
("", "warning"), (None, "warning"),
|
|
22
|
+
])
|
|
23
|
+
def test_severity_role_mapping(sev, role):
|
|
24
|
+
assert colors.role_for_severity(sev) == role
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_colorize_wraps_and_resets():
|
|
28
|
+
out = colors.suggestion("Safe alt: git push --force-with-lease", no_color=False)
|
|
29
|
+
assert out.startswith("\033[92m")
|
|
30
|
+
assert out.endswith("\033[0m")
|
|
31
|
+
assert "Safe alt" in out
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def test_caution_is_red_warning_is_yellow():
|
|
35
|
+
assert colors.caution("boom", no_color=False).startswith("\033[91m")
|
|
36
|
+
assert colors.warning("careful", no_color=False).startswith("\033[91m") is False
|
|
37
|
+
assert colors.warning("careful", no_color=False).startswith("\033[93m")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_no_color_param_disables():
|
|
41
|
+
assert colors.caution("x", no_color=True) == "x"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_empty_and_unknown_role_passthrough():
|
|
45
|
+
assert colors.colorize("", "caution", no_color=False) == ""
|
|
46
|
+
assert colors.colorize("hi", "no-such-role", no_color=False) == "hi"
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_no_color_env(monkeypatch):
|
|
50
|
+
monkeypatch.setenv("NO_COLOR", "1")
|
|
51
|
+
assert colors.color_enabled() is False
|
|
52
|
+
assert colors.suggestion("x") == "x"
|
|
53
|
+
monkeypatch.delenv("NO_COLOR", raising=False)
|
|
54
|
+
assert colors.color_enabled() is True
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def test_annotation_color_flag_colorizes_suggestion_path_green():
|
|
58
|
+
# A low/safe consequence should carry the green (92) role when color=True.
|
|
59
|
+
consequence = {"what_happens": "Lists files", "reversible": True, "severity": "info"}
|
|
60
|
+
plain = annotations.format_consequence_annotation(consequence, risk="SAFE")
|
|
61
|
+
colored = annotations.format_consequence_annotation(consequence, risk="SAFE", color=True)
|
|
62
|
+
assert "\033[" not in plain # default path unchanged (adapters color)
|
|
63
|
+
assert colored.startswith("\033[") and colored.endswith("\033[0m")
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_annotation_default_is_plain_for_adapters():
|
|
67
|
+
# Adapters add their own ANSI, so the default (color=False) must stay plain.
|
|
68
|
+
result = {"risk": "HIGH", "risk_analysis": {"reason": "rewrites history"}}
|
|
69
|
+
assert "\033[" not in annotations.format_pipeline_annotation(result)
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
VERSION = "3.0.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/definitions/network_execution.yaml
RENAMED
|
File without changes
|
|
File without changes
|
{shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/definitions/process_control.yaml
RENAMED
|
File without changes
|
{shellmate_cli-3.0.1 → shellmate_cli-3.0.2}/shellmate/rules/definitions/system_destruction.yaml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|