更改项目名为NebulaShell
This commit is contained in:
281
store/@{NebulaShell}/nodejs-adapter/README.md
Normal file
281
store/@{NebulaShell}/nodejs-adapter/README.md
Normal file
@@ -0,0 +1,281 @@
|
||||
# Node.js Adapter Plugin for NebulaShell
|
||||
|
||||
## Overview
|
||||
|
||||
The `@NebulaShell/nodejs-adapter` plugin provides Node.js and npm capabilities to other NebulaShell plugins. It enables any plugin to run Node.js projects located in their `/pkg` directory with isolated dependencies.
|
||||
|
||||
## Features
|
||||
|
||||
- **Node.js Runtime**: Execute Node.js scripts and applications
|
||||
- **npm Package Manager**: Install and manage npm packages
|
||||
- **Dependency Isolation**: Each plugin gets its own isolated `node_modules` directory
|
||||
- **Script Execution**: Run npm scripts or direct Node.js files
|
||||
- **Project Initialization**: Automatically create package.json and basic project structure
|
||||
|
||||
## Installation
|
||||
|
||||
The plugin is included in the NebulaShell store at:
|
||||
```
|
||||
store/@{NebulaShell}/nodejs-adapter/
|
||||
```
|
||||
|
||||
It will be automatically loaded when the NebulaShell server starts.
|
||||
|
||||
## Usage
|
||||
|
||||
### For Plugin Developers
|
||||
|
||||
To use the Node.js adapter in your plugin, specify it in your plugin's manifest:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "@NebulaShell/my-nodejs-plugin",
|
||||
"version": "1.0.0",
|
||||
"runtime": {
|
||||
"type": "nodejs",
|
||||
"entry_point": "pkg/index.js",
|
||||
"adapter": "@NebulaShell/nodejs-adapter"
|
||||
},
|
||||
"dependencies": {
|
||||
"nodejs-adapter": "^1.2.0"
|
||||
},
|
||||
"nodejs": {
|
||||
"packages": ["express", "lodash"],
|
||||
"scripts": {
|
||||
"start": "node index.js",
|
||||
"build": "webpack --mode production"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
my-plugin/
|
||||
├── manifest.json
|
||||
├── main.py (optional Python entry point)
|
||||
└── pkg/
|
||||
├── package.json
|
||||
├── index.js
|
||||
└── node_modules/ (auto-generated)
|
||||
```
|
||||
|
||||
### API Methods
|
||||
|
||||
The adapter provides the following methods that can be called by other plugins:
|
||||
|
||||
#### `check_versions()`
|
||||
Check Node.js and npm versions installed on the system.
|
||||
|
||||
```python
|
||||
adapter = get_plugin('nodejs-adapter')
|
||||
versions = adapter.check_versions()
|
||||
# Returns: {'node': 'v20.19.5', 'npm': '10.8.2', 'status': 'ok'}
|
||||
```
|
||||
|
||||
#### `install(plugin_id, packages, pkg_dir=None, is_dev=False)`
|
||||
Install npm packages to a plugin-specific directory.
|
||||
|
||||
```python
|
||||
result = adapter.install(
|
||||
plugin_id='my-plugin',
|
||||
packages=['express', 'lodash@4.17.21'],
|
||||
is_dev=False
|
||||
)
|
||||
# Returns: {'status': 'success', 'target_dir': '/path/to/dir', ...}
|
||||
```
|
||||
|
||||
#### `run(plugin_id, script, pkg_dir=None, args=None, env=None)`
|
||||
Execute a Node.js script or npm command.
|
||||
|
||||
```python
|
||||
# Run npm script
|
||||
result = adapter.run(
|
||||
plugin_id='my-plugin',
|
||||
script='start' # runs 'npm run start'
|
||||
)
|
||||
|
||||
# Run direct Node.js file
|
||||
result = adapter.run(
|
||||
plugin_id='my-plugin',
|
||||
script='pkg/index.js', # runs 'node pkg/index.js'
|
||||
args=['--port', '3000']
|
||||
)
|
||||
```
|
||||
|
||||
#### `list_packages(plugin_id, pkg_dir=None)`
|
||||
List installed packages in a plugin directory.
|
||||
|
||||
```python
|
||||
packages = adapter.list_packages(plugin_id='my-plugin')
|
||||
# Returns: {'status': 'success', 'packages': {...}}
|
||||
```
|
||||
|
||||
#### `init_project(plugin_id, pkg_dir=None, package_name=None, version='1.0.0')`
|
||||
Initialize a new Node.js project.
|
||||
|
||||
```python
|
||||
result = adapter.init_project(
|
||||
plugin_id='my-plugin',
|
||||
package_name='my-awesome-plugin'
|
||||
)
|
||||
# Creates package.json and index.js in the plugin directory
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The adapter can be configured via environment variables or plugin config:
|
||||
|
||||
```json
|
||||
{
|
||||
"config": {
|
||||
"node_path": "/usr/bin/node",
|
||||
"npm_path": "/usr/bin/npm",
|
||||
"default_registry": "https://registry.npmjs.org",
|
||||
"cache_dir": "~/.nebulashell/nodejs-cache"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
|
||||
- `NODEJS_ADAPTER_NODE_PATH`: Path to Node.js binary
|
||||
- `NODEJS_ADAPTER_NPM_PATH`: Path to npm binary
|
||||
- `NODEJS_ADAPTER_REGISTRY`: Custom npm registry URL
|
||||
- `NODEJS_ADAPTER_CACHE_DIR`: Directory for cached packages
|
||||
|
||||
## Examples
|
||||
|
||||
### Example 1: Simple Express Server Plugin
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "@NebulaShell/express-server",
|
||||
"version": "1.0.0",
|
||||
"runtime": {
|
||||
"type": "nodejs",
|
||||
"entry_point": "pkg/server.js",
|
||||
"adapter": "@NebulaShell/nodejs-adapter"
|
||||
},
|
||||
"nodejs": {
|
||||
"packages": ["express"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**pkg/server.js**:
|
||||
```javascript
|
||||
const express = require('express');
|
||||
const app = express();
|
||||
const port = process.env.PORT || 3000;
|
||||
|
||||
app.get('/', (req, res) => {
|
||||
res.json({ message: 'Hello from NebulaShell!' });
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Server running on port ${port}`);
|
||||
});
|
||||
```
|
||||
|
||||
### Example 2: Build Tool Plugin
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "@NebulaShell/webpack-builder",
|
||||
"version": "1.0.0",
|
||||
"runtime": {
|
||||
"type": "nodejs",
|
||||
"adapter": "@NebulaShell/nodejs-adapter"
|
||||
},
|
||||
"nodejs": {
|
||||
"packages": ["webpack", "webpack-cli"],
|
||||
"scripts": {
|
||||
"build": "webpack --mode production"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Dependency Isolation
|
||||
|
||||
Each plugin gets its own isolated `node_modules` directory:
|
||||
|
||||
- Default location: `~/.nebulashell/nodejs-cache/{plugin_id}/`
|
||||
- Custom location: Specify `pkg_dir` parameter in API calls
|
||||
- No conflicts between different plugins' dependencies
|
||||
|
||||
## Error Handling
|
||||
|
||||
All adapter methods return a status object:
|
||||
|
||||
```python
|
||||
result = adapter.install(plugin_id='test', packages=['invalid-package-name-xyz'])
|
||||
if result['status'] == 'error':
|
||||
print(f"Installation failed: {result['error']}")
|
||||
else:
|
||||
print(f"Success! Packages installed to: {result['target_dir']}")
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Test the adapter directly:
|
||||
|
||||
```bash
|
||||
cd /workspace/store/@{NebulaShell}/nodejs-adapter
|
||||
python main.py
|
||||
```
|
||||
|
||||
Expected output:
|
||||
```
|
||||
Node.js Adapter Plugin for NebulaShell
|
||||
==================================================
|
||||
|
||||
Node.js Version: v20.19.5
|
||||
npm Version: 10.8.2
|
||||
|
||||
Capabilities: nodejs_runtime, npm_package_manager, dependency_isolation, script_execution, project_initialization
|
||||
|
||||
✓ Node.js Adapter initialized successfully!
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Node.js or npm not found
|
||||
|
||||
Ensure Node.js and npm are installed on your system:
|
||||
|
||||
```bash
|
||||
# Check installation
|
||||
node --version
|
||||
npm --version
|
||||
|
||||
# Install if needed (Ubuntu/Debian)
|
||||
apt update && apt install -y nodejs npm
|
||||
|
||||
# Install if needed (macOS)
|
||||
brew install node
|
||||
```
|
||||
|
||||
### Permission errors
|
||||
|
||||
If you encounter permission errors during package installation:
|
||||
|
||||
```bash
|
||||
# Ensure cache directory is writable
|
||||
mkdir -p ~/.nebulashell/nodejs-cache
|
||||
chmod 755 ~/.nebulashell/nodejs-cache
|
||||
```
|
||||
|
||||
### Timeout during installation
|
||||
|
||||
For large packages or slow networks, increase the timeout in the adapter configuration.
|
||||
|
||||
## License
|
||||
|
||||
MIT License - See LICENSE file for details.
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions welcome! Please read CONTRIBUTING.md for guidelines.
|
||||
463
store/@{NebulaShell}/nodejs-adapter/main.py
Normal file
463
store/@{NebulaShell}/nodejs-adapter/main.py
Normal file
@@ -0,0 +1,463 @@
|
||||
"""
|
||||
Node.js Adapter Plugin for NebulaShell
|
||||
|
||||
This plugin provides Node.js and npm capabilities to other plugins.
|
||||
Other plugins can specify this adapter in their manifest to run Node.js projects
|
||||
located in their /pkg directory with isolated dependencies.
|
||||
|
||||
Features:
|
||||
- Install npm packages to plugin-specific directories
|
||||
- Execute Node.js scripts and npm commands
|
||||
- Check Node.js and npm versions
|
||||
- List installed packages
|
||||
- Dependency isolation per plugin
|
||||
"""
|
||||
|
||||
import subprocess
|
||||
import json
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Any
|
||||
|
||||
|
||||
class NodeJSAdapter:
|
||||
"""Node.js runtime adapter for managing Node.js projects and dependencies."""
|
||||
|
||||
def __init__(self, config: Optional[Dict[str, Any]] = None):
|
||||
"""Initialize the Node.js adapter with configuration."""
|
||||
self.config = config or {}
|
||||
self.node_path = self.config.get('node_path', '/usr/bin/node')
|
||||
self.npm_path = self.config.get('npm_path', '/usr/bin/npm')
|
||||
self.default_registry = self.config.get('default_registry', 'https://registry.npmjs.org')
|
||||
self.cache_dir = Path(self.config.get('cache_dir', '~/.nebulashell/nodejs-cache')).expanduser()
|
||||
|
||||
# Ensure cache directory exists
|
||||
self.cache_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
self._validate_runtime()
|
||||
|
||||
def _validate_runtime(self) -> bool:
|
||||
"""Validate that Node.js and npm are available."""
|
||||
try:
|
||||
node_result = subprocess.run(
|
||||
[self.node_path, '--version'],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10
|
||||
)
|
||||
if node_result.returncode != 0:
|
||||
raise RuntimeError(f"Node.js not found: {node_result.stderr}")
|
||||
|
||||
npm_result = subprocess.run(
|
||||
[self.npm_path, '--version'],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10
|
||||
)
|
||||
if npm_result.returncode != 0:
|
||||
raise RuntimeError(f"npm not found: {npm_result.stderr}")
|
||||
|
||||
return True
|
||||
except FileNotFoundError as e:
|
||||
raise RuntimeError(f"Node.js or npm not found in system: {str(e)}")
|
||||
except subprocess.TimeoutExpired as e:
|
||||
raise RuntimeError(f"Timeout while checking Node.js/npm versions: {str(e)}")
|
||||
|
||||
def check_versions(self) -> Dict[str, str]:
|
||||
"""Check Node.js and npm versions."""
|
||||
try:
|
||||
node_result = subprocess.run(
|
||||
[self.node_path, '--version'],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10
|
||||
)
|
||||
npm_result = subprocess.run(
|
||||
[self.npm_path, '--version'],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10
|
||||
)
|
||||
|
||||
return {
|
||||
'node': node_result.stdout.strip(),
|
||||
'npm': npm_result.stdout.strip(),
|
||||
'status': 'ok'
|
||||
}
|
||||
except subprocess.TimeoutExpired as e:
|
||||
return {
|
||||
'node': 'unknown',
|
||||
'npm': 'unknown',
|
||||
'status': 'error',
|
||||
'error': f'Timeout: {str(e)}'
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
'node': 'unknown',
|
||||
'npm': 'unknown',
|
||||
'status': 'error',
|
||||
'error': str(e)
|
||||
}
|
||||
|
||||
def install(self, plugin_id: str, packages: List[str],
|
||||
pkg_dir: Optional[Path] = None,
|
||||
is_dev: bool = False) -> Dict[str, Any]:
|
||||
"""
|
||||
Install npm packages to a plugin-specific directory.
|
||||
|
||||
Args:
|
||||
plugin_id: Unique identifier for the plugin
|
||||
packages: List of npm packages to install (e.g., ['express', 'lodash@4.17.21'])
|
||||
pkg_dir: Optional custom package directory (defaults to plugin storage dir)
|
||||
is_dev: Whether to install as dev dependencies
|
||||
|
||||
Returns:
|
||||
Dict with installation result
|
||||
"""
|
||||
try:
|
||||
# Determine target directory
|
||||
if pkg_dir is None:
|
||||
# Default to plugin storage directory
|
||||
target_dir = self.cache_dir / plugin_id
|
||||
else:
|
||||
target_dir = Path(pkg_dir)
|
||||
|
||||
target_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Build npm install command
|
||||
cmd = [self.npm_path, 'install']
|
||||
if is_dev:
|
||||
cmd.append('--save-dev')
|
||||
else:
|
||||
cmd.append('--save')
|
||||
|
||||
# Set registry if specified
|
||||
if self.default_registry:
|
||||
cmd.extend(['--registry', self.default_registry])
|
||||
|
||||
# Add packages
|
||||
cmd.extend(packages)
|
||||
|
||||
# Execute installation
|
||||
result = subprocess.run(
|
||||
cmd,
|
||||
cwd=str(target_dir),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=300 # 5 minutes timeout for installation
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
return {
|
||||
'status': 'success',
|
||||
'plugin_id': plugin_id,
|
||||
'packages': packages,
|
||||
'target_dir': str(target_dir),
|
||||
'output': result.stdout,
|
||||
'is_dev': is_dev
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'status': 'error',
|
||||
'plugin_id': plugin_id,
|
||||
'packages': packages,
|
||||
'target_dir': str(target_dir),
|
||||
'error': result.stderr,
|
||||
'output': result.stdout
|
||||
}
|
||||
except subprocess.TimeoutExpired as e:
|
||||
return {
|
||||
'status': 'error',
|
||||
'plugin_id': plugin_id,
|
||||
'packages': packages,
|
||||
'error': f'Installation timeout: {str(e)}'
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
'status': 'error',
|
||||
'plugin_id': plugin_id,
|
||||
'packages': packages,
|
||||
'error': str(e)
|
||||
}
|
||||
|
||||
def run(self, plugin_id: str, script: str,
|
||||
pkg_dir: Optional[Path] = None,
|
||||
args: Optional[List[str]] = None,
|
||||
env: Optional[Dict[str, str]] = None) -> Dict[str, Any]:
|
||||
"""
|
||||
Execute a Node.js script or npm command.
|
||||
|
||||
Args:
|
||||
plugin_id: Unique identifier for the plugin
|
||||
script: Script to run (e.g., 'start', 'build', or path to .js file)
|
||||
pkg_dir: Optional custom package directory
|
||||
args: Additional arguments to pass
|
||||
env: Custom environment variables
|
||||
|
||||
Returns:
|
||||
Dict with execution result
|
||||
"""
|
||||
try:
|
||||
# Determine working directory
|
||||
if pkg_dir is None:
|
||||
work_dir = self.cache_dir / plugin_id
|
||||
else:
|
||||
work_dir = Path(pkg_dir)
|
||||
|
||||
if not work_dir.exists():
|
||||
return {
|
||||
'status': 'error',
|
||||
'error': f'Plugin directory not found: {work_dir}'
|
||||
}
|
||||
|
||||
# Determine if it's an npm script or direct node execution
|
||||
if script.endswith('.js') or script.endswith('.ts'):
|
||||
# Direct Node.js execution
|
||||
cmd = [self.node_path, script]
|
||||
if args:
|
||||
cmd.extend(args)
|
||||
else:
|
||||
# NPM script execution
|
||||
cmd = [self.npm_path, 'run', script]
|
||||
if args:
|
||||
cmd.append('--')
|
||||
cmd.extend(args)
|
||||
|
||||
# Prepare environment
|
||||
run_env = os.environ.copy()
|
||||
if env:
|
||||
run_env.update(env)
|
||||
|
||||
# Execute
|
||||
result = subprocess.run(
|
||||
cmd,
|
||||
cwd=str(work_dir),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=300,
|
||||
env=run_env
|
||||
)
|
||||
|
||||
return {
|
||||
'status': 'success' if result.returncode == 0 else 'error',
|
||||
'plugin_id': plugin_id,
|
||||
'script': script,
|
||||
'exit_code': result.returncode,
|
||||
'stdout': result.stdout,
|
||||
'stderr': result.stderr,
|
||||
'work_dir': str(work_dir)
|
||||
}
|
||||
except subprocess.TimeoutExpired as e:
|
||||
return {
|
||||
'status': 'error',
|
||||
'plugin_id': plugin_id,
|
||||
'script': script,
|
||||
'error': f'Execution timeout: {str(e)}'
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
'status': 'error',
|
||||
'plugin_id': plugin_id,
|
||||
'script': script,
|
||||
'error': str(e)
|
||||
}
|
||||
|
||||
def list_packages(self, plugin_id: str,
|
||||
pkg_dir: Optional[Path] = None) -> Dict[str, Any]:
|
||||
"""
|
||||
List installed packages in a plugin directory.
|
||||
|
||||
Args:
|
||||
plugin_id: Unique identifier for the plugin
|
||||
pkg_dir: Optional custom package directory
|
||||
|
||||
Returns:
|
||||
Dict with list of installed packages
|
||||
"""
|
||||
try:
|
||||
# Determine working directory
|
||||
if pkg_dir is None:
|
||||
work_dir = self.cache_dir / plugin_id
|
||||
else:
|
||||
work_dir = Path(pkg_dir)
|
||||
|
||||
if not work_dir.exists():
|
||||
return {
|
||||
'status': 'error',
|
||||
'error': f'Plugin directory not found: {work_dir}'
|
||||
}
|
||||
|
||||
# Run npm list
|
||||
result = subprocess.run(
|
||||
[self.npm_path, 'list', '--json', '--depth=0'],
|
||||
cwd=str(work_dir),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=60
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
try:
|
||||
packages = json.loads(result.stdout)
|
||||
return {
|
||||
'status': 'success',
|
||||
'plugin_id': plugin_id,
|
||||
'packages': packages.get('dependencies', {}),
|
||||
'work_dir': str(work_dir)
|
||||
}
|
||||
except json.JSONDecodeError as e:
|
||||
return {
|
||||
'status': 'error',
|
||||
'plugin_id': plugin_id,
|
||||
'error': f'Failed to parse npm list output: {str(e)}',
|
||||
'raw_output': result.stdout
|
||||
}
|
||||
else:
|
||||
return {
|
||||
'status': 'error',
|
||||
'plugin_id': plugin_id,
|
||||
'error': result.stderr,
|
||||
'work_dir': str(work_dir)
|
||||
}
|
||||
except subprocess.TimeoutExpired as e:
|
||||
return {
|
||||
'status': 'error',
|
||||
'plugin_id': plugin_id,
|
||||
'error': f'Timeout listing packages: {str(e)}'
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
'status': 'error',
|
||||
'plugin_id': plugin_id,
|
||||
'error': str(e)
|
||||
}
|
||||
|
||||
def init_project(self, plugin_id: str, pkg_dir: Optional[Path] = None,
|
||||
package_name: Optional[str] = None,
|
||||
version: str = "1.0.0") -> Dict[str, Any]:
|
||||
"""
|
||||
Initialize a new Node.js project in a plugin directory.
|
||||
|
||||
Args:
|
||||
plugin_id: Unique identifier for the plugin
|
||||
pkg_dir: Optional custom package directory
|
||||
package_name: Optional package name (defaults to plugin_id)
|
||||
version: Package version
|
||||
|
||||
Returns:
|
||||
Dict with initialization result
|
||||
"""
|
||||
try:
|
||||
# Determine working directory
|
||||
if pkg_dir is None:
|
||||
work_dir = self.cache_dir / plugin_id
|
||||
else:
|
||||
work_dir = Path(pkg_dir)
|
||||
|
||||
work_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Create package.json
|
||||
package_json = {
|
||||
'name': package_name or plugin_id.replace('/', '-'),
|
||||
'version': version,
|
||||
'description': f'Node.js project for plugin {plugin_id}',
|
||||
'main': 'index.js',
|
||||
'scripts': {
|
||||
'start': 'node index.js',
|
||||
'test': 'echo "Error: no test specified" && exit 1'
|
||||
},
|
||||
'keywords': [],
|
||||
'author': '',
|
||||
'license': 'ISC'
|
||||
}
|
||||
|
||||
package_json_path = work_dir / 'package.json'
|
||||
with open(package_json_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(package_json, f, indent=2)
|
||||
|
||||
# Create basic index.js
|
||||
index_js_path = work_dir / 'index.js'
|
||||
with open(index_js_path, 'w', encoding='utf-8') as f:
|
||||
f.write('// Node.js project for NebulaShell plugin\n')
|
||||
f.write(f'// Plugin ID: {plugin_id}\n')
|
||||
f.write('console.log("Hello from NebulaShell Node.js plugin!");\n')
|
||||
|
||||
return {
|
||||
'status': 'success',
|
||||
'plugin_id': plugin_id,
|
||||
'work_dir': str(work_dir),
|
||||
'package_json': str(package_json_path),
|
||||
'index_js': str(index_js_path)
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
'status': 'error',
|
||||
'plugin_id': plugin_id,
|
||||
'error': str(e)
|
||||
}
|
||||
|
||||
|
||||
# Plugin lifecycle hooks
|
||||
def init(config: Dict[str, Any]) -> NodeJSAdapter:
|
||||
"""Initialize the Node.js adapter plugin."""
|
||||
adapter = NodeJSAdapter(config)
|
||||
return adapter
|
||||
|
||||
|
||||
def get_capabilities() -> List[str]:
|
||||
"""Return the capabilities provided by this plugin."""
|
||||
return [
|
||||
'nodejs_runtime',
|
||||
'npm_package_manager',
|
||||
'dependency_isolation',
|
||||
'script_execution',
|
||||
'project_initialization'
|
||||
]
|
||||
|
||||
|
||||
def execute_command(adapter: NodeJSAdapter, command: str, **kwargs) -> Dict[str, Any]:
|
||||
"""
|
||||
Execute a command through the adapter.
|
||||
|
||||
Available commands:
|
||||
- check_versions: Check Node.js and npm versions
|
||||
- install: Install npm packages
|
||||
- run: Execute Node.js scripts or npm commands
|
||||
- list_packages: List installed packages
|
||||
- init_project: Initialize a new Node.js project
|
||||
"""
|
||||
if command == 'check_versions':
|
||||
return adapter.check_versions()
|
||||
elif command == 'install':
|
||||
return adapter.install(**kwargs)
|
||||
elif command == 'run':
|
||||
return adapter.run(**kwargs)
|
||||
elif command == 'list_packages':
|
||||
return adapter.list_packages(**kwargs)
|
||||
elif command == 'init_project':
|
||||
return adapter.init_project(**kwargs)
|
||||
else:
|
||||
return {
|
||||
'status': 'error',
|
||||
'error': f'Unknown command: {command}'
|
||||
}
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Test the adapter
|
||||
print("Node.js Adapter Plugin for NebulaShell")
|
||||
print("=" * 50)
|
||||
|
||||
adapter = init({})
|
||||
|
||||
# Check versions
|
||||
versions = adapter.check_versions()
|
||||
print(f"\nNode.js Version: {versions.get('node', 'N/A')}")
|
||||
print(f"npm Version: {versions.get('npm', 'N/A')}")
|
||||
|
||||
# Get capabilities
|
||||
caps = get_capabilities()
|
||||
print(f"\nCapabilities: {', '.join(caps)}")
|
||||
|
||||
print("\n✓ Node.js Adapter initialized successfully!")
|
||||
30
store/@{NebulaShell}/nodejs-adapter/manifest.json
Normal file
30
store/@{NebulaShell}/nodejs-adapter/manifest.json
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"name": "@NebulaShell/nodejs-adapter",
|
||||
"version": "1.2.0",
|
||||
"description": "Node.js runtime adapter for NebulaShell - provides Node.js and npm capabilities for other plugins",
|
||||
"author": "NebulaShell Team",
|
||||
"license": "MIT",
|
||||
"runtime": {
|
||||
"type": "python",
|
||||
"entry_point": "main.py",
|
||||
"requirements": ["subprocess", "json", "os", "shutil"]
|
||||
},
|
||||
"capabilities": [
|
||||
"nodejs_runtime",
|
||||
"npm_package_manager",
|
||||
"dependency_isolation",
|
||||
"script_execution"
|
||||
],
|
||||
"config": {
|
||||
"node_path": "/usr/bin/node",
|
||||
"npm_path": "/usr/bin/npm",
|
||||
"default_registry": "https://registry.npmjs.org",
|
||||
"cache_dir": "~/.nebulashell/nodejs-cache"
|
||||
},
|
||||
"api": {
|
||||
"install": "Install npm packages to plugin-specific directory",
|
||||
"run": "Execute Node.js scripts or npm commands",
|
||||
"check_version": "Check Node.js and npm versions",
|
||||
"list_packages": "List installed packages in a plugin directory"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user