flyshell 1.0.0__py3-none-any.whl
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.
- flyshell/__init__.py +7 -0
- flyshell/abstract/__init__.py +0 -0
- flyshell/abstract/base_cmd.py +26 -0
- flyshell/abstract/base_plugin.py +75 -0
- flyshell/abstract/parent_cmd.py +59 -0
- flyshell/builtin/__init__.py +0 -0
- flyshell/builtin/fs.py +161 -0
- flyshell/builtin/system.py +124 -0
- flyshell/builtin/utils.py +113 -0
- flyshell/core/__init__.py +0 -0
- flyshell/core/auth.py +122 -0
- flyshell/core/console.py +64 -0
- flyshell/core/data.py +234 -0
- flyshell/core/directory.py +242 -0
- flyshell/core/loader.py +90 -0
- flyshell/main.py +115 -0
- flyshell-1.0.0.dist-info/METADATA +208 -0
- flyshell-1.0.0.dist-info/RECORD +22 -0
- flyshell-1.0.0.dist-info/WHEEL +5 -0
- flyshell-1.0.0.dist-info/entry_points.txt +2 -0
- flyshell-1.0.0.dist-info/licenses/LICENSE +21 -0
- flyshell-1.0.0.dist-info/top_level.txt +1 -0
flyshell/core/loader.py
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# src\flyshell\core\loader.py
|
|
2
|
+
|
|
3
|
+
from flyshell.abstract.base_plugin import BasePlugin
|
|
4
|
+
from flyshell.core import data
|
|
5
|
+
from flyshell.core.directory import COMMAND_REGISTRY
|
|
6
|
+
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
import importlib.util
|
|
9
|
+
import inspect
|
|
10
|
+
import os
|
|
11
|
+
import sys
|
|
12
|
+
|
|
13
|
+
RESERVED_NAMES = set(COMMAND_REGISTRY.keys())
|
|
14
|
+
|
|
15
|
+
def scan_plugins(plugin_folder=None):
|
|
16
|
+
folder = Path(plugin_folder) if plugin_folder else data.USER_PLUGIN_DIR
|
|
17
|
+
data.PLUGINS.clear()
|
|
18
|
+
if not folder.exists():
|
|
19
|
+
folder.mkdir(parents=True, exist_ok=True)
|
|
20
|
+
print("\nNo plugins found.")
|
|
21
|
+
return
|
|
22
|
+
folder_str = str(folder)
|
|
23
|
+
if folder_str not in sys.path:
|
|
24
|
+
sys.path.insert(0, folder_str)
|
|
25
|
+
candidates = {}
|
|
26
|
+
for item in folder.iterdir():
|
|
27
|
+
file_path = None
|
|
28
|
+
plugin_name = None
|
|
29
|
+
if item.is_file() and item.suffix == ".py" and not item.name.startswith("_"):
|
|
30
|
+
file_path = item
|
|
31
|
+
plugin_name = item.stem
|
|
32
|
+
elif item.is_dir() and not item.name.startswith((".", "_")):
|
|
33
|
+
entry = item / "plugin.py"
|
|
34
|
+
if entry.exists():
|
|
35
|
+
file_path = entry
|
|
36
|
+
plugin_name = item.name
|
|
37
|
+
if not file_path:
|
|
38
|
+
continue
|
|
39
|
+
try:
|
|
40
|
+
spec = importlib.util.spec_from_file_location(plugin_name, file_path)
|
|
41
|
+
module = importlib.util.module_from_spec(spec)
|
|
42
|
+
spec.loader.exec_module(module)
|
|
43
|
+
for _, obj in inspect.getmembers(module, inspect.isclass):
|
|
44
|
+
if issubclass(obj, BasePlugin) and obj is not BasePlugin:
|
|
45
|
+
ctx = build_context(plugin_name, file_path)
|
|
46
|
+
instance = obj(ctx)
|
|
47
|
+
candidates.setdefault(plugin_name, []).append((instance, file_path))
|
|
48
|
+
break
|
|
49
|
+
except Exception as e:
|
|
50
|
+
print(f"\n⚠️ Plugin Failure - Failed to inspect '{plugin_name}'")
|
|
51
|
+
print(f"Exception code: {e}, Flyshell will still launch.")
|
|
52
|
+
loaded_count = 0
|
|
53
|
+
first_print = True
|
|
54
|
+
for name, entries in candidates.items():
|
|
55
|
+
failed = False
|
|
56
|
+
if name in RESERVED_NAMES:
|
|
57
|
+
print(f"\n⚠️ Collision Error - Plugin '{name}' conflicts with a built-in Flyshell command and will not be loaded.")
|
|
58
|
+
failed = True
|
|
59
|
+
if len(entries) > 1:
|
|
60
|
+
paths = "\n - ".join(str(path) for _, path in entries)
|
|
61
|
+
print(f"\n⚠️ Collision Error - Multiple plugins named '{name}' detected: {paths}")
|
|
62
|
+
print(f"The above plugins will not be loaded. Please rename them to unique names.")
|
|
63
|
+
failed = True
|
|
64
|
+
if failed:
|
|
65
|
+
continue
|
|
66
|
+
instance, _ = entries[0]
|
|
67
|
+
data.PLUGINS[name] = instance
|
|
68
|
+
if first_print:
|
|
69
|
+
print("\nInstalled Plugins:")
|
|
70
|
+
first_print = False
|
|
71
|
+
print(f"✅ - {name}")
|
|
72
|
+
loaded_count += 1
|
|
73
|
+
if loaded_count > 0:
|
|
74
|
+
print(f"\nTotal of {loaded_count} plugin(s) found.")
|
|
75
|
+
else:
|
|
76
|
+
print("\nNo plugins loaded.")
|
|
77
|
+
|
|
78
|
+
def build_context(plugin_name, file_path=None):
|
|
79
|
+
plugin_storage = data.get_all_plugin_data(plugin_name)
|
|
80
|
+
context = {
|
|
81
|
+
"plugin_name": plugin_name,
|
|
82
|
+
"file_path": str(file_path) if file_path else None,
|
|
83
|
+
"metadata": {
|
|
84
|
+
"host_os": data.HOST_OS,
|
|
85
|
+
"version": data.VERSION,
|
|
86
|
+
"build": data.BUILD
|
|
87
|
+
},
|
|
88
|
+
"storage": plugin_storage
|
|
89
|
+
}
|
|
90
|
+
return context
|
flyshell/main.py
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# src\flyshell\main.py
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
import os
|
|
5
|
+
import sys
|
|
6
|
+
|
|
7
|
+
PACKAGE_ROOT = Path(__file__).resolve().parent
|
|
8
|
+
SRC_DIR = PACKAGE_ROOT.parent
|
|
9
|
+
PROJECT_ROOT = SRC_DIR.parent
|
|
10
|
+
|
|
11
|
+
if str(SRC_DIR) not in sys.path:
|
|
12
|
+
sys.path.insert(0, str(SRC_DIR))
|
|
13
|
+
|
|
14
|
+
def boot_check():
|
|
15
|
+
print("\nFlyshell will now check that your modules exist.")
|
|
16
|
+
abstract_dir = PACKAGE_ROOT / "abstract"
|
|
17
|
+
builtin_dir = PACKAGE_ROOT / "builtin"
|
|
18
|
+
core_dir = PACKAGE_ROOT / "core"
|
|
19
|
+
REQUIRED_COMPONENTS = [
|
|
20
|
+
abstract_dir,
|
|
21
|
+
abstract_dir / "base_cmd.py",
|
|
22
|
+
abstract_dir / "base_plugin.py",
|
|
23
|
+
abstract_dir / "parent_cmd.py",
|
|
24
|
+
builtin_dir,
|
|
25
|
+
builtin_dir / "fs.py",
|
|
26
|
+
builtin_dir / "system.py",
|
|
27
|
+
builtin_dir / "utils.py",
|
|
28
|
+
core_dir,
|
|
29
|
+
core_dir / "auth.py",
|
|
30
|
+
core_dir / "console.py",
|
|
31
|
+
core_dir / "data.py",
|
|
32
|
+
core_dir / "directory.py",
|
|
33
|
+
core_dir / "loader.py",
|
|
34
|
+
]
|
|
35
|
+
present = []
|
|
36
|
+
missing = []
|
|
37
|
+
for path in REQUIRED_COMPONENTS:
|
|
38
|
+
if path.exists():
|
|
39
|
+
present.append(str(path))
|
|
40
|
+
else:
|
|
41
|
+
missing.append(str(path))
|
|
42
|
+
if missing:
|
|
43
|
+
print("\nCRITICAL BOOT ERROR: Critical system module(s) could not be found.")
|
|
44
|
+
for i in present:
|
|
45
|
+
print(f"✅ {i} - File found")
|
|
46
|
+
for i in missing:
|
|
47
|
+
print(f"❌ {i} - FILE NOT FOUND")
|
|
48
|
+
if missing:
|
|
49
|
+
return False
|
|
50
|
+
tests_dir = PROJECT_ROOT / "tests"
|
|
51
|
+
if tests_dir.exists():
|
|
52
|
+
print("\nFlyshell will now check internal additional packages and features. These are not required.")
|
|
53
|
+
for path in tests_dir.glob("test_*.py"):
|
|
54
|
+
print(f"✅ {path.name} - Test found")
|
|
55
|
+
try:
|
|
56
|
+
import pytest
|
|
57
|
+
print(f"✅ Your tests can be run using Pytest.")
|
|
58
|
+
except ImportError:
|
|
59
|
+
print(f"⚠️ Your tests cannot be run as Pytest is not installed.")
|
|
60
|
+
print("\nFlyshell will now check external additional packages and features. These are not required.")
|
|
61
|
+
from flyshell.core import console
|
|
62
|
+
if console.check_readline():
|
|
63
|
+
print("✅ Terminal Readline - Available (Use arrow keys to navigate input history)")
|
|
64
|
+
else:
|
|
65
|
+
print("⚠️ Terminal Readline - Unavailable (This does not affect your performance)")
|
|
66
|
+
return True
|
|
67
|
+
|
|
68
|
+
def main():
|
|
69
|
+
os.system("")
|
|
70
|
+
print("\033[H\033[2J", end="")
|
|
71
|
+
print("\nLaunch process initiated. Flyshell is checking it is able to launch...")
|
|
72
|
+
try:
|
|
73
|
+
if boot_check():
|
|
74
|
+
from flyshell.core import auth, console, data, loader
|
|
75
|
+
if data.HOST_OS in ["Windows", "Darwin", "Linux"]:
|
|
76
|
+
if sys.version_info < (3, 10):
|
|
77
|
+
print("\nCRITICAL ERROR: Your Python version is too old to be supported by Flyshell.")
|
|
78
|
+
print("Flyshell cannot launch because it requires Python 3.10 or newer.")
|
|
79
|
+
sys.exit(1)
|
|
80
|
+
print(f"\nYour OS '{data.HOST_OS}' is compatible with Flyshell.")
|
|
81
|
+
print("Flyshell will now boot.")
|
|
82
|
+
loader.scan_plugins()
|
|
83
|
+
if auth.login_flow():
|
|
84
|
+
console.boot()
|
|
85
|
+
else:
|
|
86
|
+
print("Shutting down...\n")
|
|
87
|
+
sys.exit(0)
|
|
88
|
+
else:
|
|
89
|
+
print(f"\nCRITICAL ERROR: Host operating system '{data.HOST_OS}' is not supported.")
|
|
90
|
+
print("Flyshell cannot launch because your operating system is not supported.")
|
|
91
|
+
sys.exit(1)
|
|
92
|
+
else:
|
|
93
|
+
print("\nFlyshell cannot launch until the above file paths are restored.")
|
|
94
|
+
sys.exit(1)
|
|
95
|
+
except KeyboardInterrupt:
|
|
96
|
+
print("\n\nFlyshell session terminated, shutting down...\n")
|
|
97
|
+
sys.exit(0)
|
|
98
|
+
except Exception as e:
|
|
99
|
+
print("\n❌❌❌ Oops! An unexpected error occurred.")
|
|
100
|
+
print(f"Error details: {e}")
|
|
101
|
+
print("We don't really know what happened there. Sorry about that.\n")
|
|
102
|
+
print("Print traceback message? Default is N.")
|
|
103
|
+
choice = input("[y/n]?: ")
|
|
104
|
+
if choice.lower() == "y":
|
|
105
|
+
import traceback
|
|
106
|
+
raw = traceback.extract_tb(e.__traceback__)
|
|
107
|
+
last_frame = raw[-1]
|
|
108
|
+
print("\nTraceback details:")
|
|
109
|
+
print(f"File: '{last_frame[0]}'")
|
|
110
|
+
print(f"Line: {last_frame[1]}")
|
|
111
|
+
print(f"Exception message: '{e}'")
|
|
112
|
+
sys.exit(1)
|
|
113
|
+
|
|
114
|
+
if __name__ == "__main__":
|
|
115
|
+
main()
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: flyshell
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A modular, zero-dependency command-line environment in Python.
|
|
5
|
+
License: MIT
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Provides-Extra: dev
|
|
10
|
+
Requires-Dist: pytest; extra == "dev"
|
|
11
|
+
Provides-Extra: readline
|
|
12
|
+
Requires-Dist: pyreadline3; sys_platform == "win32" and extra == "readline"
|
|
13
|
+
Dynamic: license-file
|
|
14
|
+
|
|
15
|
+
# Flyshell
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+

|
|
19
|
+

|
|
20
|
+

|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
> Documentation last updated: v1.0.0
|
|
24
|
+
|
|
25
|
+
A modular, zero-dependency command-line environment and extensible runtime interface built in Python.
|
|
26
|
+
|
|
27
|
+
Flyshell provides a modular, extensible shell environment featuring dynamic runtime plugin loading, session persistence, secure authentication, and cross-platform process isolation, using only Python standard libraries.
|
|
28
|
+
|
|
29
|
+
No extra packages required, just install and enjoy!
|
|
30
|
+
|
|
31
|
+
## Key Features
|
|
32
|
+
|
|
33
|
+
1. **Zero External Dependencies** - Flyshell is built entirely with native Python modules with absolutely zero third-party packages required to enjoy full functionality.
|
|
34
|
+
2. **Dynamic Plugin Architecture**: Flyshell employs a dynamic plugin architecture that automatically scans for plugins in the User Directory following the standard defined in `src/flyshell/abstract/base_plugin.py`.
|
|
35
|
+
3. **Secure Authentication**: Flyshell uses salted PBKDF2 HMAC (SHA-256, 600,000 iterations) with constant-time equality comparisons to prevent timing attacks on password information.
|
|
36
|
+
4. **Cross-Platform Support**: Flyshell is fully supported by Windows (NT), macOS (Darwin) and Linux installations with native OS management and POSIX-aware parsing. Note that Flyshell is **not** supported by any other systems.
|
|
37
|
+
5. **State and History Persistence**: Flyshell has a fully encapsulated SQL storage system using SQLite3 providing session metrics and ISO 8601 UTC audit logging.
|
|
38
|
+
|
|
39
|
+
## System Requirements
|
|
40
|
+
|
|
41
|
+
1. **Python**: Your Python installation or IDE must support **Python 3.10 or newer** as Flyshell utilises structural pattern matching features. Older Python installations will be rejected by Flyshell on boot or could crash the system.
|
|
42
|
+
2. **Operating System**: Your operating system must be **Windows 10/11, macOS (Darwin) or Linux**. Any other operating system will be rejected by Flyshell on boot.
|
|
43
|
+
|
|
44
|
+
## System Architecture
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
flyshell/
|
|
48
|
+
├── .github/
|
|
49
|
+
│ └── workflows/
|
|
50
|
+
│ └── pytest.yml
|
|
51
|
+
├── src/
|
|
52
|
+
│ └── flyshell/
|
|
53
|
+
│ ├── abstract/
|
|
54
|
+
│ │ ├── __init__.py
|
|
55
|
+
│ │ ├── base_cmd.py
|
|
56
|
+
│ │ ├── base_plugin.py
|
|
57
|
+
│ │ └── parent_cmd.py
|
|
58
|
+
│ ├── builtin/
|
|
59
|
+
│ │ ├── __init__.py
|
|
60
|
+
│ │ ├── fs.py
|
|
61
|
+
│ │ ├── system.py
|
|
62
|
+
│ │ └── utils.py
|
|
63
|
+
│ ├── core/
|
|
64
|
+
│ │ ├── __init__.py
|
|
65
|
+
│ │ ├── auth.py
|
|
66
|
+
│ │ ├── console.py
|
|
67
|
+
│ │ ├── data.py
|
|
68
|
+
│ │ ├── directory.py
|
|
69
|
+
│ │ └── loader.py
|
|
70
|
+
│ ├── __init__.py
|
|
71
|
+
│ └── main.py
|
|
72
|
+
├── tests/
|
|
73
|
+
│ ├── test_auth.py
|
|
74
|
+
│ ├── test_data.py
|
|
75
|
+
│ ├── test_directory.py
|
|
76
|
+
│ ├── test_loader.py
|
|
77
|
+
│ └── test_security.py
|
|
78
|
+
├── .gitignore
|
|
79
|
+
├── LICENSE
|
|
80
|
+
├── pyproject.toml
|
|
81
|
+
└── README.md
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Installing Flyshell
|
|
85
|
+
|
|
86
|
+
There are two methods to install Flyshell.
|
|
87
|
+
|
|
88
|
+
### Method 1: Install via `pip` (Best for General Use)
|
|
89
|
+
|
|
90
|
+
Install Flyshell through `pip`:
|
|
91
|
+
```bash
|
|
92
|
+
pip install flyshell
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Then, you can simply run Flyshell:
|
|
96
|
+
```bash
|
|
97
|
+
flyshell
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### Method 2: Install from source via `git` (Best for Development & Custom Plugins)
|
|
101
|
+
|
|
102
|
+
Clone the GitHub repository:
|
|
103
|
+
```bash
|
|
104
|
+
git clone https://github.com/kianodev/flyshell.git
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Switch to the Flyshell directory and install in editable mode:
|
|
108
|
+
```bash
|
|
109
|
+
cd flyshell
|
|
110
|
+
pip install -e .
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Adding optional dependencies
|
|
114
|
+
|
|
115
|
+
To install Readline (on Windows):
|
|
116
|
+
```bash
|
|
117
|
+
pip install -e .[readline]
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
To install the development and testing suite (including Pytest):
|
|
121
|
+
```bash
|
|
122
|
+
pip install -e .[dev]
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Exploring Flyshell
|
|
126
|
+
|
|
127
|
+
Once you have installed Flyshell using either of the methods above, you will be prompted to initialise your user profile. Once this is complete, you will be greeted with a prompt that looks like this:
|
|
128
|
+
```console
|
|
129
|
+
Flyshell [v1.x.x] (current_dir)>>
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
From this stage, you can enter a wide variety of commands. To see the commands list for your installation, type `cmds` or `help` to return a full up-to-date directory. Use `fs plugins` to return plugin information.
|
|
133
|
+
|
|
134
|
+
Flyshell also supports command chaining out of the box. Use `;` to chain commands together regardless of result, `&&` to execute only on success and `||` to execute only on failure.
|
|
135
|
+
|
|
136
|
+
Use `-h` or `--help` after any command to return that command's specific help list.
|
|
137
|
+
|
|
138
|
+
To close Flyshell once you are done, enter `kill` onto the command line then confirm, or press Ctrl + D to close the session immediately.
|
|
139
|
+
|
|
140
|
+
## Creating Custom Plugins
|
|
141
|
+
|
|
142
|
+
Flyshell features an extensible plugin API. This API supports both single-file and multi-file plugins. Follow the below guide to create your own.
|
|
143
|
+
|
|
144
|
+
Plugins must inherit from the `BasePlugin` contract defined in `src/flyshell/abstract/base_plugin.py`. Plugins are stored in the User Directory. Navigate to your App Storage folder:
|
|
145
|
+
- **Windows**: `%APPDATA%\Flyshell\plugins`
|
|
146
|
+
- **macOS**: `~/Library/Application Support/Flyshell/plugins`
|
|
147
|
+
- **Linux**: `~/.local/share/Flyshell/plugins`
|
|
148
|
+
|
|
149
|
+
Place your plugins inside the `plugins/` folder.
|
|
150
|
+
|
|
151
|
+
All plugins should define the required attributes. Flyshell can read this information for both `fs plugins` and `[my_plugin] -h` / `--help` which are both supported out of the box. Flyshell will discover, inspect and import your plugin from the `plugins/` folder without you having to alter any internal code.
|
|
152
|
+
|
|
153
|
+
### The Entry-Point
|
|
154
|
+
|
|
155
|
+
All plugins must have an entry-point file. For single-file plugins, this is the plugin file. For multi-file plugins, this file must be named `plugin.py` and stored directly inside of your plugin's own folder.
|
|
156
|
+
|
|
157
|
+
This file is what enables Flyshell to speak to your plugin.
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
# Entry-point (my_plugin.py or my_plugin\plugin.py)
|
|
161
|
+
|
|
162
|
+
from flyshell import BasePlugin # This is required
|
|
163
|
+
|
|
164
|
+
class MyPlugin(BasePlugin):
|
|
165
|
+
name = "My Plugin" # The name you want visible to Flyshell
|
|
166
|
+
description = "This is my plugin." # A short one-line explaining what your plugin does
|
|
167
|
+
version = "1.0.0" # Default is 1.0.0
|
|
168
|
+
author = "kianodev" # You can put your name, your GitHub handle, or leave blank to make it 'Unknown'
|
|
169
|
+
usage = "" # (OPTIONAL) Explain how to use your plugin
|
|
170
|
+
extended_help = "" # (OPTIONAL) A more detailed, multi-line guide containing specific assistance
|
|
171
|
+
|
|
172
|
+
def on_load(self): # (OPTIONAL) Enables your program to handle specialist set-up tasks before execute()
|
|
173
|
+
pass
|
|
174
|
+
|
|
175
|
+
def on_unload(self): # (OPTIONAL) Enables your program to handle specialist shut-down tasks
|
|
176
|
+
super().on_unload() # If you use a custom on_unload(), end it with this
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def execute(self, args): # This is what Flyshell calls to execute
|
|
180
|
+
print(f"Hello! Arguments: {args}")
|
|
181
|
+
return
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Extra Functions
|
|
185
|
+
|
|
186
|
+
Additional functions are available for you to use:
|
|
187
|
+
|
|
188
|
+
1. `get_data(key, default=None)`: Retrieves a value from local plugin memory.
|
|
189
|
+
2. `set_data(key, value)`: Updates a key in local memory and automatically persists it to SQLite via `save_storage()`.
|
|
190
|
+
3. `load_storage()`: Reloads fresh key-value pairs directly from SQLite into `self.storage`.
|
|
191
|
+
4. `save_storage()`: Writes all in-memory key-value pairs in `self.storage` back to SQLite.
|
|
192
|
+
|
|
193
|
+
Plugins save automatically on shut-down. If `on_unload()` is not used, it is automatic. If `on_unload()` is used, `super().on_unload()` saves your files.
|
|
194
|
+
|
|
195
|
+
### Built-in Attributes
|
|
196
|
+
|
|
197
|
+
Every plugin has direct access to the following instance variables:
|
|
198
|
+
|
|
199
|
+
- `self.plugin_name` (`str`): The unique name identifier used to invoke the plugin.
|
|
200
|
+
- `self.storage` (`dict`): In-memory key-value data automatically loaded from the persistent database.
|
|
201
|
+
- `self.context` (`dict`): Environmental metadata provided at start-up, within it:
|
|
202
|
+
- `self.context["metadata"]["host_os"]`: Operating system (e.g., `'Windows'`, `'Linux'`, `'Darwin'`).
|
|
203
|
+
- `self.context["metadata"]["version"]`: Current Flyshell version.
|
|
204
|
+
- `self.context["file_path"]`: Full path to the plugin's source file.
|
|
205
|
+
|
|
206
|
+
### Extra Notes
|
|
207
|
+
|
|
208
|
+
You are welcome to catch errors yourself. However, Flyshell will handle them automatically. That said, if you would like your plugin to continue after an error, you need to implement error handling yourself as the default system closes your plugin.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
flyshell/__init__.py,sha256=45hJEblK9nMHFJF0N_x53uhAX9oocKmzy2kF-qHoLBo,164
|
|
2
|
+
flyshell/main.py,sha256=hf2B2Ad35FMTXynwXyZk29wVdVrIPsVbOkICtcl86Rc,4492
|
|
3
|
+
flyshell/abstract/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
flyshell/abstract/base_cmd.py,sha256=kyKDLAmZJrBFbce0epBT6nom05GXYqZGhl0Fy1cImNU,982
|
|
5
|
+
flyshell/abstract/base_plugin.py,sha256=W3E-ysd6zqSgwcqtATLujV9Bxf2_YXSifepTRqWU7W8,2408
|
|
6
|
+
flyshell/abstract/parent_cmd.py,sha256=WSVDKCklQkHHOkKPsrY8F0ltTAuCzbl7bHEY9Sp0OIY,2387
|
|
7
|
+
flyshell/builtin/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
|
+
flyshell/builtin/fs.py,sha256=dItltDzduKAexjmbsIVl_OUb-G4fCyX86tFwK60Sb0I,7215
|
|
9
|
+
flyshell/builtin/system.py,sha256=sgk4GPV8mO6luQgWMUyuTQVBFL4Y0NzB2w37XQogEJE,4974
|
|
10
|
+
flyshell/builtin/utils.py,sha256=cvzP43dU3oJm1a39fEBScUv-WJ5U9zoRuedvRIPpmr4,3478
|
|
11
|
+
flyshell/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
flyshell/core/auth.py,sha256=MwTM6uM-kddDi6B-yXc4B6TQlh0xuqOQJOZ4QhnbI9A,4271
|
|
13
|
+
flyshell/core/console.py,sha256=Ktu2Qvaa6ZGFZCw7Vld_6HDJPQBnwYJDFuX9FkEeLxM,2155
|
|
14
|
+
flyshell/core/data.py,sha256=0FlwssulyntbPoEjhHGfMd7YAoJEEDOGOjkOeA8IfGI,8842
|
|
15
|
+
flyshell/core/directory.py,sha256=bXe6sEGfjKDVrYkX2Bc6mD7hIWjVvKr1VdCatV_otWI,8360
|
|
16
|
+
flyshell/core/loader.py,sha256=2QUCAhkxf6p75O6nz5e0HG4jfIZvksBzQyEwVt-fvnU,3466
|
|
17
|
+
flyshell-1.0.0.dist-info/licenses/LICENSE,sha256=0dEPo6haQq5yozzi3aql0C0FnUCTZ0WRakYTNQakEEw,1086
|
|
18
|
+
flyshell-1.0.0.dist-info/METADATA,sha256=UVKhQ6WJxT9jxSueb9kJOCMA6uiUNW2nOVKprz9VCxE,9198
|
|
19
|
+
flyshell-1.0.0.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
|
|
20
|
+
flyshell-1.0.0.dist-info/entry_points.txt,sha256=MIfpdu-2yd0LEUu2gpmHiPxcytTQNrMgpQDNEmQH0UI,48
|
|
21
|
+
flyshell-1.0.0.dist-info/top_level.txt,sha256=oOEQzHfYVg-GEu9H5YnHffSAMkyiB6ud9KUAj_TlHRw,9
|
|
22
|
+
flyshell-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 kianodev
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
flyshell
|