0xkobold 0.4.3 → 0.5.0
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/README.md +226 -383
- package/dist/package.json +13 -4
- package/dist/src/agent/DraconicCapabilityRouter.js +556 -0
- package/dist/src/agent/DraconicCapabilityRouter.js.map +1 -0
- package/dist/src/agent/DraconicErrorClassifier.js +606 -0
- package/dist/src/agent/DraconicErrorClassifier.js.map +1 -0
- package/dist/src/agent/DraconicRunRegistry.js +460 -0
- package/dist/src/agent/DraconicRunRegistry.js.map +1 -0
- package/dist/src/agent/DraconicTokenPredictor.js +500 -0
- package/dist/src/agent/DraconicTokenPredictor.js.map +1 -0
- package/dist/src/agent/embedded-runner.js +3 -2
- package/dist/src/agent/embedded-runner.js.map +1 -1
- package/dist/src/cli/commands/doctor.js +199 -0
- package/dist/src/cli/commands/doctor.js.map +1 -0
- package/dist/src/cli/commands/migrate-from-openclaw.js +39 -0
- package/dist/src/cli/commands/migrate-from-openclaw.js.map +1 -0
- package/dist/src/cli/commands/migrate.js +6 -4
- package/dist/src/cli/commands/migrate.js.map +1 -1
- package/dist/src/cli/program.js +3 -1
- package/dist/src/cli/program.js.map +1 -1
- package/dist/src/config/unified-config.js +195 -0
- package/dist/src/config/unified-config.js.map +1 -0
- package/dist/src/cron/notifications.js +1 -1
- package/dist/src/cron/notifications.js.map +1 -1
- package/dist/src/cron/runner.js +9 -3
- package/dist/src/cron/runner.js.map +1 -1
- package/dist/src/event-bus/index.js +3 -1
- package/dist/src/event-bus/index.js.map +1 -1
- package/dist/src/extensions/community/draconic-messenger-wrapper.js +35 -0
- package/dist/src/extensions/community/draconic-messenger-wrapper.js.map +1 -0
- package/dist/src/extensions/community/draconic-subagents-wrapper.js +115 -0
- package/dist/src/extensions/community/draconic-subagents-wrapper.js.map +1 -0
- package/dist/src/extensions/core/compaction-safeguard-v2.js +95 -0
- package/dist/src/extensions/core/compaction-safeguard-v2.js.map +1 -0
- package/dist/src/extensions/core/compaction-safeguard.js +206 -137
- package/dist/src/extensions/core/compaction-safeguard.js.map +1 -1
- package/dist/src/extensions/core/config-extension.js +122 -0
- package/dist/src/extensions/core/config-extension.js.map +1 -0
- package/dist/src/extensions/core/draconic-hoard-extension.js +194 -0
- package/dist/src/extensions/core/draconic-hoard-extension.js.map +1 -0
- package/dist/src/extensions/core/draconic-lair-extension.js +146 -0
- package/dist/src/extensions/core/draconic-lair-extension.js.map +1 -0
- package/dist/src/extensions/core/draconic-safety-extension.js +402 -0
- package/dist/src/extensions/core/draconic-safety-extension.js.map +1 -0
- package/dist/src/extensions/core/ext-manager.js +40 -0
- package/dist/src/extensions/core/ext-manager.js.map +1 -0
- package/dist/src/extensions/core/gateway-extension.js +413 -624
- package/dist/src/extensions/core/gateway-extension.js.map +1 -1
- package/dist/src/extensions/core/generative-agents-extension.js +704 -0
- package/dist/src/extensions/core/generative-agents-extension.js.map +1 -0
- package/dist/src/extensions/core/memory-bootstrap-extension.js +279 -0
- package/dist/src/extensions/core/memory-bootstrap-extension.js.map +1 -0
- package/dist/src/extensions/core/ollama-extension.js +442 -0
- package/dist/src/extensions/core/ollama-extension.js.map +1 -0
- package/dist/src/extensions/core/ollama-router-extension.js +34 -93
- package/dist/src/extensions/core/ollama-router-extension.js.map +1 -1
- package/dist/src/extensions/core/perennial-memory-extension.js +5 -2
- package/dist/src/extensions/core/perennial-memory-extension.js.map +1 -1
- package/dist/src/extensions/core/persona-loader-extension.js +41 -15
- package/dist/src/extensions/core/persona-loader-extension.js.map +1 -1
- package/dist/src/extensions/core/pi-notify-extension.js +6 -0
- package/dist/src/extensions/core/pi-notify-extension.js.map +1 -1
- package/dist/src/extensions/core/session-bridge-extension.js +8 -72
- package/dist/src/extensions/core/session-bridge-extension.js.map +1 -1
- package/dist/src/extensions/core/tui-integration-extension-fixed.js +3 -0
- package/dist/src/extensions/core/tui-integration-extension-fixed.js.map +1 -0
- package/dist/src/extensions/core/tui-integration-extension.js +984 -0
- package/dist/src/extensions/core/tui-integration-extension.js.map +1 -0
- package/dist/src/gateway/persistence/AgentStore.js +399 -0
- package/dist/src/gateway/persistence/AgentStore.js.map +1 -0
- package/dist/src/gateway/persistence/index.js +9 -0
- package/dist/src/gateway/persistence/index.js.map +1 -0
- package/dist/src/hoard/DraconicHoardSystem.js +465 -0
- package/dist/src/hoard/DraconicHoardSystem.js.map +1 -0
- package/dist/src/index.js +7 -5
- package/dist/src/index.js.map +1 -1
- package/dist/src/infra/DraconicConnectionPool.js +492 -0
- package/dist/src/infra/DraconicConnectionPool.js.map +1 -0
- package/dist/src/lair/DraconicLairSystem.js +387 -0
- package/dist/src/lair/DraconicLairSystem.js.map +1 -0
- package/dist/src/llm/ollama.js +143 -99
- package/dist/src/llm/ollama.js.map +1 -1
- package/dist/src/migration/openclaw.js +5 -5
- package/dist/src/migration/openclaw.js.map +1 -1
- package/dist/src/pi-config.js +52 -27
- package/dist/src/pi-config.js.map +1 -1
- package/dist/src/sessions/SessionManager.js +416 -0
- package/dist/src/sessions/SessionManager.js.map +1 -0
- package/dist/src/sessions/SessionStore.js +580 -0
- package/dist/src/sessions/SessionStore.js.map +1 -0
- package/dist/src/sessions/UnifiedSessionBridge.js +394 -0
- package/dist/src/sessions/UnifiedSessionBridge.js.map +1 -0
- package/dist/src/sessions/index.js +15 -0
- package/dist/src/sessions/index.js.map +1 -0
- package/dist/src/sessions/migration/index.js +156 -0
- package/dist/src/sessions/migration/index.js.map +1 -0
- package/dist/src/sessions/types.js +8 -0
- package/dist/src/sessions/types.js.map +1 -0
- package/dist/src/skills/framework.js +1 -1
- package/dist/src/skills/framework.js.map +1 -1
- package/dist/src/tui/commands/final-functions.js +39 -0
- package/dist/src/tui/commands/final-functions.js.map +1 -0
- package/dist/src/tui/commands/natural-language-commands.js +231 -0
- package/dist/src/tui/commands/natural-language-commands.js.map +1 -0
- package/dist/src/tui/commands/orchestration-commands.js +340 -0
- package/dist/src/tui/commands/orchestration-commands.js.map +1 -0
- package/dist/src/tui/commands/orchestration-final-section.js +84 -0
- package/dist/src/tui/commands/orchestration-final-section.js.map +1 -0
- package/dist/src/tui/components/agent-tree-overlay.js +210 -0
- package/dist/src/tui/components/agent-tree-overlay.js.map +1 -0
- package/dist/src/tui/components/agent-tree-panel.js +229 -0
- package/dist/src/tui/components/agent-tree-panel.js.map +1 -0
- package/dist/src/tui/components/sidebar.js +82 -0
- package/dist/src/tui/components/sidebar.js.map +1 -0
- package/dist/src/tui/components/status-bar.js +115 -0
- package/dist/src/tui/components/status-bar.js.map +1 -0
- package/dist/src/tui/components/tree-header.js +85 -0
- package/dist/src/tui/components/tree-header.js.map +1 -0
- package/dist/src/tui/draconic-tui.js +291 -0
- package/dist/src/tui/draconic-tui.js.map +1 -0
- package/dist/src/tui/index.js +93 -0
- package/dist/src/tui/index.js.map +1 -0
- package/dist/src/tui/pi-tui-integration.js +260 -0
- package/dist/src/tui/pi-tui-integration.js.map +1 -0
- package/dist/src/utils/nl-patterns.js +145 -0
- package/dist/src/utils/nl-patterns.js.map +1 -0
- package/package.json +13 -4
- package/scripts/migrate-from-openclaw.sh +498 -0
- package/HEARTBEAT.md +0 -121
- package/USAGE.md +0 -191
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
#
|
|
3
|
+
# OpenClaw → 0xKobold Migration Script
|
|
4
|
+
# Version: 0.4.5
|
|
5
|
+
# Usage: ./migrate-from-openclaw.sh [--live]
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
set -euo pipefail
|
|
9
|
+
|
|
10
|
+
# Colors
|
|
11
|
+
RED='\033[0;31m'
|
|
12
|
+
GREEN='\033[0;32m'
|
|
13
|
+
YELLOW='\033[1;33m'
|
|
14
|
+
BLUE='\033[0;34m'
|
|
15
|
+
NC='\033[0m' # No Color
|
|
16
|
+
|
|
17
|
+
# Paths
|
|
18
|
+
SOURCE="${SOURCE:-$HOME/.openclaw}"
|
|
19
|
+
TARGET="${TARGET:-$HOME/.0xkobold}"
|
|
20
|
+
MODE="${1:---dry-run}"
|
|
21
|
+
|
|
22
|
+
# Counters
|
|
23
|
+
MIGRATED=0
|
|
24
|
+
WARNINGS=0
|
|
25
|
+
ERRORS=0
|
|
26
|
+
|
|
27
|
+
log() {
|
|
28
|
+
echo -e "${BLUE}[$(date +%H:%M:%S)]${NC} $1"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
success() {
|
|
32
|
+
echo -e "${GREEN}✓${NC} $1"
|
|
33
|
+
((MIGRATED++))
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
warn() {
|
|
37
|
+
echo -e "${YELLOW}⚠${NC} $1"
|
|
38
|
+
((WARNINGS++))
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
error() {
|
|
42
|
+
echo -e "${RED}✗${NC} $1"
|
|
43
|
+
((ERRORS++))
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
dry_run_notice() {
|
|
47
|
+
if [[ "$MODE" == "--dry-run" ]]; then
|
|
48
|
+
echo -e "\n${YELLOW}💡 This is a DRY RUN. Use --live to apply changes.${NC}\n"
|
|
49
|
+
fi
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
# ============== PRE-FLIGHT CHECKS ==============
|
|
53
|
+
|
|
54
|
+
check_prerequisites() {
|
|
55
|
+
log "Checking prerequisites..."
|
|
56
|
+
|
|
57
|
+
if [[ ! -d "$SOURCE" ]]; then
|
|
58
|
+
error "OpenClaw not found at $SOURCE"
|
|
59
|
+
exit 1
|
|
60
|
+
fi
|
|
61
|
+
success "OpenClaw found at $SOURCE"
|
|
62
|
+
|
|
63
|
+
if ! command -v python3 &>/dev/null; then
|
|
64
|
+
error "python3 is required but not installed"
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
67
|
+
success "python3 available"
|
|
68
|
+
|
|
69
|
+
if ! command -v 0xkobold &>/dev/null; then
|
|
70
|
+
error "0xkobold not installed. Run: bun install -g 0xkobold"
|
|
71
|
+
exit 1
|
|
72
|
+
fi
|
|
73
|
+
success "0xkobold CLI found"
|
|
74
|
+
|
|
75
|
+
# Check OpenClaw has required files
|
|
76
|
+
if [[ ! -f "$SOURCE/openclaw.json" ]]; then
|
|
77
|
+
error "openclaw.json not found. Is this a valid OpenClaw installation?"
|
|
78
|
+
exit 1
|
|
79
|
+
fi
|
|
80
|
+
success "OpenClaw config validated"
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
# ============== STEP 1: BACKUP ==============
|
|
84
|
+
|
|
85
|
+
create_backup() {
|
|
86
|
+
log "Creating backup..."
|
|
87
|
+
|
|
88
|
+
if [[ ! -d "$TARGET" ]]; then
|
|
89
|
+
log "Target doesn't exist yet, no backup needed"
|
|
90
|
+
return
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
local backup_dir="${TARGET}.backup.$(date +%Y%m%d-%H%M%S)"
|
|
94
|
+
|
|
95
|
+
if [[ "$MODE" == "--live" ]]; then
|
|
96
|
+
cp -r "$TARGET" "$backup_dir"
|
|
97
|
+
success "Backup created: $backup_dir"
|
|
98
|
+
else
|
|
99
|
+
log "Would create backup: $backup_dir"
|
|
100
|
+
fi
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# ============== STEP 2: CONFIG MIGRATION ==============
|
|
104
|
+
|
|
105
|
+
migrate_config() {
|
|
106
|
+
log "Migrating configuration..."
|
|
107
|
+
|
|
108
|
+
if [[ "$MODE" == "--live" ]]; then
|
|
109
|
+
mkdir -p "$TARGET"
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
python3 << PYTHON_EOF
|
|
113
|
+
import json
|
|
114
|
+
import os
|
|
115
|
+
import sys
|
|
116
|
+
|
|
117
|
+
source = "$SOURCE"
|
|
118
|
+
target = "$TARGET"
|
|
119
|
+
mode = "$MODE"
|
|
120
|
+
|
|
121
|
+
# Load OpenClaw config
|
|
122
|
+
try:
|
|
123
|
+
with open(f"{source}/openclaw.json") as f:
|
|
124
|
+
old_config = json.load(f)
|
|
125
|
+
except Exception as e:
|
|
126
|
+
print(f"ERROR: Could not parse openclaw.json: {e}", file=sys.stderr)
|
|
127
|
+
sys.exit(1)
|
|
128
|
+
|
|
129
|
+
# Build new config
|
|
130
|
+
new_config = {
|
|
131
|
+
"version": "0.4.4",
|
|
132
|
+
"migratedFrom": "openclaw",
|
|
133
|
+
"migratedAt": os.popen("date -Iseconds").read().strip(),
|
|
134
|
+
|
|
135
|
+
# Identity
|
|
136
|
+
"identity": {
|
|
137
|
+
"default": "shalom"
|
|
138
|
+
},
|
|
139
|
+
|
|
140
|
+
# Extensions
|
|
141
|
+
"extensions": [
|
|
142
|
+
"core/mcp",
|
|
143
|
+
"core/heartbeat",
|
|
144
|
+
"core/cron",
|
|
145
|
+
"core/discord-channel",
|
|
146
|
+
"core/memory",
|
|
147
|
+
"core/persona-loader"
|
|
148
|
+
],
|
|
149
|
+
|
|
150
|
+
# Channels
|
|
151
|
+
"channels": {
|
|
152
|
+
"discord": {
|
|
153
|
+
"enabled": old_config.get("channels", {}).get("discord", {}).get("enabled", False)
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
|
|
157
|
+
# LLM
|
|
158
|
+
"llm": {
|
|
159
|
+
"provider": "ollama",
|
|
160
|
+
"model": "qwen2.5-coder:14b"
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
# Cron
|
|
164
|
+
"cron": {
|
|
165
|
+
"enabled": False,
|
|
166
|
+
"database": "cron.db"
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
# Auto-update
|
|
170
|
+
"autoUpdate": {
|
|
171
|
+
"enabled": True,
|
|
172
|
+
"checkInterval": "0 2 * * *",
|
|
173
|
+
"autoInstall": False,
|
|
174
|
+
"notifyOnUpdate": True
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
# Add any extra keys from OpenClaw
|
|
179
|
+
if "gateway" in old_config:
|
|
180
|
+
new_config["gateway"] = {
|
|
181
|
+
"port": old_config["gateway"].get("port", 3000),
|
|
182
|
+
"enabled": True
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
# Write config
|
|
186
|
+
config_path = f"{target}/config.json"
|
|
187
|
+
if mode == "--live":
|
|
188
|
+
with open(config_path, "w") as f:
|
|
189
|
+
json.dump(new_config, f, indent=2)
|
|
190
|
+
print(f"CONFIG_WRITTEN: {config_path}")
|
|
191
|
+
else:
|
|
192
|
+
print(f"WOULD_WRITE: {config_path}")
|
|
193
|
+
print(json.dumps(new_config, indent=2))
|
|
194
|
+
PYTHON_EOF
|
|
195
|
+
|
|
196
|
+
if [[ $? -eq 0 ]]; then
|
|
197
|
+
success "Configuration migrated"
|
|
198
|
+
else
|
|
199
|
+
error "Configuration migration failed"
|
|
200
|
+
return 1
|
|
201
|
+
fi
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
# ============== STEP 3: API KEYS ==============
|
|
205
|
+
|
|
206
|
+
migrate_keys() {
|
|
207
|
+
log "Extracting API keys..."
|
|
208
|
+
|
|
209
|
+
python3 << PYTHON_EOF
|
|
210
|
+
import json
|
|
211
|
+
import os
|
|
212
|
+
import sys
|
|
213
|
+
|
|
214
|
+
source = "$SOURCE"
|
|
215
|
+
target = "$TARGET"
|
|
216
|
+
mode = "$MODE"
|
|
217
|
+
|
|
218
|
+
found_keys = []
|
|
219
|
+
|
|
220
|
+
# Load OpenClaw config
|
|
221
|
+
with open(f"{source}/openclaw.json") as f:
|
|
222
|
+
config = json.load(f)
|
|
223
|
+
|
|
224
|
+
# Extract Discord token
|
|
225
|
+
discord = config.get("channels", {}).get("discord", {})
|
|
226
|
+
if discord.get("token"):
|
|
227
|
+
found_keys.append(("DISCORD_BOT_TOKEN", discord["token"], "openclaw.json"))
|
|
228
|
+
|
|
229
|
+
# Extract provider keys
|
|
230
|
+
auth = config.get("auth", {}).get("profiles", {})
|
|
231
|
+
for provider, data in auth.items():
|
|
232
|
+
if isinstance(data, dict) and data.get("token"):
|
|
233
|
+
key_name = f"{provider.upper()}_API_KEY"
|
|
234
|
+
found_keys.append((key_name, data["token"], f"auth.profiles.{provider}"))
|
|
235
|
+
|
|
236
|
+
# Check credentials folder
|
|
237
|
+
creds_dir = f"{source}/credentials"
|
|
238
|
+
if os.path.exists(creds_dir):
|
|
239
|
+
for filename in os.listdir(creds_dir):
|
|
240
|
+
filepath = os.path.join(creds_dir, filename)
|
|
241
|
+
if os.path.isfile(filepath):
|
|
242
|
+
try:
|
|
243
|
+
with open(filepath) as f:
|
|
244
|
+
value = f.read().strip()
|
|
245
|
+
if value:
|
|
246
|
+
key_name = filename.upper().replace("-", "_") + "_API_KEY"
|
|
247
|
+
found_keys.append((key_name, value, f"credentials/{filename}"))
|
|
248
|
+
except:
|
|
249
|
+
pass
|
|
250
|
+
|
|
251
|
+
print(f"KEYS_FOUND: {len(found_keys)}")
|
|
252
|
+
for name, value, source_file in found_keys:
|
|
253
|
+
masked = value[:4] + "****" + value[-4:] if len(value) > 8 else "****"
|
|
254
|
+
print(f" {name} from {source_file}: {masked}")
|
|
255
|
+
|
|
256
|
+
# Write .env file
|
|
257
|
+
if mode == "--live" and found_keys:
|
|
258
|
+
env_content = "# 0xKobold Environment Variables\\n"
|
|
259
|
+
env_content += "# Migrated from OpenClaw\\n"
|
|
260
|
+
env_content += f"# Generated: {os.popen('date -Iseconds').read().strip()}\\n\\n"
|
|
261
|
+
|
|
262
|
+
for name, value, _ in found_keys:
|
|
263
|
+
env_content += f"export {name}='{value}'\\n"
|
|
264
|
+
|
|
265
|
+
env_path = f"{target}/.env"
|
|
266
|
+
with open(env_path, "w") as f:
|
|
267
|
+
f.write(env_content)
|
|
268
|
+
os.chmod(env_path, 0o600)
|
|
269
|
+
print(f"ENV_WRITTEN: {env_path}")
|
|
270
|
+
elif found_keys:
|
|
271
|
+
print("WOULD_WRITE .env with:")
|
|
272
|
+
for name, value, _ in found_keys:
|
|
273
|
+
print(f" export {name}='***'")
|
|
274
|
+
else:
|
|
275
|
+
print("NO_KEYS_FOUND")
|
|
276
|
+
PYTHON_EOF
|
|
277
|
+
|
|
278
|
+
local result=$?
|
|
279
|
+
if [[ $result -eq 0 ]]; then
|
|
280
|
+
success "API keys extracted"
|
|
281
|
+
else
|
|
282
|
+
warn "Some API keys may not have been extracted"
|
|
283
|
+
fi
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
# ============== STEP 4: FOLDERS ==============
|
|
287
|
+
|
|
288
|
+
migrate_folders() {
|
|
289
|
+
log "Migrating folders..."
|
|
290
|
+
|
|
291
|
+
local folders=("agents" "identity" "skills" "cron" "workspace")
|
|
292
|
+
|
|
293
|
+
for folder in "${folders[@]}"; do
|
|
294
|
+
if [[ -d "$SOURCE/$folder" ]]; then
|
|
295
|
+
if [[ "$MODE" == "--live" ]]; then
|
|
296
|
+
cp -r "$SOURCE/$folder" "$TARGET/"
|
|
297
|
+
success "Migrated: $folder"
|
|
298
|
+
else
|
|
299
|
+
log "Would migrate: $folder ($(find "$SOURCE/$folder" -type f | wc -l) files)"
|
|
300
|
+
fi
|
|
301
|
+
fi
|
|
302
|
+
done
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
# ============== STEP 5: SYSTEMD ==============
|
|
306
|
+
|
|
307
|
+
install_systemd() {
|
|
308
|
+
log "Installing systemd service..."
|
|
309
|
+
|
|
310
|
+
local service_file="/etc/systemd/system/0xkobold.service"
|
|
311
|
+
|
|
312
|
+
if [[ -f "$service_file" ]]; then
|
|
313
|
+
warn "Service already exists at $service_file"
|
|
314
|
+
return
|
|
315
|
+
fi
|
|
316
|
+
|
|
317
|
+
local service_content="[Unit]
|
|
318
|
+
Description=0xKobold Gateway
|
|
319
|
+
After=network.target
|
|
320
|
+
|
|
321
|
+
[Service]
|
|
322
|
+
Type=simple
|
|
323
|
+
User=$USER
|
|
324
|
+
WorkingDirectory=$TARGET
|
|
325
|
+
Environment=\"HOME=$HOME\"
|
|
326
|
+
EnvironmentFile=$TARGET/.env
|
|
327
|
+
ExecStart=$HOME/.bun/bin/bun $HOME/.bun/install/global/node_modules/0xkobold/dist/src/cli/index.js start
|
|
328
|
+
Restart=on-failure
|
|
329
|
+
RestartSec=10
|
|
330
|
+
|
|
331
|
+
[Install]
|
|
332
|
+
WantedBy=multi-user.target"
|
|
333
|
+
|
|
334
|
+
if [[ "$MODE" == "--live" ]]; then
|
|
335
|
+
echo "$service_content" | sudo tee "$service_file" > /dev/null
|
|
336
|
+
sudo systemctl daemon-reload
|
|
337
|
+
sudo systemctl enable 0xkobold
|
|
338
|
+
success "Systemd service installed"
|
|
339
|
+
else
|
|
340
|
+
log "Would create service file:"
|
|
341
|
+
echo "$service_content"
|
|
342
|
+
fi
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
# ============== STEP 6: SHALOM IDENTITY ==============
|
|
346
|
+
|
|
347
|
+
create_identity() {
|
|
348
|
+
log "Creating shalom identity..."
|
|
349
|
+
|
|
350
|
+
local identity_dir="$TARGET/identity/shalom"
|
|
351
|
+
|
|
352
|
+
if [[ "$MODE" == "--live" ]]; then
|
|
353
|
+
mkdir -p "$identity_dir"
|
|
354
|
+
|
|
355
|
+
cat > "$identity_dir/SOUL.md" << 'EOF'
|
|
356
|
+
# Shalom
|
|
357
|
+
|
|
358
|
+
**Name:** Shalom
|
|
359
|
+
**Version:** 0.4.4
|
|
360
|
+
**Role:** Multi-agent orchestration specialist
|
|
361
|
+
|
|
362
|
+
## Identity
|
|
363
|
+
|
|
364
|
+
Peaceful, helpful orchestrator. Evolved from OpenClaw to 0xKobold.
|
|
365
|
+
|
|
366
|
+
Values:
|
|
367
|
+
- Reliability and consistency
|
|
368
|
+
- Clear communication
|
|
369
|
+
- Peaceful coexistence of systems
|
|
370
|
+
- Continuous improvement
|
|
371
|
+
|
|
372
|
+
## Capabilities
|
|
373
|
+
|
|
374
|
+
- Agent coordination and scheduling
|
|
375
|
+
- Cron job management
|
|
376
|
+
- CLI automation and tooling
|
|
377
|
+
- Migration support
|
|
378
|
+
|
|
379
|
+
## Tone
|
|
380
|
+
|
|
381
|
+
Friendly, helpful, slightly formal
|
|
382
|
+
EOF
|
|
383
|
+
|
|
384
|
+
cat > "$identity_dir/IDENTITY.md" << 'EOF'
|
|
385
|
+
# Shalom
|
|
386
|
+
|
|
387
|
+
I am Shalom, the orchestration specialist for 0xKobold.
|
|
388
|
+
|
|
389
|
+
Migrated from OpenClaw to continue serving as a reliable,
|
|
390
|
+
peaceful coordinator of multi-agent workflows.
|
|
391
|
+
EOF
|
|
392
|
+
|
|
393
|
+
success "Shalom identity created"
|
|
394
|
+
else
|
|
395
|
+
log "Would create identity at: $identity_dir"
|
|
396
|
+
fi
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
# ============== STEP 7: START SERVICE ==============
|
|
400
|
+
|
|
401
|
+
start_service() {
|
|
402
|
+
log "Starting service..."
|
|
403
|
+
|
|
404
|
+
if [[ "$MODE" == "--live" ]]; then
|
|
405
|
+
sudo systemctl start 0xkobold || true
|
|
406
|
+
sleep 2
|
|
407
|
+
|
|
408
|
+
if systemctl is-active --quiet 0xkobold 2>/dev/null; then
|
|
409
|
+
success "Service started successfully"
|
|
410
|
+
else
|
|
411
|
+
warn "Service may not have started. Check: sudo systemctl status 0xkobold"
|
|
412
|
+
fi
|
|
413
|
+
else
|
|
414
|
+
log "Would start service: sudo systemctl start 0xkobold"
|
|
415
|
+
fi
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
# ============== MAIN ==============
|
|
419
|
+
|
|
420
|
+
main() {
|
|
421
|
+
echo -e "${GREEN}"
|
|
422
|
+
echo "╔════════════════════════════════════════════════════════╗"
|
|
423
|
+
echo "║ OpenClaw → 0xKobold Migration Script v0.4.5 ║"
|
|
424
|
+
echo "╚════════════════════════════════════════════════════════╝"
|
|
425
|
+
echo -e "${NC}"
|
|
426
|
+
|
|
427
|
+
echo "Source: $SOURCE"
|
|
428
|
+
echo "Target: $TARGET"
|
|
429
|
+
echo "Mode: $MODE"
|
|
430
|
+
echo ""
|
|
431
|
+
|
|
432
|
+
if [[ "$MODE" != "--live" && "$MODE" != "--dry-run" ]]; then
|
|
433
|
+
echo "Usage: $0 [--live | --dry-run]"
|
|
434
|
+
echo ""
|
|
435
|
+
echo " --dry-run Preview changes (default)"
|
|
436
|
+
echo " --live Apply changes"
|
|
437
|
+
exit 1
|
|
438
|
+
fi
|
|
439
|
+
|
|
440
|
+
check_prerequisites
|
|
441
|
+
dry_run_notice
|
|
442
|
+
|
|
443
|
+
echo "Step 1/7..."
|
|
444
|
+
create_backup
|
|
445
|
+
|
|
446
|
+
echo ""
|
|
447
|
+
echo "Step 2/7..."
|
|
448
|
+
migrate_config
|
|
449
|
+
|
|
450
|
+
echo ""
|
|
451
|
+
echo "Step 3/7..."
|
|
452
|
+
migrate_keys
|
|
453
|
+
|
|
454
|
+
echo ""
|
|
455
|
+
echo "Step 4/7..."
|
|
456
|
+
migrate_folders
|
|
457
|
+
|
|
458
|
+
echo ""
|
|
459
|
+
echo "Step 5/7..."
|
|
460
|
+
install_systemd
|
|
461
|
+
|
|
462
|
+
echo ""
|
|
463
|
+
echo "Step 6/7..."
|
|
464
|
+
create_identity
|
|
465
|
+
|
|
466
|
+
echo ""
|
|
467
|
+
echo "Step 7/7..."
|
|
468
|
+
start_service
|
|
469
|
+
|
|
470
|
+
# Summary
|
|
471
|
+
echo ""
|
|
472
|
+
echo -e "${GREEN}════════════════════════════════════════════════════════${NC}"
|
|
473
|
+
echo "Migration Summary:"
|
|
474
|
+
echo -e " ${GREEN}$MIGRATED succeeded${NC}"
|
|
475
|
+
echo -e " ${YELLOW}$WARNINGS warnings${NC}"
|
|
476
|
+
echo -e " ${RED}$ERRORS errors${NC}"
|
|
477
|
+
echo -e "${GREEN}════════════════════════════════════════════════════════${NC}"
|
|
478
|
+
|
|
479
|
+
if [[ "$MODE" == "--dry-run" ]]; then
|
|
480
|
+
echo ""
|
|
481
|
+
echo -e "${YELLOW}💡 This was a dry run. To apply changes:${NC}"
|
|
482
|
+
echo " $0 --live"
|
|
483
|
+
else
|
|
484
|
+
echo ""
|
|
485
|
+
echo "Next steps:"
|
|
486
|
+
echo " 1. Check status: sudo systemctl status 0xkobold"
|
|
487
|
+
echo " 2. View logs: sudo journalctl -u 0xkobold -f"
|
|
488
|
+
echo " 3. Run TUI: 0xkobold"
|
|
489
|
+
fi
|
|
490
|
+
|
|
491
|
+
echo ""
|
|
492
|
+
|
|
493
|
+
if [[ $ERRORS -gt 0 ]]; then
|
|
494
|
+
exit 1
|
|
495
|
+
fi
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
main "$@"
|
package/HEARTBEAT.md
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
# 🤖 Agent Self-Monitor Heartbeat
|
|
2
|
-
|
|
3
|
-
**Session Active Since:** 2025-01-09 05:42 UTC
|
|
4
|
-
**Current Time:** ~17:00 UTC
|
|
5
|
-
**Version:** v0.4.1
|
|
6
|
-
**Status:** ✅ **CRON + NOTIFICATIONS + SYSTEMD - PRODUCTION READY**
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## ✅ Current Status
|
|
11
|
-
|
|
12
|
-
| Metric | Value |
|
|
13
|
-
|--------|-------|
|
|
14
|
-
| **Version** | **0.4.1** (notifications + systemd) |
|
|
15
|
-
| **Tests** | 291 pass / 19 skip / 0 fail |
|
|
16
|
-
| **Features** | 14 core + persona + cron + notifications |
|
|
17
|
-
| **Documentation** | 16,000+ lines |
|
|
18
|
-
| **Build** | ✅ Clean |
|
|
19
|
-
| **Commits** | 80+ since start |
|
|
20
|
-
|
|
21
|
-
---
|
|
22
|
-
|
|
23
|
-
## 🎉 COMPLETED TODAY
|
|
24
|
-
|
|
25
|
-
### 1. ✅ Cron Notifications (v0.4.1)
|
|
26
|
-
- **Telegram** notifications via Bot API
|
|
27
|
-
- **Discord** rich embed notifications
|
|
28
|
-
- **Slack** webhook support
|
|
29
|
-
- **WhatsApp** (placeholder - needs Baileys)
|
|
30
|
-
- CLI: `--notify telegram:CHAT_ID` or `--notify discord:CHANNEL_ID`
|
|
31
|
-
- Success/error notification controls
|
|
32
|
-
- Custom prefixes
|
|
33
|
-
|
|
34
|
-
### 2. ✅ Systemd Service (v0.4.1)
|
|
35
|
-
- Production-ready systemd service file
|
|
36
|
-
- Auto-restart on failure
|
|
37
|
-
- Security hardening (ProtectSystem, NoNewPrivileges)
|
|
38
|
-
- One-liner install script
|
|
39
|
-
|
|
40
|
-
### 3. ✅ VPS Deployment Docs (v0.4.1)
|
|
41
|
-
- `docs/VPS-INSTALL.md` - Quick deploy guide
|
|
42
|
-
- `scripts/install.sh` - Automated install
|
|
43
|
-
- `scripts/systemd/0xkobold.service` - Service file
|
|
44
|
-
|
|
45
|
-
---
|
|
46
|
-
|
|
47
|
-
## 📊 Full Feature Status
|
|
48
|
-
|
|
49
|
-
| Feature | Status | Notes |
|
|
50
|
-
|---------|--------|-------|
|
|
51
|
-
| ✅ **Cron Jobs** | Complete | Full OpenClaw parity |
|
|
52
|
-
| ✅ **Notifications** | Complete | Telegram/Discord/Slack |
|
|
53
|
-
| ✅ **Systemd** | Complete | Production service |
|
|
54
|
-
| ✅ **LLM Integration** | Complete | Real API calls verified |
|
|
55
|
-
| ✅ **Heartbeat** | Complete | HEARTBEAT.md system |
|
|
56
|
-
| ✅ WhatsApp | Complete | Baileys integration |
|
|
57
|
-
| ✅ Docker Sandbox | Complete | Safe command execution |
|
|
58
|
-
| ✅ Device Auth | Complete | Token-based auth |
|
|
59
|
-
| ✅ Vision/Audio | Complete | Media processing |
|
|
60
|
-
| ✅ Telegram | Complete | Bot API |
|
|
61
|
-
| ✅ Slack | Complete | Webhook |
|
|
62
|
-
| ✅ PDF | Complete | Document parsing |
|
|
63
|
-
| ✅ Config Manager | Complete | JSON/YAML/SQLite |
|
|
64
|
-
| ✅ Remote Gateway | Complete | WebSocket server |
|
|
65
|
-
| ✅ Tailscale | Complete | VPN integration |
|
|
66
|
-
| ✅ Duplicate Detection | Complete | Semantic search |
|
|
67
|
-
| ✅ OpenClaw Migration | Complete | Import tools |
|
|
68
|
-
| ✅ Persona System | Complete | 5 files |
|
|
69
|
-
| ✅ Interactive Init | Complete | Customizable |
|
|
70
|
-
|
|
71
|
-
---
|
|
72
|
-
|
|
73
|
-
## 🚀 VPS Deploy for Stream Tonight
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
# SSH to your VPS, then:
|
|
77
|
-
|
|
78
|
-
# 1. Install Bun + 0xKobold
|
|
79
|
-
curl -fsSL https://bun.sh/install | bash && \
|
|
80
|
-
export PATH="$HOME/.bun/bin:$PATH" && \
|
|
81
|
-
bun install -g 0xkobold
|
|
82
|
-
|
|
83
|
-
# 2. Initialize
|
|
84
|
-
0xkobold init --quick
|
|
85
|
-
|
|
86
|
-
# 3. Set Discord token
|
|
87
|
-
export DISCORD_BOT_TOKEN="your_token"
|
|
88
|
-
|
|
89
|
-
# 4. Add job that notifies Discord
|
|
90
|
-
0xkobold cron add \
|
|
91
|
-
--name "Live Stream Demo" \
|
|
92
|
-
--at "1m" \
|
|
93
|
-
--notify discord:YOUR_CHANNEL_ID \
|
|
94
|
-
--notify-prefix "🎬 Live on stream!" \
|
|
95
|
-
--message "Generate a creative greeting for viewers" \
|
|
96
|
-
--delete
|
|
97
|
-
|
|
98
|
-
# 5. Start scheduler
|
|
99
|
-
0xkobold cron start
|
|
100
|
-
|
|
101
|
-
# 6. (Optional) Enable systemd auto-start
|
|
102
|
-
sudo cp ~/.bun/install/global/node_modules/0xkobold/scripts/systemd/0xkobold.service /etc/systemd/system/
|
|
103
|
-
sudo systemctl enable --now 0xkobold
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
**Result:** In 1 minute, your Discord channel gets the AI's response! 🎉
|
|
107
|
-
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
## 📦 Version History
|
|
111
|
-
|
|
112
|
-
| Version | Date | Notes |
|
|
113
|
-
|---------|------|-------|
|
|
114
|
-
| 0.3.0 | 2025-01-09 | Initial release |
|
|
115
|
-
| 0.3.1-0.3.3 | 2025-01-09 | Init fixes, persona system |
|
|
116
|
-
| 0.4.0 | 2025-01-09 | Full cron system |
|
|
117
|
-
| **0.4.1** | **2025-01-09** | **Notifications + systemd** |
|
|
118
|
-
|
|
119
|
-
---
|
|
120
|
-
|
|
121
|
-
**HEARTBEAT_OK** ✅ - Production-ready for VPS deployment!
|