@darksol/terminal 0.2.0 → 0.2.1
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.
- package/package.json +1 -1
- package/skill/SKILL.md +177 -0
- package/src/cli.js +29 -0
- package/src/services/skills.js +229 -0
- package/src/ui/banner.js +3 -2
package/package.json
CHANGED
package/skill/SKILL.md
ADDED
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: darksol-terminal
|
|
3
|
+
description: "DARKSOL Terminal — unified CLI for trading, wallets, execution scripts, AI-powered market analysis, secure agent signing, and all DARKSOL services. Use when: (1) swapping/sniping tokens on Base/Ethereum/L2s, (2) managing encrypted wallets, (3) running automated trading scripts, (4) DCA strategies, (5) market intel lookups, (6) on-chain oracle/casino/cards, (7) natural language trading via LLM, (8) signing transactions securely for x402/contracts without exposing private keys."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# DARKSOL Terminal
|
|
7
|
+
|
|
8
|
+
**All DARKSOL services. One terminal. Zero trust required. 🌑**
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install -g @darksol/terminal
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Quick Reference
|
|
17
|
+
|
|
18
|
+
### Wallet Management
|
|
19
|
+
```bash
|
|
20
|
+
darksol wallet create <name> # Create new wallet (AES-256-GCM encrypted)
|
|
21
|
+
darksol wallet import <name> # Import from private key
|
|
22
|
+
darksol wallet list # List all wallets
|
|
23
|
+
darksol wallet balance [name] # Check ETH + USDC balance
|
|
24
|
+
darksol wallet use <name> # Set active wallet
|
|
25
|
+
darksol wallet export [name] # Export details (password required for PK)
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
### Trading
|
|
29
|
+
```bash
|
|
30
|
+
darksol trade swap -i ETH -o USDC -a 0.1 # Swap via Uniswap V3
|
|
31
|
+
darksol trade snipe <token> -a 0.05 # Fast buy with gas boost
|
|
32
|
+
darksol trade snipe <token> -a 0.05 -g 2.0 # Snipe with 2x gas priority
|
|
33
|
+
darksol trade watch # Monitor new pairs
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### DCA (Dollar-Cost Averaging)
|
|
37
|
+
```bash
|
|
38
|
+
darksol dca create # Interactive DCA order creation
|
|
39
|
+
darksol dca list # List active DCA orders
|
|
40
|
+
darksol dca run # Execute pending orders
|
|
41
|
+
darksol dca cancel <id> # Cancel an order
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### AI Trading Assistant
|
|
45
|
+
```bash
|
|
46
|
+
darksol ai chat # Interactive AI trading chat
|
|
47
|
+
darksol ai ask "buy 0.5 ETH of AERO" # Parse natural language trade intent
|
|
48
|
+
darksol ai strategy VIRTUAL -b 500 # DCA strategy recommendation
|
|
49
|
+
darksol ai analyze AERO # AI-powered token analysis
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Execution Scripts
|
|
53
|
+
```bash
|
|
54
|
+
darksol script templates # List available templates
|
|
55
|
+
darksol script create # Create from template (buy, sell, limit-buy, stop-loss, etc.)
|
|
56
|
+
darksol script list # List saved scripts
|
|
57
|
+
darksol script run <name> # Execute (requires wallet password)
|
|
58
|
+
darksol script run <name> -p "pw" -y # Non-interactive (for automation/cron)
|
|
59
|
+
darksol script show <name> # View code + params
|
|
60
|
+
darksol script edit <name> # Edit params/wallet/chain
|
|
61
|
+
darksol script clone <name> <new> # Clone a script
|
|
62
|
+
darksol script delete <name> # Delete a script
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Script templates: `buy-token`, `sell-token`, `limit-buy`, `stop-loss`, `multi-buy`, `transfer`, `empty` (custom)
|
|
66
|
+
|
|
67
|
+
### Market Intel
|
|
68
|
+
```bash
|
|
69
|
+
darksol market top # Top movers on Base
|
|
70
|
+
darksol market top -c ethereum # Top movers on Ethereum
|
|
71
|
+
darksol market token VIRTUAL # Full token detail
|
|
72
|
+
darksol market compare ETH AERO VIRTUAL # Side-by-side comparison
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Secure Agent Signer (for OpenClaw / AI agents)
|
|
76
|
+
```bash
|
|
77
|
+
darksol agent start <wallet> # Start signing proxy
|
|
78
|
+
darksol agent start <wallet> --max-value 0.5 --daily-limit 2.0
|
|
79
|
+
darksol agent docs # Full security documentation
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The agent signer creates a local HTTP server at `127.0.0.1:18790` that signs transactions without exposing the private key. AI agents authenticate with a one-time bearer token.
|
|
83
|
+
|
|
84
|
+
**Endpoints:**
|
|
85
|
+
- `GET /address` — wallet address
|
|
86
|
+
- `GET /balance` — ETH balance
|
|
87
|
+
- `POST /send` — sign + broadcast transaction
|
|
88
|
+
- `POST /sign-message` — sign EIP-191 message (x402)
|
|
89
|
+
- `POST /sign-typed-data` — sign EIP-712 typed data (x402)
|
|
90
|
+
- `GET /policy` — spending limits
|
|
91
|
+
- `GET /audit` — operation log
|
|
92
|
+
|
|
93
|
+
### Oracle
|
|
94
|
+
```bash
|
|
95
|
+
darksol oracle flip # Coin flip
|
|
96
|
+
darksol oracle dice 20 # Roll d20
|
|
97
|
+
darksol oracle number 1 100 # Random 1-100
|
|
98
|
+
darksol oracle shuffle a b c d # Shuffle list
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Casino
|
|
102
|
+
```bash
|
|
103
|
+
darksol casino bet coin-flip heads # Place a bet
|
|
104
|
+
darksol casino tables # View games
|
|
105
|
+
darksol casino stats # House stats
|
|
106
|
+
darksol casino receipt <id> # Verify on-chain
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Prepaid Cards
|
|
110
|
+
```bash
|
|
111
|
+
darksol cards catalog # Available providers
|
|
112
|
+
darksol cards order -p swype -a 50 # Order a card
|
|
113
|
+
darksol cards status <id> # Check order
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Builder Index
|
|
117
|
+
```bash
|
|
118
|
+
darksol builders leaderboard # ERC-8021 builder rankings
|
|
119
|
+
darksol builders lookup <code> # Builder profile
|
|
120
|
+
darksol builders feed # Recent transactions
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Facilitator
|
|
124
|
+
```bash
|
|
125
|
+
darksol facilitator health # Status
|
|
126
|
+
darksol facilitator verify <payment> # Verify off-chain
|
|
127
|
+
darksol facilitator settle <payment> # Settle on-chain (free)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### API Keys
|
|
131
|
+
```bash
|
|
132
|
+
darksol keys list # Show all services + status
|
|
133
|
+
darksol keys add openai # Add OpenAI key
|
|
134
|
+
darksol keys add coingecko # Add CoinGecko Pro key
|
|
135
|
+
darksol keys add alchemy # Add Alchemy RPC key
|
|
136
|
+
darksol keys remove <service> # Remove a key
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Supported: `openai`, `anthropic`, `openrouter`, `ollama`, `coingecko`, `dexscreener`, `alchemy`, `infura`, `quicknode`, `oneinch`, `paraswap`
|
|
140
|
+
|
|
141
|
+
### Configuration
|
|
142
|
+
```bash
|
|
143
|
+
darksol config show # View all settings
|
|
144
|
+
darksol config set chain base # Set active chain
|
|
145
|
+
darksol config set slippage 1.0 # Set slippage %
|
|
146
|
+
darksol config rpc base https://... # Custom RPC endpoint
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Reference
|
|
150
|
+
```bash
|
|
151
|
+
darksol tips # Trading + scripting tips
|
|
152
|
+
darksol tips --trading # Trading tips only
|
|
153
|
+
darksol networks # Chain reference table
|
|
154
|
+
darksol quickstart # Getting started guide
|
|
155
|
+
darksol lookup 0x... # Look up address on-chain
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Supported Chains
|
|
159
|
+
- **Base** (default) — chain ID 8453
|
|
160
|
+
- **Ethereum** — chain ID 1
|
|
161
|
+
- **Polygon** — chain ID 137
|
|
162
|
+
- **Arbitrum** — chain ID 42161
|
|
163
|
+
- **Optimism** — chain ID 10
|
|
164
|
+
|
|
165
|
+
## Agent Integration Notes
|
|
166
|
+
|
|
167
|
+
- All commands work non-interactively with flags (`-p`, `-y`, `--key`, etc.)
|
|
168
|
+
- Set `darksol config set output json` for programmatic JSON responses
|
|
169
|
+
- Scripts can be executed via cron: `darksol script run my-dca -p "pass" -y`
|
|
170
|
+
- The agent signer is the recommended way to give AI agents wallet access
|
|
171
|
+
- Helper functions available at `@darksol/terminal/src/utils/helpers.js`
|
|
172
|
+
|
|
173
|
+
## Security
|
|
174
|
+
- Private keys encrypted with AES-256-GCM + scrypt KDF
|
|
175
|
+
- Agent signer: PK never exposed, loopback-only, bearer auth, spending limits
|
|
176
|
+
- Dangerous contract calls (transferOwnership, selfdestruct) blocked by default
|
|
177
|
+
- Full audit logging on all signing operations
|
package/src/cli.js
CHANGED
|
@@ -18,6 +18,7 @@ import { showTradingTips, showScriptTips, showNetworkReference, showQuickStart,
|
|
|
18
18
|
import { addKey, removeKey, listKeys } from './config/keys.js';
|
|
19
19
|
import { parseIntent, startChat, adviseStrategy, analyzeToken } from './llm/intent.js';
|
|
20
20
|
import { startAgentSigner, showAgentDocs } from './wallet/agent-signer.js';
|
|
21
|
+
import { listSkills, installSkill, skillInfo, uninstallSkill } from './services/skills.js';
|
|
21
22
|
|
|
22
23
|
export function cli(argv) {
|
|
23
24
|
const program = new Command();
|
|
@@ -385,6 +386,33 @@ export function cli(argv) {
|
|
|
385
386
|
.description('Show agent signer security documentation')
|
|
386
387
|
.action(() => showAgentDocs());
|
|
387
388
|
|
|
389
|
+
// ═══════════════════════════════════════
|
|
390
|
+
// SKILLS COMMANDS
|
|
391
|
+
// ═══════════════════════════════════════
|
|
392
|
+
const skills = program
|
|
393
|
+
.command('skills')
|
|
394
|
+
.description('DARKSOL skills directory — install agent skills');
|
|
395
|
+
|
|
396
|
+
skills
|
|
397
|
+
.command('list')
|
|
398
|
+
.description('List all available DARKSOL skills')
|
|
399
|
+
.action(() => listSkills());
|
|
400
|
+
|
|
401
|
+
skills
|
|
402
|
+
.command('install <name>')
|
|
403
|
+
.description('Install a skill to OpenClaw')
|
|
404
|
+
.action((name) => installSkill(name));
|
|
405
|
+
|
|
406
|
+
skills
|
|
407
|
+
.command('info <name>')
|
|
408
|
+
.description('Show skill details')
|
|
409
|
+
.action((name) => skillInfo(name));
|
|
410
|
+
|
|
411
|
+
skills
|
|
412
|
+
.command('uninstall <name>')
|
|
413
|
+
.description('Uninstall a skill')
|
|
414
|
+
.action((name) => uninstallSkill(name));
|
|
415
|
+
|
|
388
416
|
// ═══════════════════════════════════════
|
|
389
417
|
// TIPS & REFERENCE COMMANDS
|
|
390
418
|
// ═══════════════════════════════════════
|
|
@@ -572,6 +600,7 @@ export function cli(argv) {
|
|
|
572
600
|
['cards', 'Prepaid Visa/MC cards'],
|
|
573
601
|
['builders', 'ERC-8021 builder index'],
|
|
574
602
|
['facilitator', 'x402 payment facilitator'],
|
|
603
|
+
['skills', 'Agent skill directory & install'],
|
|
575
604
|
['config', 'Terminal configuration'],
|
|
576
605
|
['tips', 'Trading & scripting tips'],
|
|
577
606
|
['networks', 'Chain reference & explorers'],
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import fetch from 'node-fetch';
|
|
2
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync, readdirSync, cpSync } from 'fs';
|
|
3
|
+
import { join, dirname } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { theme } from '../ui/theme.js';
|
|
7
|
+
import { spinner, kvDisplay, success, error, warn, info, table } from '../ui/components.js';
|
|
8
|
+
import { showSection } from '../ui/banner.js';
|
|
9
|
+
|
|
10
|
+
const OPENCLAW_SKILLS_DIR = join(homedir(), '.openclaw', 'skills');
|
|
11
|
+
|
|
12
|
+
// ──────────────────────────────────────────────────
|
|
13
|
+
// DARKSOL SKILL CATALOG
|
|
14
|
+
// ──────────────────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
const SKILL_CATALOG = [
|
|
17
|
+
{
|
|
18
|
+
name: 'darksol-terminal',
|
|
19
|
+
description: 'DARKSOL Terminal — unified CLI for trading, wallets, scripts, AI assistant, agent signing',
|
|
20
|
+
version: '0.2.0',
|
|
21
|
+
source: 'local', // bundled with the package
|
|
22
|
+
category: 'trading',
|
|
23
|
+
installed: () => existsSync(join(OPENCLAW_SKILLS_DIR, 'darksol-terminal', 'SKILL.md')),
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: 'darksol-facilitator',
|
|
27
|
+
description: 'Free on-chain x402 payment facilitator — verify and settle micropayments',
|
|
28
|
+
version: '1.0.0',
|
|
29
|
+
source: 'url',
|
|
30
|
+
url: 'https://facilitator.darksol.net/skill/SKILL.md',
|
|
31
|
+
category: 'payments',
|
|
32
|
+
installed: () => existsSync(join(OPENCLAW_SKILLS_DIR, 'darksol-facilitator', 'SKILL.md')),
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'darksol-prepaid-cards',
|
|
36
|
+
description: 'Crypto → prepaid Visa/MC cards, no KYC, agent-native REST API',
|
|
37
|
+
version: '1.0.0',
|
|
38
|
+
source: 'url',
|
|
39
|
+
url: 'https://acp.darksol.net/dist/darksol-prepaid-cards.skill',
|
|
40
|
+
skillMdUrl: 'https://acp.darksol.net/cards/skill/SKILL.md',
|
|
41
|
+
category: 'payments',
|
|
42
|
+
installed: () => existsSync(join(OPENCLAW_SKILLS_DIR, 'darksol-prepaid-cards', 'SKILL.md')),
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'random-oracle',
|
|
46
|
+
description: 'On-chain random oracle — verifiable randomness via x402',
|
|
47
|
+
version: '1.0.0',
|
|
48
|
+
source: 'url',
|
|
49
|
+
url: 'https://acp.darksol.net/oracle/skill/SKILL.md',
|
|
50
|
+
category: 'oracle',
|
|
51
|
+
installed: () => existsSync(join(OPENCLAW_SKILLS_DIR, 'random-oracle', 'SKILL.md')),
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'the-clawsino',
|
|
55
|
+
description: 'On-chain agent casino — coin flip, dice, hi-lo, slots via x402',
|
|
56
|
+
version: '1.0.0',
|
|
57
|
+
source: 'url',
|
|
58
|
+
url: 'https://casino.darksol.net/skill/SKILL.md',
|
|
59
|
+
category: 'gaming',
|
|
60
|
+
installed: () => existsSync(join(OPENCLAW_SKILLS_DIR, 'the-clawsino', 'SKILL.md')),
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
// ──────────────────────────────────────────────────
|
|
65
|
+
// LIST SKILLS
|
|
66
|
+
// ──────────────────────────────────────────────────
|
|
67
|
+
|
|
68
|
+
export function listSkills() {
|
|
69
|
+
showSection('DARKSOL SKILLS DIRECTORY');
|
|
70
|
+
|
|
71
|
+
const rows = SKILL_CATALOG.map(s => {
|
|
72
|
+
const isInstalled = s.installed();
|
|
73
|
+
return [
|
|
74
|
+
isInstalled ? theme.success('● ') + theme.gold(s.name) : theme.dim('○ ') + s.name,
|
|
75
|
+
s.description.slice(0, 55) + (s.description.length > 55 ? '...' : ''),
|
|
76
|
+
s.version,
|
|
77
|
+
isInstalled ? theme.success('Installed') : theme.dim('Available'),
|
|
78
|
+
];
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
table(['Skill', 'Description', 'Version', 'Status'], rows);
|
|
82
|
+
|
|
83
|
+
console.log('');
|
|
84
|
+
info('Install: darksol skills install <name>');
|
|
85
|
+
info('Info: darksol skills info <name>');
|
|
86
|
+
info('Skills install to: ' + OPENCLAW_SKILLS_DIR);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// ──────────────────────────────────────────────────
|
|
90
|
+
// INSTALL SKILL
|
|
91
|
+
// ──────────────────────────────────────────────────
|
|
92
|
+
|
|
93
|
+
export async function installSkill(name) {
|
|
94
|
+
const skill = SKILL_CATALOG.find(s => s.name === name);
|
|
95
|
+
|
|
96
|
+
if (!skill) {
|
|
97
|
+
error(`Unknown skill: ${name}`);
|
|
98
|
+
info('Available: ' + SKILL_CATALOG.map(s => s.name).join(', '));
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
if (skill.installed()) {
|
|
103
|
+
warn(`${name} is already installed`);
|
|
104
|
+
const inquirer = (await import('inquirer')).default;
|
|
105
|
+
const { reinstall } = await inquirer.prompt([{
|
|
106
|
+
type: 'confirm',
|
|
107
|
+
name: 'reinstall',
|
|
108
|
+
message: theme.gold('Reinstall / update?'),
|
|
109
|
+
default: false,
|
|
110
|
+
}]);
|
|
111
|
+
if (!reinstall) return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const spin = spinner(`Installing ${name}...`).start();
|
|
115
|
+
|
|
116
|
+
try {
|
|
117
|
+
const targetDir = join(OPENCLAW_SKILLS_DIR, name);
|
|
118
|
+
mkdirSync(targetDir, { recursive: true });
|
|
119
|
+
|
|
120
|
+
if (skill.source === 'local') {
|
|
121
|
+
// Copy from the npm package's bundled skill directory
|
|
122
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
123
|
+
const bundledSkillDir = join(__dirname, '..', '..', 'skill');
|
|
124
|
+
|
|
125
|
+
if (existsSync(join(bundledSkillDir, 'SKILL.md'))) {
|
|
126
|
+
const skillContent = readFileSync(join(bundledSkillDir, 'SKILL.md'), 'utf8');
|
|
127
|
+
writeFileSync(join(targetDir, 'SKILL.md'), skillContent);
|
|
128
|
+
} else {
|
|
129
|
+
throw new Error('Bundled SKILL.md not found in package');
|
|
130
|
+
}
|
|
131
|
+
} else if (skill.source === 'url') {
|
|
132
|
+
// Fetch from remote
|
|
133
|
+
const url = skill.skillMdUrl || skill.url;
|
|
134
|
+
const resp = await fetch(url);
|
|
135
|
+
if (!resp.ok) throw new Error(`Failed to fetch: ${resp.status}`);
|
|
136
|
+
const content = await resp.text();
|
|
137
|
+
|
|
138
|
+
// Handle .skill files (may be a zip or just SKILL.md content)
|
|
139
|
+
if (url.endsWith('.skill')) {
|
|
140
|
+
// .skill files are typically just the SKILL.md content
|
|
141
|
+
writeFileSync(join(targetDir, 'SKILL.md'), content);
|
|
142
|
+
} else {
|
|
143
|
+
writeFileSync(join(targetDir, 'SKILL.md'), content);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
spin.succeed(`${name} installed`);
|
|
148
|
+
|
|
149
|
+
showSection(`INSTALLED: ${name}`);
|
|
150
|
+
kvDisplay([
|
|
151
|
+
['Name', name],
|
|
152
|
+
['Version', skill.version],
|
|
153
|
+
['Category', skill.category],
|
|
154
|
+
['Location', targetDir],
|
|
155
|
+
]);
|
|
156
|
+
console.log('');
|
|
157
|
+
success('Skill is now available to OpenClaw and other agents');
|
|
158
|
+
|
|
159
|
+
} catch (err) {
|
|
160
|
+
spin.fail(`Failed to install ${name}`);
|
|
161
|
+
error(err.message);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// ──────────────────────────────────────────────────
|
|
166
|
+
// SKILL INFO
|
|
167
|
+
// ──────────────────────────────────────────────────
|
|
168
|
+
|
|
169
|
+
export async function skillInfo(name) {
|
|
170
|
+
const skill = SKILL_CATALOG.find(s => s.name === name);
|
|
171
|
+
|
|
172
|
+
if (!skill) {
|
|
173
|
+
error(`Unknown skill: ${name}`);
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const isInstalled = skill.installed();
|
|
178
|
+
|
|
179
|
+
showSection(`SKILL: ${name}`);
|
|
180
|
+
kvDisplay([
|
|
181
|
+
['Name', skill.name],
|
|
182
|
+
['Description', skill.description],
|
|
183
|
+
['Version', skill.version],
|
|
184
|
+
['Category', skill.category],
|
|
185
|
+
['Status', isInstalled ? theme.success('Installed') : theme.dim('Not installed')],
|
|
186
|
+
['Source', skill.source === 'local' ? 'Bundled with @darksol/terminal' : skill.url || 'Remote'],
|
|
187
|
+
]);
|
|
188
|
+
|
|
189
|
+
if (isInstalled) {
|
|
190
|
+
const skillPath = join(OPENCLAW_SKILLS_DIR, name, 'SKILL.md');
|
|
191
|
+
console.log('');
|
|
192
|
+
console.log(theme.dim(` Location: ${skillPath}`));
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
console.log('');
|
|
196
|
+
if (!isInstalled) {
|
|
197
|
+
info(`Install: darksol skills install ${name}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// ──────────────────────────────────────────────────
|
|
202
|
+
// UNINSTALL SKILL
|
|
203
|
+
// ──────────────────────────────────────────────────
|
|
204
|
+
|
|
205
|
+
export async function uninstallSkill(name) {
|
|
206
|
+
const skill = SKILL_CATALOG.find(s => s.name === name);
|
|
207
|
+
const skillDir = join(OPENCLAW_SKILLS_DIR, name);
|
|
208
|
+
|
|
209
|
+
if (!existsSync(skillDir)) {
|
|
210
|
+
error(`${name} is not installed`);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const inquirer = (await import('inquirer')).default;
|
|
215
|
+
const { confirm } = await inquirer.prompt([{
|
|
216
|
+
type: 'confirm',
|
|
217
|
+
name: 'confirm',
|
|
218
|
+
message: theme.accent(`Uninstall ${name}?`),
|
|
219
|
+
default: false,
|
|
220
|
+
}]);
|
|
221
|
+
|
|
222
|
+
if (!confirm) return;
|
|
223
|
+
|
|
224
|
+
const { rmSync } = await import('fs');
|
|
225
|
+
rmSync(skillDir, { recursive: true, force: true });
|
|
226
|
+
success(`${name} uninstalled`);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export { SKILL_CATALOG, OPENCLAW_SKILLS_DIR };
|
package/src/ui/banner.js
CHANGED
|
@@ -26,7 +26,7 @@ export function showBanner(opts = {}) {
|
|
|
26
26
|
);
|
|
27
27
|
console.log(
|
|
28
28
|
theme.dim(' ║ ') +
|
|
29
|
-
theme.subtle(' v0.2.
|
|
29
|
+
theme.subtle(' v0.2.1') +
|
|
30
30
|
theme.dim(' ') +
|
|
31
31
|
theme.gold('🌑') +
|
|
32
32
|
theme.dim(' ║')
|
|
@@ -44,7 +44,7 @@ export function showBanner(opts = {}) {
|
|
|
44
44
|
|
|
45
45
|
export function showMiniBanner() {
|
|
46
46
|
console.log('');
|
|
47
|
-
console.log(theme.gold.bold(' 🌑 DARKSOL TERMINAL') + theme.dim(' v0.2.
|
|
47
|
+
console.log(theme.gold.bold(' 🌑 DARKSOL TERMINAL') + theme.dim(' v0.2.1'));
|
|
48
48
|
console.log(theme.dim(' ─────────────────────────────'));
|
|
49
49
|
console.log('');
|
|
50
50
|
}
|
|
@@ -60,3 +60,4 @@ export function showDivider() {
|
|
|
60
60
|
}
|
|
61
61
|
|
|
62
62
|
|
|
63
|
+
|