0xkobold 0.0.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/.agents/skills/nextjs-best-practices/SKILL.md +208 -0
- package/.agents/skills/sql-optimization-patterns/SKILL.md +509 -0
- package/HEARTBEAT.md +45 -0
- package/README.md +197 -0
- package/USAGE.md +191 -0
- package/dist/package.json +77 -0
- package/dist/src/agent/pi-adapter.js +307 -0
- package/dist/src/agent/pi-adapter.js.map +1 -0
- package/dist/src/agent/tool-adapter.js +86 -0
- package/dist/src/agent/tool-adapter.js.map +1 -0
- package/dist/src/approval/queue.js +114 -0
- package/dist/src/approval/queue.js.map +1 -0
- package/dist/src/ascii-kobold.js +76 -0
- package/dist/src/ascii-kobold.js.map +1 -0
- package/dist/src/cli/client.js +217 -0
- package/dist/src/cli/client.js.map +1 -0
- package/dist/src/cli/commands/agent.js +272 -0
- package/dist/src/cli/commands/agent.js.map +1 -0
- package/dist/src/cli/commands/chat.js +234 -0
- package/dist/src/cli/commands/chat.js.map +1 -0
- package/dist/src/cli/commands/config.js +202 -0
- package/dist/src/cli/commands/config.js.map +1 -0
- package/dist/src/cli/commands/daemon.js +203 -0
- package/dist/src/cli/commands/daemon.js.map +1 -0
- package/dist/src/cli/commands/gateway.js +184 -0
- package/dist/src/cli/commands/gateway.js.map +1 -0
- package/dist/src/cli/commands/init.js +175 -0
- package/dist/src/cli/commands/init.js.map +1 -0
- package/dist/src/cli/commands/kobold.js +21 -0
- package/dist/src/cli/commands/kobold.js.map +1 -0
- package/dist/src/cli/commands/logs.js +27 -0
- package/dist/src/cli/commands/logs.js.map +1 -0
- package/dist/src/cli/commands/mode.js +121 -0
- package/dist/src/cli/commands/mode.js.map +1 -0
- package/dist/src/cli/commands/persona.js +261 -0
- package/dist/src/cli/commands/persona.js.map +1 -0
- package/dist/src/cli/commands/start.js +66 -0
- package/dist/src/cli/commands/start.js.map +1 -0
- package/dist/src/cli/commands/status.js +117 -0
- package/dist/src/cli/commands/status.js.map +1 -0
- package/dist/src/cli/commands/stop.js +27 -0
- package/dist/src/cli/commands/stop.js.map +1 -0
- package/dist/src/cli/commands/system.js +128 -0
- package/dist/src/cli/commands/system.js.map +1 -0
- package/dist/src/cli/commands/tui.js +103 -0
- package/dist/src/cli/commands/tui.js.map +1 -0
- package/dist/src/cli/commands/update.js +133 -0
- package/dist/src/cli/commands/update.js.map +1 -0
- package/dist/src/cli/extensions/discord.js +113 -0
- package/dist/src/cli/extensions/discord.js.map +1 -0
- package/dist/src/cli/extensions/env.js +91 -0
- package/dist/src/cli/extensions/env.js.map +1 -0
- package/dist/src/cli/extensions/heartbeat.js +78 -0
- package/dist/src/cli/extensions/heartbeat.js.map +1 -0
- package/dist/src/cli/index.js +24 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/cli/program.js +70 -0
- package/dist/src/cli/program.js.map +1 -0
- package/dist/src/cli/repl.js +184 -0
- package/dist/src/cli/repl.js.map +1 -0
- package/dist/src/cli/shared/discord-service.js +102 -0
- package/dist/src/cli/shared/discord-service.js.map +1 -0
- package/dist/src/config/index.js +10 -0
- package/dist/src/config/index.js.map +1 -0
- package/dist/src/config/loader.js +401 -0
- package/dist/src/config/loader.js.map +1 -0
- package/dist/src/config/paths.js +84 -0
- package/dist/src/config/paths.js.map +1 -0
- package/dist/src/config/types.js +8 -0
- package/dist/src/config/types.js.map +1 -0
- package/dist/src/context-detector.js +60 -0
- package/dist/src/context-detector.js.map +1 -0
- package/dist/src/discord/index.js +376 -0
- package/dist/src/discord/index.js.map +1 -0
- package/dist/src/event-bus/index.js +97 -0
- package/dist/src/event-bus/index.js.map +1 -0
- package/dist/src/extensions/command-args.js +68 -0
- package/dist/src/extensions/command-args.js.map +1 -0
- package/dist/src/extensions/core/agent-registry-extension.js +541 -0
- package/dist/src/extensions/core/agent-registry-extension.js.map +1 -0
- package/dist/src/extensions/core/agent-worker.js +148 -0
- package/dist/src/extensions/core/agent-worker.js.map +1 -0
- package/dist/src/extensions/core/compaction-safeguard.js +154 -0
- package/dist/src/extensions/core/compaction-safeguard.js.map +1 -0
- package/dist/src/extensions/core/confirm-destructive.js +43 -0
- package/dist/src/extensions/core/confirm-destructive.js.map +1 -0
- package/dist/src/extensions/core/context-aware-extension.js +124 -0
- package/dist/src/extensions/core/context-aware-extension.js.map +1 -0
- package/dist/src/extensions/core/context-pruning/extension.js +124 -0
- package/dist/src/extensions/core/context-pruning/extension.js.map +1 -0
- package/dist/src/extensions/core/context-pruning/pruner.js +312 -0
- package/dist/src/extensions/core/context-pruning/pruner.js.map +1 -0
- package/dist/src/extensions/core/context-pruning/runtime.js +48 -0
- package/dist/src/extensions/core/context-pruning/runtime.js.map +1 -0
- package/dist/src/extensions/core/context-pruning/settings.js +105 -0
- package/dist/src/extensions/core/context-pruning/settings.js.map +1 -0
- package/dist/src/extensions/core/dirty-repo-guard.js +42 -0
- package/dist/src/extensions/core/dirty-repo-guard.js.map +1 -0
- package/dist/src/extensions/core/discord-channel-extension.js +205 -0
- package/dist/src/extensions/core/discord-channel-extension.js.map +1 -0
- package/dist/src/extensions/core/discord-extension.js +142 -0
- package/dist/src/extensions/core/discord-extension.js.map +1 -0
- package/dist/src/extensions/core/env-loader-extension.js +157 -0
- package/dist/src/extensions/core/env-loader-extension.js.map +1 -0
- package/dist/src/extensions/core/fileops-extension.js +699 -0
- package/dist/src/extensions/core/fileops-extension.js.map +1 -0
- package/dist/src/extensions/core/gateway-extension.js +730 -0
- package/dist/src/extensions/core/gateway-extension.js.map +1 -0
- package/dist/src/extensions/core/git-checkpoint.js +46 -0
- package/dist/src/extensions/core/git-checkpoint.js.map +1 -0
- package/dist/src/extensions/core/handoff-extension.js +206 -0
- package/dist/src/extensions/core/handoff-extension.js.map +1 -0
- package/dist/src/extensions/core/heartbeat-extension.js +373 -0
- package/dist/src/extensions/core/heartbeat-extension.js.map +1 -0
- package/dist/src/extensions/core/mcp-extension.js +413 -0
- package/dist/src/extensions/core/mcp-extension.js.map +1 -0
- package/dist/src/extensions/core/mode-manager-extension.js +562 -0
- package/dist/src/extensions/core/mode-manager-extension.js.map +1 -0
- package/dist/src/extensions/core/multi-channel-extension.js +435 -0
- package/dist/src/extensions/core/multi-channel-extension.js.map +1 -0
- package/dist/src/extensions/core/ollama-provider-extension.js +66 -0
- package/dist/src/extensions/core/ollama-provider-extension.js.map +1 -0
- package/dist/src/extensions/core/onboarding-extension.js +122 -0
- package/dist/src/extensions/core/onboarding-extension.js.map +1 -0
- package/dist/src/extensions/core/persona-loader-extension.js +139 -0
- package/dist/src/extensions/core/persona-loader-extension.js.map +1 -0
- package/dist/src/extensions/core/pi-notify-extension.js +70 -0
- package/dist/src/extensions/core/pi-notify-extension.js.map +1 -0
- package/dist/src/extensions/core/protected-paths.js +24 -0
- package/dist/src/extensions/core/protected-paths.js.map +1 -0
- package/dist/src/extensions/core/questionnaire-extension.js +242 -0
- package/dist/src/extensions/core/questionnaire-extension.js.map +1 -0
- package/dist/src/extensions/core/self-update-extension.js +181 -0
- package/dist/src/extensions/core/self-update-extension.js.map +1 -0
- package/dist/src/extensions/core/session-bridge-extension.js +78 -0
- package/dist/src/extensions/core/session-bridge-extension.js.map +1 -0
- package/dist/src/extensions/core/session-manager-extension.js +319 -0
- package/dist/src/extensions/core/session-manager-extension.js.map +1 -0
- package/dist/src/extensions/core/session-name-extension.js +88 -0
- package/dist/src/extensions/core/session-name-extension.js.map +1 -0
- package/dist/src/extensions/core/session-pruning-extension.js +480 -0
- package/dist/src/extensions/core/session-pruning-extension.js.map +1 -0
- package/dist/src/extensions/core/task-manager-extension.js +661 -0
- package/dist/src/extensions/core/task-manager-extension.js.map +1 -0
- package/dist/src/extensions/core/update-extension.js +438 -0
- package/dist/src/extensions/core/update-extension.js.map +1 -0
- package/dist/src/extensions/core/websearch-extension.js +463 -0
- package/dist/src/extensions/core/websearch-extension.js.map +1 -0
- package/dist/src/extensions/index.js +5 -0
- package/dist/src/extensions/index.js.map +1 -0
- package/dist/src/extensions/loader.js +80 -0
- package/dist/src/extensions/loader.js.map +1 -0
- package/dist/src/gateway/index.js +353 -0
- package/dist/src/gateway/index.js.map +1 -0
- package/dist/src/index.js +150 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/llm/anthropic.js +86 -0
- package/dist/src/llm/anthropic.js.map +1 -0
- package/dist/src/llm/index.js +9 -0
- package/dist/src/llm/index.js.map +1 -0
- package/dist/src/llm/ollama.js +113 -0
- package/dist/src/llm/ollama.js.map +1 -0
- package/dist/src/llm/router.js +145 -0
- package/dist/src/llm/router.js.map +1 -0
- package/dist/src/llm/types.js +7 -0
- package/dist/src/llm/types.js.map +1 -0
- package/dist/src/memory/index.js +5 -0
- package/dist/src/memory/index.js.map +1 -0
- package/dist/src/memory/store.js +91 -0
- package/dist/src/memory/store.js.map +1 -0
- package/dist/src/pi-config.js +80 -0
- package/dist/src/pi-config.js.map +1 -0
- package/dist/src/skills/builtin/file.js +184 -0
- package/dist/src/skills/builtin/file.js.map +1 -0
- package/dist/src/skills/builtin/shell.js +100 -0
- package/dist/src/skills/builtin/shell.js.map +1 -0
- package/dist/src/skills/builtin/subagent.js +62 -0
- package/dist/src/skills/builtin/subagent.js.map +1 -0
- package/dist/src/skills/hello.js +42 -0
- package/dist/src/skills/hello.js.map +1 -0
- package/dist/src/skills/index.js +11 -0
- package/dist/src/skills/index.js.map +1 -0
- package/dist/src/skills/loader.js +382 -0
- package/dist/src/skills/loader.js.map +1 -0
- package/dist/src/skills/types.js +8 -0
- package/dist/src/skills/types.js.map +1 -0
- package/dist/src/utils/working-dir.js +71 -0
- package/dist/src/utils/working-dir.js.map +1 -0
- package/package.json +77 -0
- package/skills/1password/SKILL.md +70 -0
- package/skills/1password/references/cli-examples.md +29 -0
- package/skills/1password/references/get-started.md +17 -0
- package/skills/apple-notes/SKILL.md +77 -0
- package/skills/apple-reminders/SKILL.md +118 -0
- package/skills/bear-notes/SKILL.md +107 -0
- package/skills/blogwatcher/SKILL.md +69 -0
- package/skills/blucli/SKILL.md +47 -0
- package/skills/bluebubbles/SKILL.md +131 -0
- package/skills/camsnap/SKILL.md +45 -0
- package/skills/canvas/SKILL.md +198 -0
- package/skills/clawhub/SKILL.md +77 -0
- package/skills/coding-agent/SKILL.md +284 -0
- package/skills/discord/SKILL.md +197 -0
- package/skills/eightctl/SKILL.md +50 -0
- package/skills/food-order/SKILL.md +48 -0
- package/skills/gemini/SKILL.md +43 -0
- package/skills/gh-issues/SKILL.md +865 -0
- package/skills/gifgrep/SKILL.md +79 -0
- package/skills/github/SKILL.md +163 -0
- package/skills/gog/SKILL.md +116 -0
- package/skills/goplaces/SKILL.md +52 -0
- package/skills/healthcheck/SKILL.md +245 -0
- package/skills/himalaya/SKILL.md +257 -0
- package/skills/himalaya/references/configuration.md +184 -0
- package/skills/himalaya/references/message-composition.md +199 -0
- package/skills/imsg/SKILL.md +122 -0
- package/skills/mcporter/SKILL.md +61 -0
- package/skills/model-usage/SKILL.md +69 -0
- package/skills/model-usage/references/codexbar-cli.md +33 -0
- package/skills/model-usage/scripts/model_usage.py +310 -0
- package/skills/nano-banana-pro/SKILL.md +58 -0
- package/skills/nano-banana-pro/scripts/generate_image.py +184 -0
- package/skills/nano-pdf/SKILL.md +38 -0
- package/skills/notion/SKILL.md +172 -0
- package/skills/obsidian/SKILL.md +81 -0
- package/skills/openai-image-gen/SKILL.md +89 -0
- package/skills/openai-image-gen/scripts/gen.py +240 -0
- package/skills/openai-whisper/SKILL.md +38 -0
- package/skills/openai-whisper-api/SKILL.md +52 -0
- package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
- package/skills/openhue/SKILL.md +112 -0
- package/skills/oracle/SKILL.md +125 -0
- package/skills/ordercli/SKILL.md +78 -0
- package/skills/peekaboo/SKILL.md +190 -0
- package/skills/sag/SKILL.md +87 -0
- package/skills/session-logs/SKILL.md +115 -0
- package/skills/sherpa-onnx-tts/SKILL.md +103 -0
- package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +178 -0
- package/skills/skill-creator/SKILL.md +370 -0
- package/skills/skill-creator/license.txt +202 -0
- package/skills/skill-creator/scripts/init_skill.py +378 -0
- package/skills/skill-creator/scripts/package_skill.py +111 -0
- package/skills/skill-creator/scripts/quick_validate.py +101 -0
- package/skills/slack/SKILL.md +144 -0
- package/skills/songsee/SKILL.md +49 -0
- package/skills/sonoscli/SKILL.md +46 -0
- package/skills/spotify-player/SKILL.md +64 -0
- package/skills/summarize/SKILL.md +87 -0
- package/skills/things-mac/SKILL.md +86 -0
- package/skills/tmux/SKILL.md +153 -0
- package/skills/tmux/scripts/find-sessions.sh +112 -0
- package/skills/tmux/scripts/wait-for-text.sh +83 -0
- package/skills/trello/SKILL.md +95 -0
- package/skills/video-frames/SKILL.md +46 -0
- package/skills/video-frames/scripts/frame.sh +81 -0
- package/skills/voice-call/SKILL.md +45 -0
- package/skills/wacli/SKILL.md +72 -0
- package/skills/weather/SKILL.md +112 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { KoboldClient } from "../client.js";
|
|
3
|
+
import { createInterface } from "node:readline";
|
|
4
|
+
const client = new KoboldClient();
|
|
5
|
+
const sendCommand = new Command("send")
|
|
6
|
+
.description("Send a message to the daemon")
|
|
7
|
+
.argument("<message>", "Message to send")
|
|
8
|
+
.option("-s, --session <id>", "Session ID")
|
|
9
|
+
.option("-a, --agent <id>", "Agent ID to use")
|
|
10
|
+
.option("--no-stream", "Disable streaming response")
|
|
11
|
+
.action(async (message, options) => {
|
|
12
|
+
try {
|
|
13
|
+
const connected = await client.connect();
|
|
14
|
+
if (!connected) {
|
|
15
|
+
console.error("❌ Daemon is not running. Start it with: 0xkobold daemon start");
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const response = await client.send({
|
|
19
|
+
type: "chat",
|
|
20
|
+
content: message,
|
|
21
|
+
sessionId: options.session,
|
|
22
|
+
agentId: options.agent,
|
|
23
|
+
stream: options.stream
|
|
24
|
+
});
|
|
25
|
+
if (response.error) {
|
|
26
|
+
console.error("❌ Error:", response.error);
|
|
27
|
+
process.exit(1);
|
|
28
|
+
}
|
|
29
|
+
console.log(response.content);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
console.error("❌ Failed to send message:", error);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
client.disconnect();
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
const sessionCommand = new Command("session")
|
|
40
|
+
.description("Manage chat sessions")
|
|
41
|
+
.addCommand(new Command("list")
|
|
42
|
+
.description("List active sessions")
|
|
43
|
+
.action(async () => {
|
|
44
|
+
try {
|
|
45
|
+
const connected = await client.connect();
|
|
46
|
+
if (!connected) {
|
|
47
|
+
console.error("❌ Daemon is not running");
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
const response = await client.send({
|
|
51
|
+
type: "list_sessions"
|
|
52
|
+
});
|
|
53
|
+
if (response.error) {
|
|
54
|
+
console.error("❌ Error:", response.error);
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
if (response.sessions.length === 0) {
|
|
58
|
+
console.log("No active sessions");
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
console.log("Active sessions:");
|
|
62
|
+
response.sessions.forEach((session) => {
|
|
63
|
+
console.log(` ${session.id} - ${session.agent} (${session.startedAt})`);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.error("❌ Failed to list sessions:", error);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
70
|
+
finally {
|
|
71
|
+
client.disconnect();
|
|
72
|
+
}
|
|
73
|
+
}))
|
|
74
|
+
.addCommand(new Command("new")
|
|
75
|
+
.description("Create a new session")
|
|
76
|
+
.option("-a, --agent <id>", "Agent ID")
|
|
77
|
+
.action(async (options) => {
|
|
78
|
+
try {
|
|
79
|
+
const connected = await client.connect();
|
|
80
|
+
if (!connected) {
|
|
81
|
+
console.error("❌ Daemon is not running");
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
const response = await client.send({
|
|
85
|
+
type: "create_session",
|
|
86
|
+
agentId: options.agent
|
|
87
|
+
});
|
|
88
|
+
if (response.error) {
|
|
89
|
+
console.error("❌ Error:", response.error);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
console.log(`✓ Session created: ${response.sessionId}`);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.error("❌ Failed to create session:", error);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
finally {
|
|
99
|
+
client.disconnect();
|
|
100
|
+
}
|
|
101
|
+
}));
|
|
102
|
+
const historyCommand = new Command("history")
|
|
103
|
+
.description("View chat history")
|
|
104
|
+
.option("-s, --session <id>", "Session ID")
|
|
105
|
+
.option("-n, --limit <number>", "Limit number of messages", "20")
|
|
106
|
+
.action(async (options) => {
|
|
107
|
+
try {
|
|
108
|
+
const connected = await client.connect();
|
|
109
|
+
if (!connected) {
|
|
110
|
+
console.error("❌ Daemon is not running");
|
|
111
|
+
process.exit(1);
|
|
112
|
+
}
|
|
113
|
+
const response = await client.send({
|
|
114
|
+
type: "get_history",
|
|
115
|
+
sessionId: options.session,
|
|
116
|
+
limit: parseInt(options.limit)
|
|
117
|
+
});
|
|
118
|
+
if (response.error) {
|
|
119
|
+
console.error("❌ Error:", response.error);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
if (response.messages.length === 0) {
|
|
123
|
+
console.log("No messages found");
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
response.messages.forEach((msg) => {
|
|
127
|
+
const role = msg.role === "user" ? "You" : "Kobold";
|
|
128
|
+
console.log(`\n[${role}]: ${msg.content}`);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
catch (error) {
|
|
132
|
+
console.error("❌ Failed to get history:", error);
|
|
133
|
+
process.exit(1);
|
|
134
|
+
}
|
|
135
|
+
finally {
|
|
136
|
+
client.disconnect();
|
|
137
|
+
}
|
|
138
|
+
});
|
|
139
|
+
const interactiveCommand = new Command("interactive")
|
|
140
|
+
.description("Start interactive chat session")
|
|
141
|
+
.option("-s, --session <id>", "Session ID")
|
|
142
|
+
.option("-a, --agent <id>", "Agent ID")
|
|
143
|
+
.action(async (options) => {
|
|
144
|
+
const rl = createInterface({
|
|
145
|
+
input: process.stdin,
|
|
146
|
+
output: process.stdout,
|
|
147
|
+
prompt: "🐲 > "
|
|
148
|
+
});
|
|
149
|
+
try {
|
|
150
|
+
const connected = await client.connect();
|
|
151
|
+
if (!connected) {
|
|
152
|
+
console.error("❌ Daemon is not running. Start it with: 0xkobold daemon start");
|
|
153
|
+
rl.close();
|
|
154
|
+
process.exit(1);
|
|
155
|
+
}
|
|
156
|
+
console.log("🐲 0xKobold Interactive Chat");
|
|
157
|
+
console.log("Type 'exit' or 'quit' to exit\n");
|
|
158
|
+
let sessionId = options.session;
|
|
159
|
+
rl.prompt();
|
|
160
|
+
rl.on("line", async (line) => {
|
|
161
|
+
const input = line.trim();
|
|
162
|
+
if (input === "exit" || input === "quit") {
|
|
163
|
+
rl.close();
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (!input) {
|
|
167
|
+
rl.prompt();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
process.stdout.write("🐲 ... ");
|
|
172
|
+
const response = await client.send({
|
|
173
|
+
type: "chat",
|
|
174
|
+
content: input,
|
|
175
|
+
sessionId,
|
|
176
|
+
agentId: options.agent
|
|
177
|
+
});
|
|
178
|
+
process.stdout.write("\r \r");
|
|
179
|
+
if (response.error) {
|
|
180
|
+
console.error("❌ Error:", response.error);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
console.log(response.content);
|
|
184
|
+
if (response.sessionId && !sessionId) {
|
|
185
|
+
sessionId = response.sessionId;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
process.stdout.write("\r \r");
|
|
191
|
+
console.error("❌ Failed:", error);
|
|
192
|
+
}
|
|
193
|
+
rl.prompt();
|
|
194
|
+
});
|
|
195
|
+
rl.on("close", () => {
|
|
196
|
+
client.disconnect();
|
|
197
|
+
console.log("\n👋 Goodbye!");
|
|
198
|
+
process.exit(0);
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
catch (error) {
|
|
202
|
+
console.error("❌ Connection failed:", error);
|
|
203
|
+
rl.close();
|
|
204
|
+
process.exit(1);
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
export const chatCommand = new Command("chat")
|
|
208
|
+
.description("Chat with 0xKobold")
|
|
209
|
+
.argument("[message]", "Message to send")
|
|
210
|
+
.option("-s, --session <id>", "Session ID")
|
|
211
|
+
.option("-a, --agent <id>", "Agent ID")
|
|
212
|
+
.option("-i, --interactive", "Start interactive mode")
|
|
213
|
+
.action(async (message, options) => {
|
|
214
|
+
if (options.interactive) {
|
|
215
|
+
await interactiveCommand.parseAsync([]);
|
|
216
|
+
}
|
|
217
|
+
else if (message) {
|
|
218
|
+
await sendCommand.parseAsync([message]);
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
console.log("Usage:");
|
|
222
|
+
console.log(" 0xkobold chat \"Hello!\" Send a quick message");
|
|
223
|
+
console.log(" 0xkobold chat --interactive Start interactive mode");
|
|
224
|
+
console.log(" 0xkobold chat send <message> Send a message");
|
|
225
|
+
console.log(" 0xkobold chat session list List sessions");
|
|
226
|
+
console.log(" 0xkobold chat history View history");
|
|
227
|
+
console.log("\nRun '0xkobold chat --help' for more options");
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
chatCommand.addCommand(sendCommand);
|
|
231
|
+
chatCommand.addCommand(sessionCommand);
|
|
232
|
+
chatCommand.addCommand(historyCommand);
|
|
233
|
+
chatCommand.addCommand(interactiveCommand);
|
|
234
|
+
//# sourceMappingURL=chat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat.js","sourceRoot":"","sources":["../../../../src/cli/commands/chat.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config CLI command for Kobold
|
|
3
|
+
*
|
|
4
|
+
* Similar to koclaw/openclaw's `openclaw config`
|
|
5
|
+
* Usage: kobold config [get|set|unset|file|validate|init] [args]
|
|
6
|
+
*/
|
|
7
|
+
import * as fs from "node:fs/promises";
|
|
8
|
+
import * as path from "node:path";
|
|
9
|
+
import { loadConfig, getConfig, writeConfig, getConfigValue, setConfigValue, } from "../../config/loader.js";
|
|
10
|
+
import { getConfigPath, getDefaultConfigPath, getLocalConfigPath } from "../../config/paths.js";
|
|
11
|
+
function formatValue(value) {
|
|
12
|
+
if (value === undefined)
|
|
13
|
+
return "undefined";
|
|
14
|
+
if (value === null)
|
|
15
|
+
return "null";
|
|
16
|
+
if (typeof value === "string")
|
|
17
|
+
return `"${value}"`;
|
|
18
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
19
|
+
return String(value);
|
|
20
|
+
return JSON.stringify(value);
|
|
21
|
+
}
|
|
22
|
+
function parseSetValue(raw) {
|
|
23
|
+
// Try JSON first
|
|
24
|
+
try {
|
|
25
|
+
return JSON.parse(raw);
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
// Treat as string
|
|
29
|
+
return raw;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
async function ensureConfigDir() {
|
|
33
|
+
const configPath = getDefaultConfigPath();
|
|
34
|
+
const configDir = path.dirname(configPath);
|
|
35
|
+
try {
|
|
36
|
+
await fs.mkdir(configDir, { recursive: true });
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Directory might already exist
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
async function showHelp() {
|
|
43
|
+
console.log(`Kobold Config - Manage kobold.json configuration
|
|
44
|
+
|
|
45
|
+
Usage:
|
|
46
|
+
kobold config # Show help
|
|
47
|
+
kobold config file # Show current config file path
|
|
48
|
+
kobold config get <path> # Get config value
|
|
49
|
+
kobold config set <path> <value> # Set config value (JSON or string)
|
|
50
|
+
kobold config unset <path> # Remove config value (sets to undefined)
|
|
51
|
+
kobold config validate # Validate current config
|
|
52
|
+
kobold config init # Create default config file
|
|
53
|
+
kobold config edit # Open config in $EDITOR
|
|
54
|
+
|
|
55
|
+
Examples:
|
|
56
|
+
kobold config get agents.defaults.heartbeat.every
|
|
57
|
+
kobold config set agents.defaults.heartbeat.every "1h"
|
|
58
|
+
kobold config set gateway.port 19001
|
|
59
|
+
kobold config unset agents.list[0].skills
|
|
60
|
+
|
|
61
|
+
Config file locations (in order of priority):
|
|
62
|
+
1. $KOBOLD_CONFIG_PATH (env var)
|
|
63
|
+
2. ./kobold.json (current directory)
|
|
64
|
+
3. ~/.config/kobold/kobold.json (default)`);
|
|
65
|
+
}
|
|
66
|
+
export async function handleConfigCommand(args) {
|
|
67
|
+
const subcommand = args[0];
|
|
68
|
+
if (!subcommand || subcommand === "help" || subcommand === "--help") {
|
|
69
|
+
await showHelp();
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
switch (subcommand) {
|
|
73
|
+
case "file": {
|
|
74
|
+
const currentPath = getConfigPath();
|
|
75
|
+
const exists = await fs.access(currentPath).then(() => true).catch(() => false);
|
|
76
|
+
console.log(exists ? `"${currentPath}"` : `"${currentPath}" (not yet created)`);
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case "get": {
|
|
80
|
+
const pathArg = args[1];
|
|
81
|
+
if (!pathArg) {
|
|
82
|
+
console.error("Error: path required. Usage: kobold config get <path>");
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
const config = await loadConfig();
|
|
86
|
+
const value = getConfigValue(pathArg);
|
|
87
|
+
if (value === undefined) {
|
|
88
|
+
console.error(`No value at path: ${pathArg}`);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
console.log(formatValue(value));
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
case "set": {
|
|
95
|
+
const pathArg = args[1];
|
|
96
|
+
const valueArg = args.slice(2).join(" ");
|
|
97
|
+
if (!pathArg || !valueArg) {
|
|
98
|
+
console.error("Error: path and value required. Usage: kobold config set <path> <value>");
|
|
99
|
+
process.exit(1);
|
|
100
|
+
}
|
|
101
|
+
const snapshot = await loadConfig();
|
|
102
|
+
const value = parseSetValue(valueArg);
|
|
103
|
+
const newConfig = setConfigValue(snapshot.config, pathArg, value);
|
|
104
|
+
// Determine where to write
|
|
105
|
+
const configPath = getConfigPath();
|
|
106
|
+
const targetPath = configPath === getDefaultConfigPath() &&
|
|
107
|
+
!(await fs.access(getLocalConfigPath()).then(() => true).catch(() => false))
|
|
108
|
+
? getDefaultConfigPath()
|
|
109
|
+
: configPath;
|
|
110
|
+
await ensureConfigDir();
|
|
111
|
+
await writeConfig(newConfig, targetPath);
|
|
112
|
+
console.log(`Set ${pathArg} = ${formatValue(value)}`);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
case "unset": {
|
|
116
|
+
const pathArg = args[1];
|
|
117
|
+
if (!pathArg) {
|
|
118
|
+
console.error("Error: path required. Usage: kobold config unset <path>");
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
const snapshot = await loadConfig();
|
|
122
|
+
const newConfig = setConfigValue(snapshot.config, pathArg, undefined);
|
|
123
|
+
const configPath = getConfigPath();
|
|
124
|
+
await writeConfig(newConfig, configPath);
|
|
125
|
+
console.log(`Unset ${pathArg}`);
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
case "validate": {
|
|
129
|
+
const snapshot = await loadConfig();
|
|
130
|
+
if (!snapshot.valid) {
|
|
131
|
+
console.error("Config validation failed:");
|
|
132
|
+
for (const issue of snapshot.issues) {
|
|
133
|
+
console.error(` ${issue.path}: ${issue.message}`);
|
|
134
|
+
}
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
137
|
+
if (snapshot.exists) {
|
|
138
|
+
console.log(`✓ Config at "${snapshot.path}" is valid`);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
console.log(`✓ Using defaults (no config file at "${snapshot.path}")`);
|
|
142
|
+
}
|
|
143
|
+
if (snapshot.issues.length > 0) {
|
|
144
|
+
console.log("\nWarnings:");
|
|
145
|
+
for (const issue of snapshot.issues) {
|
|
146
|
+
console.log(` ${issue.path}: ${issue.message}`);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
case "init": {
|
|
152
|
+
const configPath = getConfigPath();
|
|
153
|
+
try {
|
|
154
|
+
await fs.access(configPath);
|
|
155
|
+
console.error(`Config file already exists at "${configPath}"`);
|
|
156
|
+
// Check if --force flag is present
|
|
157
|
+
if (!args.includes("--force")) {
|
|
158
|
+
console.log("Use --force to overwrite");
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
// File doesn't exist, safe to create
|
|
164
|
+
}
|
|
165
|
+
const defaultConfig = getConfig();
|
|
166
|
+
await ensureConfigDir();
|
|
167
|
+
await writeConfig(defaultConfig, configPath);
|
|
168
|
+
console.log(`✓ Created config at "${configPath}"`);
|
|
169
|
+
break;
|
|
170
|
+
}
|
|
171
|
+
case "edit": {
|
|
172
|
+
const editor = process.env.EDITOR || "nano";
|
|
173
|
+
const configPath = getConfigPath();
|
|
174
|
+
// Create file if it doesn't exist
|
|
175
|
+
try {
|
|
176
|
+
await fs.access(configPath);
|
|
177
|
+
}
|
|
178
|
+
catch {
|
|
179
|
+
console.log(`Config file doesn't exist. Creating default config...`);
|
|
180
|
+
const defaultConfig = getConfig();
|
|
181
|
+
await ensureConfigDir();
|
|
182
|
+
await writeConfig(defaultConfig, configPath);
|
|
183
|
+
}
|
|
184
|
+
const { spawn } = await import("node:child_process");
|
|
185
|
+
spawn(editor, [configPath], { stdio: "inherit" });
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
default:
|
|
189
|
+
console.error(`Unknown subcommand: ${subcommand}`);
|
|
190
|
+
await showHelp();
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
// CLI entry point
|
|
195
|
+
if (import.meta.main) {
|
|
196
|
+
const args = process.argv.slice(2);
|
|
197
|
+
handleConfigCommand(args).catch((err) => {
|
|
198
|
+
console.error("Error:", err);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../src/cli/commands/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import { Command } from "commander";
|
|
2
|
+
import { spawn, exec } from "node:child_process";
|
|
3
|
+
import { writeFile, readFile, unlink } from "node:fs/promises";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { homedir } from "node:os";
|
|
7
|
+
import { promisify } from "node:util";
|
|
8
|
+
const execAsync = promisify(exec);
|
|
9
|
+
const KOBOLD_DIR = join(homedir(), ".0xkobold");
|
|
10
|
+
const PID_FILE = join(KOBOLD_DIR, "daemon.pid");
|
|
11
|
+
const LOG_FILE = join(KOBOLD_DIR, "daemon.log");
|
|
12
|
+
async function isDaemonRunning() {
|
|
13
|
+
try {
|
|
14
|
+
if (!existsSync(PID_FILE))
|
|
15
|
+
return false;
|
|
16
|
+
const pid = parseInt(await readFile(PID_FILE, "utf-8"));
|
|
17
|
+
process.kill(pid, 0);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
async function getDaemonPid() {
|
|
25
|
+
try {
|
|
26
|
+
if (!existsSync(PID_FILE))
|
|
27
|
+
return null;
|
|
28
|
+
return parseInt(await readFile(PID_FILE, "utf-8"));
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const startCommand = new Command("start")
|
|
35
|
+
.description("Start the 0xKobold daemon")
|
|
36
|
+
.option("-d, --detach", "Run daemon in background (default: true)")
|
|
37
|
+
.option("-p, --port <port>", "Port to listen on", "3456")
|
|
38
|
+
.action(async (options) => {
|
|
39
|
+
try {
|
|
40
|
+
if (await isDaemonRunning()) {
|
|
41
|
+
const pid = await getDaemonPid();
|
|
42
|
+
console.log(`⚠️ Daemon is already running (PID: ${pid})`);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
console.log("🚀 Starting 0xKobold daemon...");
|
|
46
|
+
// Use TypeScript file directly with Bun (no build required)
|
|
47
|
+
const daemonScript = join(process.cwd(), "daemon/index.ts");
|
|
48
|
+
if (!existsSync(daemonScript)) {
|
|
49
|
+
console.error("❌ Daemon script not found: daemon/index.ts");
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
const env = {
|
|
53
|
+
...process.env,
|
|
54
|
+
KOBOLD_PORT: options.port,
|
|
55
|
+
KOBOLD_DIR
|
|
56
|
+
};
|
|
57
|
+
if (options.detach !== false) {
|
|
58
|
+
const child = spawn("bun", ["run", daemonScript], {
|
|
59
|
+
detached: true,
|
|
60
|
+
stdio: ["ignore", "ignore", "ignore"],
|
|
61
|
+
env
|
|
62
|
+
});
|
|
63
|
+
child.unref();
|
|
64
|
+
if (child.pid) {
|
|
65
|
+
await writeFile(PID_FILE, child.pid.toString());
|
|
66
|
+
}
|
|
67
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
68
|
+
if (await isDaemonRunning()) {
|
|
69
|
+
console.log(`✓ Daemon started (PID: ${child.pid}, Port: ${options.port})`);
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
console.error("❌ Failed to start daemon");
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
const child = spawn("bun", ["run", daemonScript], {
|
|
78
|
+
stdio: "inherit",
|
|
79
|
+
env
|
|
80
|
+
});
|
|
81
|
+
if (child.pid) {
|
|
82
|
+
await writeFile(PID_FILE, child.pid.toString());
|
|
83
|
+
}
|
|
84
|
+
child.on("exit", async (code) => {
|
|
85
|
+
if (existsSync(PID_FILE)) {
|
|
86
|
+
await unlink(PID_FILE);
|
|
87
|
+
}
|
|
88
|
+
process.exit(code || 0);
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
console.error("❌ Failed to start daemon:", error);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
const stopCommand = new Command("stop")
|
|
98
|
+
.description("Stop the 0xKobold daemon")
|
|
99
|
+
.action(async () => {
|
|
100
|
+
try {
|
|
101
|
+
const pid = await getDaemonPid();
|
|
102
|
+
if (!pid) {
|
|
103
|
+
console.log("⚠️ Daemon is not running");
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
console.log("🛑 Stopping daemon...");
|
|
107
|
+
try {
|
|
108
|
+
process.kill(pid, "SIGTERM");
|
|
109
|
+
let attempts = 0;
|
|
110
|
+
while (await isDaemonRunning() && attempts < 10) {
|
|
111
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
112
|
+
attempts++;
|
|
113
|
+
}
|
|
114
|
+
if (await isDaemonRunning()) {
|
|
115
|
+
process.kill(pid, "SIGKILL");
|
|
116
|
+
console.log("✓ Daemon force stopped");
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
console.log("✓ Daemon stopped gracefully");
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
console.log("⚠️ Daemon process not found, cleaning up...");
|
|
124
|
+
}
|
|
125
|
+
if (existsSync(PID_FILE)) {
|
|
126
|
+
await unlink(PID_FILE);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
console.error("❌ Failed to stop daemon:", error);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
const statusCommand = new Command("status")
|
|
135
|
+
.description("Check daemon status")
|
|
136
|
+
.action(async () => {
|
|
137
|
+
try {
|
|
138
|
+
const running = await isDaemonRunning();
|
|
139
|
+
const pid = await getDaemonPid();
|
|
140
|
+
if (running && pid) {
|
|
141
|
+
console.log(`✓ Daemon is running (PID: ${pid})`);
|
|
142
|
+
try {
|
|
143
|
+
const { stdout } = await execAsync(`ps -p ${pid} -o pid,ppid,cmd,%mem,%cpu`);
|
|
144
|
+
console.log("\nProcess details:");
|
|
145
|
+
console.log(stdout);
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
console.log(" Memory/CPU info unavailable");
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
console.log("✗ Daemon is not running");
|
|
153
|
+
if (existsSync(PID_FILE)) {
|
|
154
|
+
console.log(" (stale PID file detected, cleaning up...)");
|
|
155
|
+
await unlink(PID_FILE);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
console.error("❌ Failed to check status:", error);
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
const restartCommand = new Command("restart")
|
|
165
|
+
.description("Restart the daemon")
|
|
166
|
+
.action(async () => {
|
|
167
|
+
console.log("🔄 Restarting daemon...");
|
|
168
|
+
await stopCommand.parseAsync([]);
|
|
169
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
170
|
+
await startCommand.parseAsync([]);
|
|
171
|
+
});
|
|
172
|
+
const logsCommand = new Command("logs")
|
|
173
|
+
.description("View daemon logs")
|
|
174
|
+
.option("-f, --follow", "Follow log output")
|
|
175
|
+
.option("-n, --lines <number>", "Number of lines to show", "50")
|
|
176
|
+
.action(async (options) => {
|
|
177
|
+
try {
|
|
178
|
+
if (!existsSync(LOG_FILE)) {
|
|
179
|
+
console.log("No log file found");
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (options.follow) {
|
|
183
|
+
const tail = spawn("tail", ["-f", LOG_FILE], { stdio: "inherit" });
|
|
184
|
+
tail.on("exit", (code) => process.exit(code || 0));
|
|
185
|
+
}
|
|
186
|
+
else {
|
|
187
|
+
const { stdout } = await execAsync(`tail -n ${options.lines} "${LOG_FILE}"`);
|
|
188
|
+
console.log(stdout);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
catch (error) {
|
|
192
|
+
console.error("❌ Failed to read logs:", error);
|
|
193
|
+
process.exit(1);
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
export const daemonCommand = new Command("daemon")
|
|
197
|
+
.description("Manage the 0xKobold daemon")
|
|
198
|
+
.addCommand(startCommand)
|
|
199
|
+
.addCommand(stopCommand)
|
|
200
|
+
.addCommand(statusCommand)
|
|
201
|
+
.addCommand(restartCommand)
|
|
202
|
+
.addCommand(logsCommand);
|
|
203
|
+
//# sourceMappingURL=daemon.js.map
|