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.
Files changed (258) hide show
  1. package/.agents/skills/nextjs-best-practices/SKILL.md +208 -0
  2. package/.agents/skills/sql-optimization-patterns/SKILL.md +509 -0
  3. package/HEARTBEAT.md +45 -0
  4. package/README.md +197 -0
  5. package/USAGE.md +191 -0
  6. package/dist/package.json +77 -0
  7. package/dist/src/agent/pi-adapter.js +307 -0
  8. package/dist/src/agent/pi-adapter.js.map +1 -0
  9. package/dist/src/agent/tool-adapter.js +86 -0
  10. package/dist/src/agent/tool-adapter.js.map +1 -0
  11. package/dist/src/approval/queue.js +114 -0
  12. package/dist/src/approval/queue.js.map +1 -0
  13. package/dist/src/ascii-kobold.js +76 -0
  14. package/dist/src/ascii-kobold.js.map +1 -0
  15. package/dist/src/cli/client.js +217 -0
  16. package/dist/src/cli/client.js.map +1 -0
  17. package/dist/src/cli/commands/agent.js +272 -0
  18. package/dist/src/cli/commands/agent.js.map +1 -0
  19. package/dist/src/cli/commands/chat.js +234 -0
  20. package/dist/src/cli/commands/chat.js.map +1 -0
  21. package/dist/src/cli/commands/config.js +202 -0
  22. package/dist/src/cli/commands/config.js.map +1 -0
  23. package/dist/src/cli/commands/daemon.js +203 -0
  24. package/dist/src/cli/commands/daemon.js.map +1 -0
  25. package/dist/src/cli/commands/gateway.js +184 -0
  26. package/dist/src/cli/commands/gateway.js.map +1 -0
  27. package/dist/src/cli/commands/init.js +175 -0
  28. package/dist/src/cli/commands/init.js.map +1 -0
  29. package/dist/src/cli/commands/kobold.js +21 -0
  30. package/dist/src/cli/commands/kobold.js.map +1 -0
  31. package/dist/src/cli/commands/logs.js +27 -0
  32. package/dist/src/cli/commands/logs.js.map +1 -0
  33. package/dist/src/cli/commands/mode.js +121 -0
  34. package/dist/src/cli/commands/mode.js.map +1 -0
  35. package/dist/src/cli/commands/persona.js +261 -0
  36. package/dist/src/cli/commands/persona.js.map +1 -0
  37. package/dist/src/cli/commands/start.js +66 -0
  38. package/dist/src/cli/commands/start.js.map +1 -0
  39. package/dist/src/cli/commands/status.js +117 -0
  40. package/dist/src/cli/commands/status.js.map +1 -0
  41. package/dist/src/cli/commands/stop.js +27 -0
  42. package/dist/src/cli/commands/stop.js.map +1 -0
  43. package/dist/src/cli/commands/system.js +128 -0
  44. package/dist/src/cli/commands/system.js.map +1 -0
  45. package/dist/src/cli/commands/tui.js +103 -0
  46. package/dist/src/cli/commands/tui.js.map +1 -0
  47. package/dist/src/cli/commands/update.js +133 -0
  48. package/dist/src/cli/commands/update.js.map +1 -0
  49. package/dist/src/cli/extensions/discord.js +113 -0
  50. package/dist/src/cli/extensions/discord.js.map +1 -0
  51. package/dist/src/cli/extensions/env.js +91 -0
  52. package/dist/src/cli/extensions/env.js.map +1 -0
  53. package/dist/src/cli/extensions/heartbeat.js +78 -0
  54. package/dist/src/cli/extensions/heartbeat.js.map +1 -0
  55. package/dist/src/cli/index.js +24 -0
  56. package/dist/src/cli/index.js.map +1 -0
  57. package/dist/src/cli/program.js +70 -0
  58. package/dist/src/cli/program.js.map +1 -0
  59. package/dist/src/cli/repl.js +184 -0
  60. package/dist/src/cli/repl.js.map +1 -0
  61. package/dist/src/cli/shared/discord-service.js +102 -0
  62. package/dist/src/cli/shared/discord-service.js.map +1 -0
  63. package/dist/src/config/index.js +10 -0
  64. package/dist/src/config/index.js.map +1 -0
  65. package/dist/src/config/loader.js +401 -0
  66. package/dist/src/config/loader.js.map +1 -0
  67. package/dist/src/config/paths.js +84 -0
  68. package/dist/src/config/paths.js.map +1 -0
  69. package/dist/src/config/types.js +8 -0
  70. package/dist/src/config/types.js.map +1 -0
  71. package/dist/src/context-detector.js +60 -0
  72. package/dist/src/context-detector.js.map +1 -0
  73. package/dist/src/discord/index.js +376 -0
  74. package/dist/src/discord/index.js.map +1 -0
  75. package/dist/src/event-bus/index.js +97 -0
  76. package/dist/src/event-bus/index.js.map +1 -0
  77. package/dist/src/extensions/command-args.js +68 -0
  78. package/dist/src/extensions/command-args.js.map +1 -0
  79. package/dist/src/extensions/core/agent-registry-extension.js +541 -0
  80. package/dist/src/extensions/core/agent-registry-extension.js.map +1 -0
  81. package/dist/src/extensions/core/agent-worker.js +148 -0
  82. package/dist/src/extensions/core/agent-worker.js.map +1 -0
  83. package/dist/src/extensions/core/compaction-safeguard.js +154 -0
  84. package/dist/src/extensions/core/compaction-safeguard.js.map +1 -0
  85. package/dist/src/extensions/core/confirm-destructive.js +43 -0
  86. package/dist/src/extensions/core/confirm-destructive.js.map +1 -0
  87. package/dist/src/extensions/core/context-aware-extension.js +124 -0
  88. package/dist/src/extensions/core/context-aware-extension.js.map +1 -0
  89. package/dist/src/extensions/core/context-pruning/extension.js +124 -0
  90. package/dist/src/extensions/core/context-pruning/extension.js.map +1 -0
  91. package/dist/src/extensions/core/context-pruning/pruner.js +312 -0
  92. package/dist/src/extensions/core/context-pruning/pruner.js.map +1 -0
  93. package/dist/src/extensions/core/context-pruning/runtime.js +48 -0
  94. package/dist/src/extensions/core/context-pruning/runtime.js.map +1 -0
  95. package/dist/src/extensions/core/context-pruning/settings.js +105 -0
  96. package/dist/src/extensions/core/context-pruning/settings.js.map +1 -0
  97. package/dist/src/extensions/core/dirty-repo-guard.js +42 -0
  98. package/dist/src/extensions/core/dirty-repo-guard.js.map +1 -0
  99. package/dist/src/extensions/core/discord-channel-extension.js +205 -0
  100. package/dist/src/extensions/core/discord-channel-extension.js.map +1 -0
  101. package/dist/src/extensions/core/discord-extension.js +142 -0
  102. package/dist/src/extensions/core/discord-extension.js.map +1 -0
  103. package/dist/src/extensions/core/env-loader-extension.js +157 -0
  104. package/dist/src/extensions/core/env-loader-extension.js.map +1 -0
  105. package/dist/src/extensions/core/fileops-extension.js +699 -0
  106. package/dist/src/extensions/core/fileops-extension.js.map +1 -0
  107. package/dist/src/extensions/core/gateway-extension.js +730 -0
  108. package/dist/src/extensions/core/gateway-extension.js.map +1 -0
  109. package/dist/src/extensions/core/git-checkpoint.js +46 -0
  110. package/dist/src/extensions/core/git-checkpoint.js.map +1 -0
  111. package/dist/src/extensions/core/handoff-extension.js +206 -0
  112. package/dist/src/extensions/core/handoff-extension.js.map +1 -0
  113. package/dist/src/extensions/core/heartbeat-extension.js +373 -0
  114. package/dist/src/extensions/core/heartbeat-extension.js.map +1 -0
  115. package/dist/src/extensions/core/mcp-extension.js +413 -0
  116. package/dist/src/extensions/core/mcp-extension.js.map +1 -0
  117. package/dist/src/extensions/core/mode-manager-extension.js +562 -0
  118. package/dist/src/extensions/core/mode-manager-extension.js.map +1 -0
  119. package/dist/src/extensions/core/multi-channel-extension.js +435 -0
  120. package/dist/src/extensions/core/multi-channel-extension.js.map +1 -0
  121. package/dist/src/extensions/core/ollama-provider-extension.js +66 -0
  122. package/dist/src/extensions/core/ollama-provider-extension.js.map +1 -0
  123. package/dist/src/extensions/core/onboarding-extension.js +122 -0
  124. package/dist/src/extensions/core/onboarding-extension.js.map +1 -0
  125. package/dist/src/extensions/core/persona-loader-extension.js +139 -0
  126. package/dist/src/extensions/core/persona-loader-extension.js.map +1 -0
  127. package/dist/src/extensions/core/pi-notify-extension.js +70 -0
  128. package/dist/src/extensions/core/pi-notify-extension.js.map +1 -0
  129. package/dist/src/extensions/core/protected-paths.js +24 -0
  130. package/dist/src/extensions/core/protected-paths.js.map +1 -0
  131. package/dist/src/extensions/core/questionnaire-extension.js +242 -0
  132. package/dist/src/extensions/core/questionnaire-extension.js.map +1 -0
  133. package/dist/src/extensions/core/self-update-extension.js +181 -0
  134. package/dist/src/extensions/core/self-update-extension.js.map +1 -0
  135. package/dist/src/extensions/core/session-bridge-extension.js +78 -0
  136. package/dist/src/extensions/core/session-bridge-extension.js.map +1 -0
  137. package/dist/src/extensions/core/session-manager-extension.js +319 -0
  138. package/dist/src/extensions/core/session-manager-extension.js.map +1 -0
  139. package/dist/src/extensions/core/session-name-extension.js +88 -0
  140. package/dist/src/extensions/core/session-name-extension.js.map +1 -0
  141. package/dist/src/extensions/core/session-pruning-extension.js +480 -0
  142. package/dist/src/extensions/core/session-pruning-extension.js.map +1 -0
  143. package/dist/src/extensions/core/task-manager-extension.js +661 -0
  144. package/dist/src/extensions/core/task-manager-extension.js.map +1 -0
  145. package/dist/src/extensions/core/update-extension.js +438 -0
  146. package/dist/src/extensions/core/update-extension.js.map +1 -0
  147. package/dist/src/extensions/core/websearch-extension.js +463 -0
  148. package/dist/src/extensions/core/websearch-extension.js.map +1 -0
  149. package/dist/src/extensions/index.js +5 -0
  150. package/dist/src/extensions/index.js.map +1 -0
  151. package/dist/src/extensions/loader.js +80 -0
  152. package/dist/src/extensions/loader.js.map +1 -0
  153. package/dist/src/gateway/index.js +353 -0
  154. package/dist/src/gateway/index.js.map +1 -0
  155. package/dist/src/index.js +150 -0
  156. package/dist/src/index.js.map +1 -0
  157. package/dist/src/llm/anthropic.js +86 -0
  158. package/dist/src/llm/anthropic.js.map +1 -0
  159. package/dist/src/llm/index.js +9 -0
  160. package/dist/src/llm/index.js.map +1 -0
  161. package/dist/src/llm/ollama.js +113 -0
  162. package/dist/src/llm/ollama.js.map +1 -0
  163. package/dist/src/llm/router.js +145 -0
  164. package/dist/src/llm/router.js.map +1 -0
  165. package/dist/src/llm/types.js +7 -0
  166. package/dist/src/llm/types.js.map +1 -0
  167. package/dist/src/memory/index.js +5 -0
  168. package/dist/src/memory/index.js.map +1 -0
  169. package/dist/src/memory/store.js +91 -0
  170. package/dist/src/memory/store.js.map +1 -0
  171. package/dist/src/pi-config.js +80 -0
  172. package/dist/src/pi-config.js.map +1 -0
  173. package/dist/src/skills/builtin/file.js +184 -0
  174. package/dist/src/skills/builtin/file.js.map +1 -0
  175. package/dist/src/skills/builtin/shell.js +100 -0
  176. package/dist/src/skills/builtin/shell.js.map +1 -0
  177. package/dist/src/skills/builtin/subagent.js +62 -0
  178. package/dist/src/skills/builtin/subagent.js.map +1 -0
  179. package/dist/src/skills/hello.js +42 -0
  180. package/dist/src/skills/hello.js.map +1 -0
  181. package/dist/src/skills/index.js +11 -0
  182. package/dist/src/skills/index.js.map +1 -0
  183. package/dist/src/skills/loader.js +382 -0
  184. package/dist/src/skills/loader.js.map +1 -0
  185. package/dist/src/skills/types.js +8 -0
  186. package/dist/src/skills/types.js.map +1 -0
  187. package/dist/src/utils/working-dir.js +71 -0
  188. package/dist/src/utils/working-dir.js.map +1 -0
  189. package/package.json +77 -0
  190. package/skills/1password/SKILL.md +70 -0
  191. package/skills/1password/references/cli-examples.md +29 -0
  192. package/skills/1password/references/get-started.md +17 -0
  193. package/skills/apple-notes/SKILL.md +77 -0
  194. package/skills/apple-reminders/SKILL.md +118 -0
  195. package/skills/bear-notes/SKILL.md +107 -0
  196. package/skills/blogwatcher/SKILL.md +69 -0
  197. package/skills/blucli/SKILL.md +47 -0
  198. package/skills/bluebubbles/SKILL.md +131 -0
  199. package/skills/camsnap/SKILL.md +45 -0
  200. package/skills/canvas/SKILL.md +198 -0
  201. package/skills/clawhub/SKILL.md +77 -0
  202. package/skills/coding-agent/SKILL.md +284 -0
  203. package/skills/discord/SKILL.md +197 -0
  204. package/skills/eightctl/SKILL.md +50 -0
  205. package/skills/food-order/SKILL.md +48 -0
  206. package/skills/gemini/SKILL.md +43 -0
  207. package/skills/gh-issues/SKILL.md +865 -0
  208. package/skills/gifgrep/SKILL.md +79 -0
  209. package/skills/github/SKILL.md +163 -0
  210. package/skills/gog/SKILL.md +116 -0
  211. package/skills/goplaces/SKILL.md +52 -0
  212. package/skills/healthcheck/SKILL.md +245 -0
  213. package/skills/himalaya/SKILL.md +257 -0
  214. package/skills/himalaya/references/configuration.md +184 -0
  215. package/skills/himalaya/references/message-composition.md +199 -0
  216. package/skills/imsg/SKILL.md +122 -0
  217. package/skills/mcporter/SKILL.md +61 -0
  218. package/skills/model-usage/SKILL.md +69 -0
  219. package/skills/model-usage/references/codexbar-cli.md +33 -0
  220. package/skills/model-usage/scripts/model_usage.py +310 -0
  221. package/skills/nano-banana-pro/SKILL.md +58 -0
  222. package/skills/nano-banana-pro/scripts/generate_image.py +184 -0
  223. package/skills/nano-pdf/SKILL.md +38 -0
  224. package/skills/notion/SKILL.md +172 -0
  225. package/skills/obsidian/SKILL.md +81 -0
  226. package/skills/openai-image-gen/SKILL.md +89 -0
  227. package/skills/openai-image-gen/scripts/gen.py +240 -0
  228. package/skills/openai-whisper/SKILL.md +38 -0
  229. package/skills/openai-whisper-api/SKILL.md +52 -0
  230. package/skills/openai-whisper-api/scripts/transcribe.sh +85 -0
  231. package/skills/openhue/SKILL.md +112 -0
  232. package/skills/oracle/SKILL.md +125 -0
  233. package/skills/ordercli/SKILL.md +78 -0
  234. package/skills/peekaboo/SKILL.md +190 -0
  235. package/skills/sag/SKILL.md +87 -0
  236. package/skills/session-logs/SKILL.md +115 -0
  237. package/skills/sherpa-onnx-tts/SKILL.md +103 -0
  238. package/skills/sherpa-onnx-tts/bin/sherpa-onnx-tts +178 -0
  239. package/skills/skill-creator/SKILL.md +370 -0
  240. package/skills/skill-creator/license.txt +202 -0
  241. package/skills/skill-creator/scripts/init_skill.py +378 -0
  242. package/skills/skill-creator/scripts/package_skill.py +111 -0
  243. package/skills/skill-creator/scripts/quick_validate.py +101 -0
  244. package/skills/slack/SKILL.md +144 -0
  245. package/skills/songsee/SKILL.md +49 -0
  246. package/skills/sonoscli/SKILL.md +46 -0
  247. package/skills/spotify-player/SKILL.md +64 -0
  248. package/skills/summarize/SKILL.md +87 -0
  249. package/skills/things-mac/SKILL.md +86 -0
  250. package/skills/tmux/SKILL.md +153 -0
  251. package/skills/tmux/scripts/find-sessions.sh +112 -0
  252. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  253. package/skills/trello/SKILL.md +95 -0
  254. package/skills/video-frames/SKILL.md +46 -0
  255. package/skills/video-frames/scripts/frame.sh +81 -0
  256. package/skills/voice-call/SKILL.md +45 -0
  257. package/skills/wacli/SKILL.md +72 -0
  258. package/skills/weather/SKILL.md +112 -0
@@ -0,0 +1,435 @@
1
+ /**
2
+ * Multi-Channel Extension
3
+ *
4
+ * Supports Discord, Web, and future channels with unified session management.
5
+ * Each channel type has its own message format, but shares session and memory.
6
+ */
7
+ import { Database } from "bun:sqlite";
8
+ import { join } from "path";
9
+ import { homedir } from "os";
10
+ import { existsSync, mkdirSync } from "fs";
11
+ import { parseArgs } from "../command-args.js";
12
+ const KOBOLD_DIR = join(homedir(), ".0xkobold");
13
+ const CHANNELS_DB = join(KOBOLD_DIR, "channels.db");
14
+ let db = null;
15
+ let currentChannel = null;
16
+ /**
17
+ * Initialize channels database
18
+ */
19
+ function initDatabase() {
20
+ if (db)
21
+ return db;
22
+ if (!existsSync(KOBOLD_DIR)) {
23
+ mkdirSync(KOBOLD_DIR, { recursive: true });
24
+ }
25
+ db = new Database(CHANNELS_DB);
26
+ db.run("PRAGMA journal_mode = WAL;");
27
+ // Channel configs
28
+ db.run(`
29
+ CREATE TABLE IF NOT EXISTS channel_configs (
30
+ id TEXT PRIMARY KEY,
31
+ type TEXT NOT NULL,
32
+ channel_id TEXT,
33
+ user_id TEXT NOT NULL,
34
+ guild_id TEXT,
35
+ webhook_url TEXT,
36
+ session_id TEXT NOT NULL,
37
+ workspace TEXT NOT NULL,
38
+ created_at INTEGER NOT NULL
39
+ )
40
+ `);
41
+ // Unified message log
42
+ db.run(`
43
+ CREATE TABLE IF NOT EXISTS channel_messages (
44
+ id TEXT PRIMARY KEY,
45
+ channel_id TEXT NOT NULL,
46
+ session_id TEXT NOT NULL,
47
+ source TEXT NOT NULL,
48
+ role TEXT NOT NULL,
49
+ content TEXT NOT NULL,
50
+ timestamp INTEGER NOT NULL,
51
+ metadata TEXT
52
+ )
53
+ `);
54
+ // Channel state (for syncing across instances)
55
+ db.run(`
56
+ CREATE TABLE IF NOT EXISTS channel_state (
57
+ channel_id TEXT PRIMARY KEY,
58
+ last_message_id TEXT,
59
+ last_activity INTEGER,
60
+ typing_since INTEGER
61
+ )
62
+ `);
63
+ // Indexes
64
+ db.run(`CREATE INDEX IF NOT EXISTS idx_messages_channel ON channel_messages(channel_id, timestamp)`);
65
+ db.run(`CREATE INDEX IF NOT EXISTS idx_messages_session ON channel_messages(session_id)`);
66
+ console.log("[MultiChannel] Database initialized");
67
+ return db;
68
+ }
69
+ /**
70
+ * Generate channel ID
71
+ */
72
+ function generateChannelId(type) {
73
+ return `${type}-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
74
+ }
75
+ /**
76
+ * Multi-Channel Extension
77
+ */
78
+ export default function multiChannelExtension(pi) {
79
+ const database = initDatabase();
80
+ /**
81
+ * Get or create channel
82
+ */
83
+ function getOrCreateChannel(type, userId, sessionId, channelId, guildId) {
84
+ // Check for existing channel
85
+ let existing;
86
+ if (type === "discord" && channelId) {
87
+ existing = database.query("SELECT * FROM channel_configs WHERE type = ? AND channel_id = ?"
88
+ // @ts-ignore SQLite binding
89
+ ).get([type, channelId]);
90
+ }
91
+ if (!existing) {
92
+ const id = generateChannelId(type);
93
+ const now = Date.now();
94
+ const workspace = join(KOBOLD_DIR, "workspaces", type, id);
95
+ const config = {
96
+ id,
97
+ type,
98
+ channelId,
99
+ userId,
100
+ guildId,
101
+ sessionId,
102
+ workspace,
103
+ createdAt: now,
104
+ };
105
+ // @ts-ignore SQLite binding
106
+ database.run(`INSERT INTO channel_configs (id, type, channel_id, user_id, guild_id, session_id, workspace, created_at)
107
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [config.id,
108
+ config.type,
109
+ config.channelId || null,
110
+ config.userId,
111
+ config.guildId || null,
112
+ config.sessionId,
113
+ config.workspace,
114
+ config.createdAt]);
115
+ console.log(`[MultiChannel] Created ${type} channel: ${id.slice(0, 8)}...`);
116
+ return config;
117
+ }
118
+ return {
119
+ id: existing.id,
120
+ type: existing.type,
121
+ channelId: existing.channel_id,
122
+ userId: existing.user_id,
123
+ guildId: existing.guild_id,
124
+ webhookUrl: existing.webhook_url,
125
+ sessionId: existing.session_id,
126
+ workspace: existing.workspace,
127
+ createdAt: existing.created_at,
128
+ };
129
+ }
130
+ /**
131
+ * Store message
132
+ */
133
+ function storeMessage(channelId, sessionId, source, role, content, metadata) {
134
+ const msg = {
135
+ id: `msg-${Date.now()}`,
136
+ channelId,
137
+ sessionId,
138
+ source,
139
+ role,
140
+ content,
141
+ timestamp: Date.now(),
142
+ metadata,
143
+ };
144
+ // @ts-ignore SQLite binding
145
+ database.run(`INSERT INTO channel_messages (id, channel_id, session_id, source, role, content, timestamp, metadata)
146
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, [msg.id,
147
+ msg.channelId,
148
+ msg.sessionId,
149
+ msg.source,
150
+ msg.role,
151
+ msg.content,
152
+ msg.timestamp,
153
+ JSON.stringify(metadata || {})]);
154
+ // Update channel state
155
+ // @ts-ignore SQLite binding
156
+ database.run(`INSERT INTO channel_state (channel_id, last_message_id, last_activity)
157
+ VALUES (?, ?, ?)
158
+ ON CONFLICT(channel_id) DO UPDATE SET
159
+ last_message_id = excluded.last_message_id,
160
+ last_activity = excluded.last_activity`, [channelId,
161
+ msg.id,
162
+ msg.timestamp]);
163
+ return msg;
164
+ }
165
+ /**
166
+ * Get channel history
167
+ */
168
+ function getChannelHistory(channelId, limit = 50) {
169
+ const rows = database.query(`SELECT * FROM channel_messages
170
+ WHERE channel_id = ?
171
+ ORDER BY timestamp DESC
172
+ LIMIT ?`).all(channelId, limit);
173
+ return rows.map(r => ({
174
+ id: r.id,
175
+ channelId: r.channel_id,
176
+ sessionId: r.session_id,
177
+ source: r.source,
178
+ role: r.role,
179
+ content: r.content,
180
+ timestamp: r.timestamp,
181
+ metadata: JSON.parse(String(r.metadata || "{}")),
182
+ })).reverse();
183
+ }
184
+ /**
185
+ * Broadcast message to all instances of channel
186
+ */
187
+ function broadcastToChannel(channelId, message) {
188
+ // In real implementation, would use WebSocket/pub-sub
189
+ // For now, we just store and rely on polling
190
+ console.log(`[MultiChannel] Broadcast to ${channelId}: ${message.content.slice(0, 50)}...`);
191
+ }
192
+ // ═══════════════════════════════════════════════════════════════
193
+ // EVENT HANDLERS
194
+ // ═══════════════════════════════════════════════════════════════
195
+ pi.on("session_start", async (_event, ctx) => {
196
+ const sessionId = ctx.sessionManager.getSessionId();
197
+ const channelType = (process.env.KOBOLD_CHANNEL_TYPE || "tui");
198
+ const userId = process.env.KOBOLD_USER_ID || "anonymous";
199
+ currentChannel = getOrCreateChannel(channelType, userId, sessionId, process.env.KOBOLD_CHANNEL_ID, process.env.KOBOLD_GUILD_ID);
200
+ // Load history
201
+ const history = getChannelHistory(currentChannel.id, 50);
202
+ if (history.length > 0) {
203
+ console.log(`[MultiChannel] Loaded ${history.length} messages from ${channelType} channel`);
204
+ }
205
+ // Set environment for tools
206
+ process.env.KOBOLD_CHANNEL_CONFIG_ID = currentChannel.id;
207
+ });
208
+ // Update on session switch
209
+ pi.on("session_switch", async (event, ctx) => {
210
+ const sessionId = ctx.sessionManager.getSessionId();
211
+ if (currentChannel) {
212
+ currentChannel.sessionId = sessionId;
213
+ }
214
+ });
215
+ // @ts-ignore Event type
216
+ pi.on("message", async (event, ctx) => {
217
+ if (!currentChannel)
218
+ return;
219
+ // Store incoming message
220
+ storeMessage(currentChannel.id, currentChannel.sessionId, currentChannel.type, "user", event.content || "", { timestamp: Date.now() });
221
+ });
222
+ // @ts-ignore Event type
223
+ pi.on("reply", async (event, ctx) => {
224
+ if (!currentChannel)
225
+ return;
226
+ // Store outgoing message
227
+ storeMessage(currentChannel.id, currentChannel.sessionId, currentChannel.type, "assistant", event.content || "", { timestamp: Date.now() });
228
+ });
229
+ // ═══════════════════════════════════════════════════════════════
230
+ // COMMANDS
231
+ // ═══════════════════════════════════════════════════════════════
232
+ pi.registerCommand("channel", {
233
+ description: "Show current channel info",
234
+ handler: async (_args, ctx) => {
235
+ if (!currentChannel) {
236
+ ctx.ui?.notify?.("No active channel", "warning");
237
+ return;
238
+ }
239
+ const history = getChannelHistory(currentChannel.id, 1);
240
+ const lines = [
241
+ `📡 Channel Info`,
242
+ ``,
243
+ `Type: ${currentChannel.type}`,
244
+ `ID: ${currentChannel.id}`,
245
+ `Session: ${currentChannel.sessionId.slice(0, 16)}...`,
246
+ `Workspace: ${currentChannel.workspace}`,
247
+ `User: ${currentChannel.userId}`,
248
+ ];
249
+ if (currentChannel.channelId) {
250
+ lines.push(`Channel: ${currentChannel.channelId}`);
251
+ }
252
+ if (currentChannel.guildId) {
253
+ lines.push(`Guild: ${currentChannel.guildId}`);
254
+ }
255
+ lines.push(`Messages: ${history.length}+`);
256
+ ctx.ui?.notify?.(lines.join("\n"), "info");
257
+ },
258
+ });
259
+ pi.registerCommand("channels", {
260
+ description: "List active channels",
261
+ // @ts-ignore Command args property
262
+ args: [{ name: "type", description: "Filter by type (tui/discord/web)", required: false }],
263
+ handler: async (args, ctx) => {
264
+ let query = "SELECT * FROM channel_configs";
265
+ const params = [];
266
+ if (args.type) {
267
+ query += " WHERE type = ?";
268
+ params.push(args.type);
269
+ }
270
+ query += " ORDER BY created_at DESC";
271
+ const rows = database.query(query).all(...params);
272
+ if (rows.length === 0) {
273
+ ctx.ui?.notify?.("No channels yet", "info");
274
+ return;
275
+ }
276
+ const grouped = rows.reduce((acc, r) => {
277
+ if (!acc[r.type])
278
+ acc[r.type] = [];
279
+ acc[r.type].push(r);
280
+ return acc;
281
+ }, {});
282
+ const lines = ["📡 Channels\n"];
283
+ for (const [type, channels] of Object.entries(grouped)) {
284
+ lines.push(`${type.toUpperCase()}:`);
285
+ for (const c of channels) {
286
+ const current = c.id === currentChannel?.id ? " 👈" : "";
287
+ lines.push(` ${c.id.slice(0, 20)}... (${c.session_id.slice(0, 8)}...)${current}`);
288
+ }
289
+ lines.push("");
290
+ }
291
+ ctx.ui?.notify?.(lines.join("\n"), "info");
292
+ },
293
+ });
294
+ pi.registerCommand("channel-history", {
295
+ description: "Show recent channel messages",
296
+ // @ts-ignore Command args property
297
+ args: [{ name: "limit", description: "Number of messages (default: 10)", required: false }],
298
+ handler: async (args, ctx) => {
299
+ if (!currentChannel) {
300
+ ctx.ui?.notify?.("No active channel", "warning");
301
+ return;
302
+ }
303
+ const parsed = parseArgs(args, [{ name: "limit", required: false }]);
304
+ const limit = parseInt(String(parsed.limit)) || 10;
305
+ const history = getChannelHistory(currentChannel.id, limit);
306
+ if (history.length === 0) {
307
+ ctx.ui?.notify?.("No messages in channel", "info");
308
+ return;
309
+ }
310
+ const lines = ["💬 Recent Messages\n"];
311
+ for (const msg of history) {
312
+ const time = new Date(msg.timestamp).toLocaleTimeString();
313
+ const prefix = msg.role === "user" ? "👤" : "🤖";
314
+ lines.push(`${prefix} [${time}] ${msg.content.slice(0, 60)}...`);
315
+ }
316
+ ctx.ui?.notify?.(lines.join("\n"), "info");
317
+ },
318
+ });
319
+ // ═══════════════════════════════════════════════════════════════
320
+ // TOOLS
321
+ // ═══════════════════════════════════════════════════════════════
322
+ pi.registerTool({
323
+ name: "channel_broadcast",
324
+ description: "Broadcast a message to all channel participants",
325
+ // @ts-ignore TSchema mismatch
326
+ parameters: {
327
+ type: "object",
328
+ properties: {
329
+ content: { type: "string", description: "Message content" },
330
+ channel_id: { type: "string", description: "Target channel (default: current)" },
331
+ },
332
+ required: ["content"],
333
+ },
334
+ async execute(args) {
335
+ if (!currentChannel) {
336
+ return {
337
+ content: [{ type: "text", text: "No active channel" }],
338
+ details: { error: "no_channel" },
339
+ };
340
+ }
341
+ const content = String(args.content);
342
+ const targetChannel = String(args.channel_id || currentChannel.id);
343
+ const msg = storeMessage(targetChannel, currentChannel.sessionId, currentChannel.type, "assistant", content, { broadcast: true });
344
+ broadcastToChannel(targetChannel, msg);
345
+ return {
346
+ content: [{ type: "text", text: `Broadcast to ${targetChannel}` }],
347
+ details: { channelId: targetChannel, messageId: msg.id },
348
+ };
349
+ },
350
+ });
351
+ pi.registerTool({
352
+ name: "channel_switch",
353
+ description: "Switch to a different channel (for multi-channel agents)",
354
+ // @ts-ignore TSchema mismatch
355
+ parameters: {
356
+ type: "object",
357
+ properties: {
358
+ channel_id: { type: "string", description: "Channel ID to switch to" },
359
+ },
360
+ required: ["channel_id"],
361
+ },
362
+ async execute(args) {
363
+ const channelId = String(args.channel_id);
364
+ // @ts-ignore SQLite binding
365
+ const config = database.query("SELECT * FROM channel_configs WHERE id = ?").get([channelId]);
366
+ if (!config) {
367
+ return {
368
+ content: [{ type: "text", text: `Channel ${channelId} not found` }],
369
+ details: { error: "not_found" },
370
+ };
371
+ }
372
+ currentChannel = {
373
+ id: config.id,
374
+ type: config.type,
375
+ channelId: config.channel_id,
376
+ userId: config.user_id,
377
+ guildId: config.guild_id,
378
+ webhookUrl: config.webhook_url,
379
+ sessionId: config.session_id,
380
+ workspace: config.workspace,
381
+ createdAt: config.created_at,
382
+ };
383
+ return {
384
+ content: [{ type: "text", text: `Switched to ${config.type} channel ${channelId}` }],
385
+ details: { channel: currentChannel },
386
+ };
387
+ },
388
+ });
389
+ pi.registerTool({
390
+ name: "channel_stats",
391
+ description: "Get statistics across all channels",
392
+ // @ts-ignore TSchema type mismatch
393
+ // @ts-ignore TSchema mismatch
394
+ parameters: { type: "object", properties: {} },
395
+ async execute() {
396
+ const channels = database.query("SELECT type, COUNT(*) as count FROM channel_configs GROUP BY type").all();
397
+ // @ts-ignore SQLite binding
398
+ const messages = database.query("SELECT COUNT(*) as total FROM channel_messages").get();
399
+ const today = Date.now() - (24 * 60 * 60 * 1000);
400
+ const recent = database.query("SELECT COUNT(*) as count FROM channel_messages WHERE timestamp > ?"
401
+ // @ts-ignore SQLite binding
402
+ ).get([today]);
403
+ return {
404
+ content: [
405
+ { type: "text", text: `Channel Stats:\n` +
406
+ `Total Channels: ${channels.reduce((a, c) => a + c.count, 0)}\n` +
407
+ channels.map(c => ` ${c.type}: ${c.count}`).join("\n") +
408
+ `\nTotal Messages: ${messages?.total || 0}\n` +
409
+ `Last 24h: ${recent?.count || 0}`
410
+ },
411
+ ],
412
+ details: { channels, messages: messages?.total, recent: recent?.count },
413
+ };
414
+ },
415
+ });
416
+ // Status bar
417
+ // @ts-ignore ExtensionAPI property
418
+ // pi.registerStatusBarItem("channel", {
419
+ // render() {
420
+ // if (!currentChannel) return "";
421
+ // const icons: Record<ChannelType, string> = {
422
+ // tui: "💻",
423
+ // discord: "💬",
424
+ // web: "🌐",
425
+ // slack: "💼",
426
+ // telegram: "✈️",
427
+ // };
428
+ // return `${icons[currentChannel.type]} ${currentChannel.type}`;
429
+ // },
430
+ // });
431
+ console.log("[MultiChannel] Multi-channel support loaded");
432
+ console.log("[MultiChannel] Commands: /channel, /channels, /channel-history");
433
+ console.log("[MultiChannel] Supports: TUI, Discord, Web, Slack, Telegram");
434
+ }
435
+ //# sourceMappingURL=multi-channel-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-channel-extension.js","sourceRoot":"","sources":["../../../../src/extensions/core/multi-channel-extension.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AA2B/C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAChD,MAAM,WAAW,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;AAEpD,IAAI,EAAE,GAAoB,IAAI,CAAC;AAC/B,IAAI,cAAc,GAAyB,IAAI,CAAC;AAEhD;;GAEG;AACH,SAAS,YAAY;IACnB,IAAI,EAAE;QAAE,OAAO,EAAE,CAAC;IAElB,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,EAAE,GAAG,IAAI,QAAQ,CAAC,WAAW,CAAC,CAAC;IAC/B,EAAE,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;IAErC,kBAAkB;IAClB,EAAE,CAAC,GAAG,CAAC;;;;;;;;;;;;GAYN,CAAC,CAAC;IAEH,sBAAsB;IACtB,EAAE,CAAC,GAAG,CAAC;;;;;;;;;;;GAWN,CAAC,CAAC;IAEH,+CAA+C;IAC/C,EAAE,CAAC,GAAG,CAAC;;;;;;;GAON,CAAC,CAAC;IAEH,UAAU;IACV,EAAE,CAAC,GAAG,CAAC,4FAA4F,CAAC,CAAC;IACrG,EAAE,CAAC,GAAG,CAAC,iFAAiF,CAAC,CAAC;IAE1F,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;IACnD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED;;GAEG;AACH,SAAS,iBAAiB,CAAC,IAAiB;IAC1C,OAAO,GAAG,IAAI,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;AAC3E,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,EAAgB;IAC5D,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAEhC;;OAEG;IACH,SAAS,kBAAkB,CACzB,IAAiB,EACjB,MAAc,EACd,SAAiB,EACjB,SAAkB,EAClB,OAAgB;QAEhB,6BAA6B;QAC7B,IAAI,QAAQ,CAAC;QAEb,IAAI,IAAI,KAAK,SAAS,IAAI,SAAS,EAAE,CAAC;YACpC,QAAQ,GAAG,QAAQ,CAAC,KAAK,CACvB,iEAAiE;YACnE,4BAA4B;aAC3B,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,SAAS,CAAC,CAAQ,CAAC;QAClC,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,EAAE,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;YACnC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YAE3D,MAAM,MAAM,GAAkB;gBAC5B,EAAE;gBACF,IAAI;gBACJ,SAAS;gBACT,MAAM;gBACN,OAAO;gBACP,SAAS;gBACT,SAAS;gBACT,SAAS,EAAE,GAAG;aACf,CAAC;YAER,4BAA4B;YACtB,QAAQ,CAAC,GAAG,CACV;yCACiC,EACjC,CAAC,MAAM,CAAC,EAAE;gBACV,MAAM,CAAC,IAAI;gBACX,MAAM,CAAC,SAAS,IAAI,IAAI;gBACxB,MAAM,CAAC,MAAM;gBACb,MAAM,CAAC,OAAO,IAAI,IAAI;gBACtB,MAAM,CAAC,SAAS;gBAChB,MAAM,CAAC,SAAS;gBAChB,MAAM,CAAC,SAAS,CAAC,CAClB,CAAC;YAEF,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,aAAa,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;YAC5E,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,OAAO;YACL,EAAE,EAAE,QAAQ,CAAC,EAAE;YACf,IAAI,EAAE,QAAQ,CAAC,IAAI;YACnB,SAAS,EAAE,QAAQ,CAAC,UAAU;YAC9B,MAAM,EAAE,QAAQ,CAAC,OAAO;YACxB,OAAO,EAAE,QAAQ,CAAC,QAAQ;YAC1B,UAAU,EAAE,QAAQ,CAAC,WAAW;YAChC,SAAS,EAAE,QAAQ,CAAC,UAAU;YAC9B,SAAS,EAAE,QAAQ,CAAC,SAAS;YAC7B,SAAS,EAAE,QAAQ,CAAC,UAAU;SAC/B,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,SAAS,YAAY,CACnB,SAAiB,EACjB,SAAiB,EACjB,MAAmB,EACnB,IAA0B,EAC1B,OAAe,EACf,QAAkC;QAElC,MAAM,GAAG,GAAY;YACnB,EAAE,EAAE,OAAO,IAAI,CAAC,GAAG,EAAE,EAAE;YACvB,SAAS;YACT,SAAS;YACT,MAAM;YACN,IAAI;YACJ,OAAO;YACP,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,QAAQ;SACT,CAAC;QAEN,4BAA4B;QACxB,QAAQ,CAAC,GAAG,CACV;uCACiC,EACjC,CAAC,GAAG,CAAC,EAAE;YACP,GAAG,CAAC,SAAS;YACb,GAAG,CAAC,SAAS;YACb,GAAG,CAAC,MAAM;YACV,GAAG,CAAC,IAAI;YACR,GAAG,CAAC,OAAO;YACX,GAAG,CAAC,SAAS;YACb,IAAI,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,CAChC,CAAC;QAEF,uBAAuB;QAC3B,4BAA4B;QACxB,QAAQ,CAAC,GAAG,CACV;;;;8CAIwC,EACxC,CAAC,SAAS;YACV,GAAG,CAAC,EAAE;YACN,GAAG,CAAC,SAAS,CAAC,CACf,CAAC;QAEF,OAAO,GAAG,CAAC;IACb,CAAC;IAED;;OAEG;IACH,SAAS,iBAAiB,CAAC,SAAiB,EAAE,QAAgB,EAAE;QAC9D,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CACzB;;;eAGS,CACV,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,CAAU,CAAC;QAEjC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACpB,EAAE,EAAE,CAAC,CAAC,EAAE;YACR,SAAS,EAAE,CAAC,CAAC,UAAU;YACvB,SAAS,EAAE,CAAC,CAAC,UAAU;YACvB,MAAM,EAAE,CAAC,CAAC,MAAqB;YAC/B,IAAI,EAAE,CAAC,CAAC,IAAI;YACZ,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,IAAI,IAAI,CAAC,CAAC;SACjD,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;IAChB,CAAC;IAED;;OAEG;IACH,SAAS,kBAAkB,CAAC,SAAiB,EAAE,OAAgB;QAC7D,sDAAsD;QACtD,6CAA6C;QAC7C,OAAO,CAAC,GAAG,CAAC,+BAA+B,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;IAC9F,CAAC;IAED,kEAAkE;IAClE,iBAAiB;IACjB,kEAAkE;IAElE,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;QAC3C,MAAM,SAAS,GAAG,GAAG,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;QACpD,MAAM,WAAW,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,KAAK,CAAgB,CAAC;QAC9E,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,WAAW,CAAC;QAEzD,cAAc,GAAG,kBAAkB,CACjC,WAAW,EACX,MAAM,EACN,SAAS,EACT,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAC7B,OAAO,CAAC,GAAG,CAAC,eAAe,CAC5B,CAAC;QAEF,eAAe;QACf,MAAM,OAAO,GAAG,iBAAiB,CAAC,cAAc,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAEzD,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,yBAAyB,OAAO,CAAC,MAAM,kBAAkB,WAAW,UAAU,CAAC,CAAC;QAC9F,CAAC;QAED,4BAA4B;QAC5B,OAAO,CAAC,GAAG,CAAC,wBAAwB,GAAG,cAAc,CAAC,EAAE,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,2BAA2B;IAC3B,EAAE,CAAC,EAAE,CAAC,gBAAgB,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC3C,MAAM,SAAS,GAAG,GAAG,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;QACpD,IAAI,cAAc,EAAE,CAAC;YACnB,cAAc,CAAC,SAAS,GAAG,SAAS,CAAC;QACvC,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,wBAAwB;IACxB,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QACpC,IAAI,CAAC,cAAc;YAAE,OAAO;QAE5B,yBAAyB;QACzB,YAAY,CACV,cAAc,CAAC,EAAE,EACjB,cAAc,CAAC,SAAS,EACxB,cAAc,CAAC,IAAI,EACnB,MAAM,EACN,KAAK,CAAC,OAAO,IAAI,EAAE,EACnB,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAC1B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,wBAAwB;IACxB,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAClC,IAAI,CAAC,cAAc;YAAE,OAAO;QAE5B,yBAAyB;QACzB,YAAY,CACV,cAAc,CAAC,EAAE,EACjB,cAAc,CAAC,SAAS,EACxB,cAAc,CAAC,IAAI,EACnB,WAAW,EACX,KAAK,CAAC,OAAO,IAAI,EAAE,EACnB,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAC1B,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,kEAAkE;IAClE,WAAW;IACX,kEAAkE;IAElE,EAAE,CAAC,eAAe,CAAC,SAAS,EAAE;QAC5B,WAAW,EAAE,2BAA2B;QACxC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;YAC5B,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;gBACjD,OAAO;YACT,CAAC;YAED,MAAM,OAAO,GAAG,iBAAiB,CAAC,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACxD,MAAM,KAAK,GAAG;gBACZ,iBAAiB;gBACjB,EAAE;gBACF,SAAS,cAAc,CAAC,IAAI,EAAE;gBAC9B,OAAO,cAAc,CAAC,EAAE,EAAE;gBAC1B,YAAY,cAAc,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK;gBACtD,cAAc,cAAc,CAAC,SAAS,EAAE;gBACxC,SAAS,cAAc,CAAC,MAAM,EAAE;aACjC,CAAC;YAEF,IAAI,cAAc,CAAC,SAAS,EAAE,CAAC;gBAC7B,KAAK,CAAC,IAAI,CAAC,YAAY,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC;YACrD,CAAC;YACD,IAAI,cAAc,CAAC,OAAO,EAAE,CAAC;gBAC3B,KAAK,CAAC,IAAI,CAAC,UAAU,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC;YACjD,CAAC;YAED,KAAK,CAAC,IAAI,CAAC,aAAa,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC;YAE3C,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,eAAe,CAAC,UAAU,EAAE;QAC7B,WAAW,EAAE,sBAAsB;QACrC,mCAAmC;QACjC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,kCAAkC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC1F,OAAO,EAAE,KAAK,EAAE,IAAS,EAAE,GAAG,EAAE,EAAE;YAChC,IAAI,KAAK,GAAG,+BAA+B,CAAC;YAC5C,MAAM,MAAM,GAAU,EAAE,CAAC;YAEzB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBACd,KAAK,IAAI,iBAAiB,CAAC;gBAC3B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACzB,CAAC;YAED,KAAK,IAAI,2BAA2B,CAAC;YAErC,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAU,CAAC;YAE3D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACtB,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;gBAC5C,OAAO;YACT,CAAC;YAED,MAAM,OAAO,GAA0B,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;gBAC5D,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;oBAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACnC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;gBACpB,OAAO,GAAG,CAAC;YACb,CAAC,EAAE,EAA2B,CAAC,CAAC;YAEhC,MAAM,KAAK,GAAa,CAAC,eAAe,CAAC,CAAC;YAE1C,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACvD,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;gBACrC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;oBACzB,MAAM,OAAO,GAAG,CAAC,CAAC,EAAE,KAAK,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,OAAO,OAAO,EAAE,CAAC,CAAC;gBACrF,CAAC;gBACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACjB,CAAC;YAED,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,eAAe,CAAC,iBAAiB,EAAE;QACpC,WAAW,EAAE,8BAA8B;QAC7C,mCAAmC;QACjC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,kCAAkC,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QAC3F,OAAO,EAAE,KAAK,EAAE,IAAY,EAAE,GAAG,EAAE,EAAE;YACnC,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;gBACjD,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC;YACrE,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;YACnD,MAAM,OAAO,GAAG,iBAAiB,CAAC,cAAc,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YAE5D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,wBAAwB,EAAE,MAAM,CAAC,CAAC;gBACnD,OAAO;YACT,CAAC;YAED,MAAM,KAAK,GAAa,CAAC,sBAAsB,CAAC,CAAC;YAEjD,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;gBAC1B,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,kBAAkB,EAAE,CAAC;gBAC1D,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBACjD,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,KAAK,IAAI,KAAK,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC;YACnE,CAAC;YAED,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAC7C,CAAC;KACF,CAAC,CAAC;IAEH,kEAAkE;IAClE,QAAQ;IACR,kEAAkE;IAElE,EAAE,CAAC,YAAY,CAAC;QACd,IAAI,EAAE,mBAAmB;QACzB,WAAW,EAAE,iDAAiD;QAC9D,8BAA8B;QAC9B,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE;gBAC3D,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,EAAE;aACjF;YACD,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB;QACD,KAAK,CAAC,OAAO,CAAC,IAAS;YACrB,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,mBAAmB,EAAE,CAAC;oBACtD,OAAO,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE;iBACjC,CAAC;YACJ,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACrC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,IAAI,cAAc,CAAC,EAAE,CAAC,CAAC;YAEnE,MAAM,GAAG,GAAG,YAAY,CACtB,aAAa,EACb,cAAc,CAAC,SAAS,EACxB,cAAc,CAAC,IAAI,EACnB,WAAW,EACX,OAAO,EACP,EAAE,SAAS,EAAE,IAAI,EAAE,CACpB,CAAC;YAEF,kBAAkB,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;YAEvC,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,aAAa,EAAE,EAAE,CAAC;gBAClE,OAAO,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,CAAC,EAAE,EAAE;aACzD,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,YAAY,CAAC;QACd,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,0DAA0D;QACvE,8BAA8B;QAC9B,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yBAAyB,EAAE;aACvE;YACD,QAAQ,EAAE,CAAC,YAAY,CAAC;SACzB;QACD,KAAK,CAAC,OAAO,CAAC,IAAS;YACrB,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAChD,4BAA4B;YACtB,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,CAAQ,CAAC;YAEpG,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,OAAO;oBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,SAAS,YAAY,EAAE,CAAC;oBACnE,OAAO,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE;iBAChC,CAAC;YACJ,CAAC;YAED,cAAc,GAAG;gBACf,EAAE,EAAE,MAAM,CAAC,EAAE;gBACb,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,SAAS,EAAE,MAAM,CAAC,UAAU;gBAC5B,MAAM,EAAE,MAAM,CAAC,OAAO;gBACtB,OAAO,EAAE,MAAM,CAAC,QAAQ;gBACxB,UAAU,EAAE,MAAM,CAAC,WAAW;gBAC9B,SAAS,EAAE,MAAM,CAAC,UAAU;gBAC5B,SAAS,EAAE,MAAM,CAAC,SAAS;gBAC3B,SAAS,EAAE,MAAM,CAAC,UAAU;aAC7B,CAAC;YAEF,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,MAAM,CAAC,IAAI,YAAY,SAAS,EAAE,EAAE,CAAC;gBACpF,OAAO,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE;aACrC,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;IAEH,EAAE,CAAC,YAAY,CAAC;QACd,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,oCAAoC;QACnD,mCAAmC;QACjC,8BAA8B;QAC9B,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE;QAC9C,KAAK,CAAC,OAAO;YACX,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,mEAAmE,CAAC,CAAC,GAAG,EAAW,CAAC;YAC1H,4BAA4B;YACtB,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC,GAAG,EAAS,CAAC;YAE/F,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAC3B,oEAAoE;YACtE,4BAA4B;aAC3B,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAQ,CAAC;YAEtB,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,kBAAkB;4BACtC,mBAAmB,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI;4BAChE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;4BACvD,qBAAqB,QAAQ,EAAE,KAAK,IAAI,CAAC,IAAI;4BAC7C,aAAa,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE;qBAClC;iBACF;gBACD,OAAO,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE;aACxE,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;IAEH,aAAa;IACb,mCAAmC;IACrC,0CAA0C;IAC1C,iBAAiB;IACjB,wCAAwC;IACxC,qDAAqD;IACrD,qBAAqB;IACrB,yBAAyB;IACzB,qBAAqB;IACrB,uBAAuB;IACvB,0BAA0B;IAC1B,WAAW;IACX,uEAAuE;IACvE,SAAS;IACT,QAAQ;IAEN,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,gEAAgE,CAAC,CAAC;IAC9E,OAAO,CAAC,GAAG,CAAC,6DAA6D,CAAC,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,66 @@
1
+ /**
2
+ * Ollama Provider Extension for 0xKobold
3
+ *
4
+ * Registers Ollama as a model provider with pi-coding-agent
5
+ * Fixes the "No models available" error by providing Ollama model definitions
6
+ */
7
+ const OLLAMA_BASE_URL = process.env.OLLAMA_URL ?? 'http://localhost:11434';
8
+ export default function ollamaProviderExtension(pi) {
9
+ // Register Ollama as a provider with available models
10
+ // Note: Ollama doesn't require authentication, but pi-coding-agent requires apiKey or oauth
11
+ const models = [
12
+ {
13
+ id: 'kimi-k2.5:cloud',
14
+ name: 'Kimi K2.5 (Cloud)',
15
+ reasoning: true,
16
+ input: ['text', "image"],
17
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
18
+ contextWindow: 256000,
19
+ maxTokens: 8192,
20
+ },
21
+ {
22
+ id: 'minimax-m2.5:cloud',
23
+ name: 'Minimax M2.5 (Cloud)',
24
+ reasoning: true,
25
+ input: ['text'],
26
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
27
+ contextWindow: 198000,
28
+ maxTokens: 8192,
29
+ },
30
+ {
31
+ id: 'glm-5:cloud',
32
+ name: 'GLM-5 (Cloud)',
33
+ reasoning: true,
34
+ input: ['text'],
35
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
36
+ contextWindow: 198000,
37
+ maxTokens: 8192,
38
+ },
39
+ {
40
+ id: 'qwen3.5:cloud',
41
+ name: 'Qwen3.5 (Cloud)',
42
+ reasoning: true,
43
+ input: ['text'],
44
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
45
+ contextWindow: 256000,
46
+ maxTokens: 8192,
47
+ },
48
+ {
49
+ id: 'qwen3.5:397b-cloud',
50
+ name: 'Qwen3.5 397B (Cloud)',
51
+ reasoning: true,
52
+ input: ['text', "image"],
53
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
54
+ contextWindow: 256000,
55
+ maxTokens: 8192,
56
+ },
57
+ ];
58
+ pi.registerProvider('ollama', {
59
+ baseUrl: `${OLLAMA_BASE_URL}/v1`,
60
+ apiKey: 'ollama', // Dummy key (Ollama doesn't require auth for local access)
61
+ api: 'openai-completions',
62
+ models
63
+ });
64
+ console.log(`[Ollama] Provider registered with models: ${models.map(m => m.name).join(', ')}`);
65
+ }
66
+ //# sourceMappingURL=ollama-provider-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama-provider-extension.js","sourceRoot":"","sources":["../../../../src/extensions/core/ollama-provider-extension.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,wBAAwB,CAAC;AAE3E,MAAM,CAAC,OAAO,UAAU,uBAAuB,CAAC,EAAgB;IAC9D,sDAAsD;IACtD,4FAA4F;IAC5F,MAAM,MAAM,GAA0B;QACpC;YACE,EAAE,EAAE,iBAAiB;YACrB,IAAI,EAAE,mBAAmB;YACzB,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;YACxB,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE;YAC1D,aAAa,EAAE,MAAM;YACrB,SAAS,EAAE,IAAI;SAChB;QACD;YACE,EAAE,EAAE,oBAAoB;YACxB,IAAI,EAAE,sBAAsB;YAC5B,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,CAAC,MAAM,CAAC;YACf,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE;YAC1D,aAAa,EAAE,MAAM;YACrB,SAAS,EAAE,IAAI;SAChB;QACD;YACE,EAAE,EAAE,aAAa;YACjB,IAAI,EAAE,eAAe;YACrB,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,CAAC,MAAM,CAAC;YACf,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE;YAC1D,aAAa,EAAE,MAAM;YACrB,SAAS,EAAE,IAAI;SAChB;QACD;YACE,EAAE,EAAE,eAAe;YACnB,IAAI,EAAE,iBAAiB;YACvB,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,CAAC,MAAM,CAAC;YACf,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE;YAC1D,aAAa,EAAE,MAAM;YACrB,SAAS,EAAE,IAAI;SAChB;QACD;YACE,EAAE,EAAE,oBAAoB;YACxB,IAAI,EAAE,sBAAsB;YAC5B,SAAS,EAAE,IAAI;YACf,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC;YACxB,IAAI,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE;YAC1D,aAAa,EAAE,MAAM;YACrB,SAAS,EAAE,IAAI;SAChB;KACF,CAAA;IACD,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE;QAC5B,OAAO,EAAE,GAAG,eAAe,KAAK;QAChC,MAAM,EAAE,QAAQ,EAAE,2DAA2D;QAC7E,GAAG,EAAE,oBAAoB;QACzB,MAAM;KACP,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,6CAA6C,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACjG,CAAC"}
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Onboarding Extension for 0xKobold
3
+ *
4
+ * Handles first-run setup by creating default persona files.
5
+ * Interactive editing can be done later via /persona-edit command.
6
+ */
7
+ import { existsSync, mkdirSync, writeFileSync } from "fs";
8
+ import { join } from "path";
9
+ import { homedir } from "os";
10
+ const PERSONA_DIR = join(homedir(), ".0xkobold");
11
+ const ONBOARDING_FLAG = join(PERSONA_DIR, ".onboarded");
12
+ function isOnboarded() {
13
+ return existsSync(ONBOARDING_FLAG);
14
+ }
15
+ function markOnboarded() {
16
+ writeFileSync(ONBOARDING_FLAG, new Date().toISOString(), "utf-8");
17
+ }
18
+ /**
19
+ * Generate default USER.md
20
+ */
21
+ function generateDefaultUserProfile() {
22
+ return `# User Profile
23
+
24
+ ## Identity
25
+ - **Name**: Developer
26
+ - **Role**: Software Developer
27
+ - **Experience Level**: Intermediate
28
+ - **Preferred Languages**: TypeScript, JavaScript
29
+
30
+ ## Working Style
31
+ - Prefers collaborative approach
32
+ - Wants to understand the "why" behind suggestions
33
+ - Values clean git history
34
+
35
+ ## Preferences
36
+ - **Communication**: Clear and concise
37
+ - **Code Style**: Clean and maintainable
38
+ - **Approach**: Options with trade-offs
39
+
40
+ ## Notes
41
+ Onboarded: ${new Date().toLocaleDateString()}
42
+ Edit this file at ~/.0xkobold/USER.md
43
+ `;
44
+ }
45
+ /**
46
+ * Onboarding Extension
47
+ */
48
+ export default function onboardingExtension(pi) {
49
+ // Check onboarding on session start
50
+ pi.on("session_start", async (_event, ctx) => {
51
+ if (isOnboarded()) {
52
+ return;
53
+ }
54
+ await runOnboarding(ctx);
55
+ });
56
+ async function runOnboarding(ctx) {
57
+ try {
58
+ // Ensure persona directory exists
59
+ if (!existsSync(PERSONA_DIR)) {
60
+ mkdirSync(PERSONA_DIR, { recursive: true });
61
+ }
62
+ // Show welcome message
63
+ ctx.ui?.notify?.("🐉 Welcome to 0xKobold!\n\n" +
64
+ "Your digital familiar is ready.\n" +
65
+ "I've created default persona files for you.\n\n" +
66
+ "To customize:\n" +
67
+ " - Edit ~/.0xkobold/USER.md\n" +
68
+ " - Or run: 0xkobold persona init\n" +
69
+ " - Then: 0xkobold persona edit USER.md\n\n" +
70
+ "Use /help to see all commands.", "info");
71
+ // Create USER.md if it doesn't exist
72
+ const userFile = join(PERSONA_DIR, "USER.md");
73
+ if (!existsSync(userFile)) {
74
+ writeFileSync(userFile, generateDefaultUserProfile(), "utf-8");
75
+ }
76
+ // Mark as onboarded
77
+ markOnboarded();
78
+ }
79
+ catch (error) {
80
+ console.error("[Onboarding] Error:", error);
81
+ ctx.ui?.notify?.("Onboarding error. You can run /setup manually.", "warning");
82
+ }
83
+ }
84
+ // Register commands
85
+ pi.registerCommand("onboarding", {
86
+ description: "Run onboarding (create default persona files)",
87
+ handler: async (_args, ctx) => {
88
+ if (isOnboarded()) {
89
+ ctx.ui?.notify?.("Already onboarded. Run /reset-onboarding to redo.", "info");
90
+ return;
91
+ }
92
+ await runOnboarding(ctx);
93
+ },
94
+ });
95
+ pi.registerCommand("setup", {
96
+ description: "Alias for /onboarding",
97
+ handler: async (_args, ctx) => {
98
+ await runOnboarding(ctx);
99
+ },
100
+ });
101
+ pi.registerCommand("reset-onboarding", {
102
+ description: "Reset onboarding (run it again next session)",
103
+ handler: async (_args, ctx) => {
104
+ try {
105
+ const { unlinkSync } = await import("fs");
106
+ if (existsSync(ONBOARDING_FLAG)) {
107
+ unlinkSync(ONBOARDING_FLAG);
108
+ // @ts-ignore Notify type
109
+ ctx.ui?.notify?.("Onboarding reset. Restart to run again.", "success");
110
+ }
111
+ else {
112
+ ctx.ui?.notify?.("Not yet onboarded.", "info");
113
+ }
114
+ }
115
+ catch (error) {
116
+ ctx.ui?.notify?.("Error: " + error, "error");
117
+ }
118
+ },
119
+ });
120
+ console.log("[Onboarding] Extension loaded");
121
+ }
122
+ //# sourceMappingURL=onboarding-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onboarding-extension.js","sourceRoot":"","sources":["../../../../src/extensions/core/onboarding-extension.ts"],"names":[],"mappings":"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"}