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,181 @@
1
+ /**
2
+ * Self-Update Extension for 0xKobold
3
+ *
4
+ * Manages updates for 0xKobold itself from git repository
5
+ * Workflow:
6
+ * 1. Check git remote for new tags/commits
7
+ * 2. Compare with current HEAD
8
+ * 3. Offer to pull and restart
9
+ */
10
+ import { homedir } from 'node:os';
11
+ import { join } from 'node:path';
12
+ const SELF_UPDATE_FILE = join(homedir(), '.0xkobold', '.self-update-pending');
13
+ async function checkForSelfUpdate() {
14
+ try {
15
+ // Get current version from package.json
16
+ const packageJson = await Bun.file('package.json').json();
17
+ const currentVersion = packageJson.version;
18
+ // Fetch latest tags from git
19
+ const fetchProc = Bun.spawn(['git', 'fetch', '--tags'], {
20
+ cwd: process.cwd(),
21
+ stdout: 'pipe',
22
+ stderr: 'pipe',
23
+ });
24
+ await fetchProc.exited;
25
+ // Get latest tag
26
+ const tagProc = Bun.spawn(['git', 'describe', '--tags', '--abbrev=0'], {
27
+ cwd: process.cwd(),
28
+ stdout: 'pipe',
29
+ stderr: 'pipe',
30
+ });
31
+ const exitCode = await tagProc.exited;
32
+ if (exitCode !== 0) {
33
+ // No tags found - check git log for commits instead
34
+ const logProc = Bun.spawn(['git', 'log', '--oneline', 'HEAD..origin/main'], {
35
+ cwd: process.cwd(),
36
+ stdout: 'pipe',
37
+ stderr: 'pipe',
38
+ });
39
+ const commitsBehind = (await new Response(logProc.stdout).text()).trim();
40
+ const hasCommits = commitsBehind.length > 0;
41
+ return {
42
+ hasUpdate: hasCommits,
43
+ currentVersion,
44
+ latestVersion: hasCommits ? 'new-commits-available' : currentVersion,
45
+ };
46
+ }
47
+ const latestTag = (await new Response(tagProc.stdout).text()).trim();
48
+ // Compare versions (simple semver comparison)
49
+ return {
50
+ hasUpdate: latestTag !== `v${currentVersion}` && latestTag !== currentVersion,
51
+ currentVersion,
52
+ latestVersion: latestTag.replace(/^v/, ''),
53
+ };
54
+ }
55
+ catch {
56
+ return { hasUpdate: false, currentVersion: 'unknown', latestVersion: 'unknown' };
57
+ }
58
+ }
59
+ async function performSelfUpdate(targetVersion) {
60
+ try {
61
+ // Stash any local changes
62
+ await Bun.spawn(['git', 'stash'], { cwd: process.cwd() }).exited;
63
+ // Pull latest
64
+ const pullProc = Bun.spawn(['git', 'pull', 'origin', 'main'], {
65
+ cwd: process.cwd(),
66
+ stdout: 'pipe',
67
+ stderr: 'pipe',
68
+ });
69
+ const exitCode = await pullProc.exited;
70
+ if (exitCode !== 0) {
71
+ return false;
72
+ }
73
+ // Reinstall dependencies
74
+ const installProc = Bun.spawn(['bun', 'install'], {
75
+ cwd: process.cwd(),
76
+ stdout: 'pipe',
77
+ stderr: 'pipe',
78
+ });
79
+ const installExit = await installProc.exited;
80
+ return installExit === 0;
81
+ }
82
+ catch {
83
+ return false;
84
+ }
85
+ }
86
+ async function restartApplication() {
87
+ console.log('[SelfUpdate] Restarting application...');
88
+ await new Promise(r => setTimeout(r, 500));
89
+ const proc = Bun.spawn(['bun', 'run', 'src/index.ts'], {
90
+ cwd: process.cwd(),
91
+ detached: true,
92
+ stdio: ['ignore', 'ignore', 'ignore'],
93
+ });
94
+ proc.unref?.();
95
+ process.exit(0);
96
+ }
97
+ export default function selfUpdateExtension(pi) {
98
+ const checkOnStartup = pi.getFlag('self-update-check') ?? true;
99
+ // Only check for updates in development mode (running from src/, not dist/)
100
+ // This prevents update notifications when running from global install
101
+ const isDevMode = typeof __dirname !== 'undefined' &&
102
+ (__dirname.includes('/src/') || __dirname.includes('\\src\\'));
103
+ // Register flags
104
+ pi.registerFlag('self-update-check', {
105
+ description: 'Check for 0xKobold updates on startup',
106
+ type: 'boolean',
107
+ default: true,
108
+ });
109
+ async function checkAndNotify() {
110
+ const { hasUpdate, currentVersion, latestVersion } = await checkForSelfUpdate();
111
+ if (!hasUpdate) {
112
+ console.log('[SelfUpdate] 0xKobold is up to date');
113
+ return;
114
+ }
115
+ console.log(`[SelfUpdate] Update available: ${latestVersion} (current: ${currentVersion})`);
116
+ // Store update info for commands to access
117
+ // @ts-ignore
118
+ pi.__selfUpdateInfo = { hasUpdate: true, currentVersion, latestVersion };
119
+ }
120
+ // Check on session start - only in main process AND dev mode
121
+ if (checkOnStartup && isDevMode) {
122
+ pi.on('session_start', async (_event, ctx) => {
123
+ // Skip in subagent sessions
124
+ const isSubagent = process.env.KOBOLD_SUBAGENT === 'true' || process.env.PI_SESSION_PARENT;
125
+ if (isSubagent) {
126
+ return;
127
+ }
128
+ // Skip if running with command flags (non-interactive)
129
+ const args = process.argv.slice(2);
130
+ if (args.includes('--command') || args.includes('-c')) {
131
+ return;
132
+ }
133
+ // Delay to let UI initialize
134
+ setTimeout(async () => {
135
+ const { hasUpdate, latestVersion } = await checkForSelfUpdate();
136
+ if (hasUpdate && ctx.ui?.notify) {
137
+ ctx.ui.notify(`🐉 0xKobold update available: ${latestVersion}\nRun /self-update:install to update`, 'info');
138
+ }
139
+ }, 5000);
140
+ });
141
+ }
142
+ // Log mode for debugging
143
+ console.log(`[SelfUpdate] Extension loaded (${isDevMode ? 'dev' : 'production'} mode)`);
144
+ // Register commands
145
+ pi.registerCommand('self-update:check', {
146
+ description: 'Check for 0xKobold updates',
147
+ handler: async (_args, ctx) => {
148
+ await checkAndNotify();
149
+ // Check stored info
150
+ // @ts-ignore
151
+ const info = pi.__selfUpdateInfo;
152
+ if (info?.hasUpdate) {
153
+ ctx.ui.notify(`🐉 Update available: ${info.latestVersion}\nRun /self-update:install to update`, 'info');
154
+ }
155
+ else {
156
+ ctx.ui.notify('✅ 0xKobold is up to date', 'info');
157
+ }
158
+ },
159
+ });
160
+ pi.registerCommand('self-update:install', {
161
+ description: 'Install 0xKobold update and restart',
162
+ handler: async (_args, ctx) => {
163
+ const { hasUpdate, latestVersion } = await checkForSelfUpdate();
164
+ if (!hasUpdate) {
165
+ ctx.ui.notify('✅ No updates available', 'info');
166
+ return;
167
+ }
168
+ ctx.ui.notify(`🔄 Updating to ${latestVersion}...`, 'info');
169
+ const success = await performSelfUpdate(latestVersion);
170
+ if (success) {
171
+ ctx.ui.notify('✅ Update complete. Restarting...', 'info');
172
+ await restartApplication();
173
+ }
174
+ else {
175
+ ctx.ui.notify('❌ Update failed. Check console for errors.', 'error');
176
+ }
177
+ },
178
+ });
179
+ console.log('[SelfUpdate] Extension loaded');
180
+ }
181
+ //# sourceMappingURL=self-update-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"self-update-extension.js","sourceRoot":"","sources":["../../../../src/extensions/core/self-update-extension.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Session Bridge Extension
3
+ *
4
+ * Bridges pi-coding-agent's native session management with 0xKobold's
5
+ * extensions by setting KOBOLD_SESSION_ID environment variable.
6
+ *
7
+ * This allows extensions to get a consistent session ID without managing
8
+ * their own databases or duplicating session storage.
9
+ */
10
+ let currentSessionId = "default";
11
+ /**
12
+ * Generate a human-readable session ID from pi-coding-agent's session data
13
+ * Format: kobold-{timestamp}-{short-hash}
14
+ */
15
+ function generateKoboldSessionId(piSessionId) {
16
+ // pi-coding-agent session IDs are file paths or UUIDs
17
+ // Create a shorter, more readable ID for display
18
+ const hash = piSessionId.slice(-8).replace(/[^a-zA-Z0-9]/g, '');
19
+ const timestamp = Date.now().toString(36).slice(-6);
20
+ return `kobold-${timestamp}-${hash}`;
21
+ }
22
+ /**
23
+ * Session Bridge Extension
24
+ */
25
+ export default function sessionBridgeExtension(pi) {
26
+ // Listen for session start
27
+ pi.on("session_start", async (_event, ctx) => {
28
+ const piSessionId = ctx.sessionManager.getSessionId();
29
+ currentSessionId = generateKoboldSessionId(piSessionId);
30
+ // Set environment variable for legacy extensions
31
+ process.env.KOBOLD_SESSION_ID = currentSessionId;
32
+ process.env.KOBOLD_WORKING_DIR = ctx.sessionManager.getCwd();
33
+ console.log(`[SessionBridge] Session started: ${currentSessionId}`);
34
+ });
35
+ // Update on session switch (e.g., /resume, /fork, /switch)
36
+ pi.on("session_switch", async (event, ctx) => {
37
+ const piSessionId = ctx.sessionManager.getSessionId();
38
+ currentSessionId = generateKoboldSessionId(piSessionId);
39
+ process.env.KOBOLD_SESSION_ID = currentSessionId;
40
+ process.env.KOBOLD_WORKING_DIR = ctx.sessionManager.getCwd();
41
+ console.log(`[SessionBridge] Session switched: ${currentSessionId} (${event.reason})`);
42
+ });
43
+ // Update on fork
44
+ pi.on("session_fork", async (event, ctx) => {
45
+ const piSessionId = ctx.sessionManager.getSessionId();
46
+ currentSessionId = generateKoboldSessionId(piSessionId);
47
+ process.env.KOBOLD_SESSION_ID = currentSessionId;
48
+ process.env.KOBOLD_WORKING_DIR = ctx.sessionManager.getCwd();
49
+ console.log(`[SessionBridge] Session forked: ${currentSessionId}`);
50
+ });
51
+ // Tool to get current session info
52
+ pi.registerTool({
53
+ name: "get_session_info",
54
+ // @ts-ignore ToolDefinition type
55
+ label: "Session Info",
56
+ description: "Get information about the current session",
57
+ // @ts-ignore TSchema mismatch
58
+ parameters: { type: "object", properties: {} },
59
+ async execute() {
60
+ return {
61
+ content: [
62
+ {
63
+ type: "text",
64
+ text: `Session ID: ${currentSessionId}\n` +
65
+ `Working Dir: ${process.env.KOBOLD_WORKING_DIR}\n` +
66
+ `Session File: ${process.env.PI_SESSION_FILE || 'N/A'}`
67
+ },
68
+ ],
69
+ details: {
70
+ sessionId: currentSessionId,
71
+ workingDir: process.env.KOBOLD_WORKING_DIR,
72
+ },
73
+ };
74
+ },
75
+ });
76
+ console.log("[SessionBridge] Extension loaded - bridging pi-coding-agent sessions to 0xKobold");
77
+ }
78
+ //# sourceMappingURL=session-bridge-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-bridge-extension.js","sourceRoot":"","sources":["../../../../src/extensions/core/session-bridge-extension.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,IAAI,gBAAgB,GAAW,SAAS,CAAC;AAEzC;;;GAGG;AACH,SAAS,uBAAuB,CAAC,WAAmB;IAClD,sDAAsD;IACtD,iDAAiD;IACjD,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,eAAe,EAAE,EAAE,CAAC,CAAC;IAChE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,OAAO,UAAU,SAAS,IAAI,IAAI,EAAE,CAAC;AACvC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,EAAgB;IAC7D,2BAA2B;IAC3B,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE;QAC3C,MAAM,WAAW,GAAG,GAAG,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;QACtD,gBAAgB,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAC;QAExD,iDAAiD;QACjD,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,gBAAgB,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,GAAG,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;QAE7D,OAAO,CAAC,GAAG,CAAC,oCAAoC,gBAAgB,EAAE,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IAEH,2DAA2D;IAC3D,EAAE,CAAC,EAAE,CAAC,gBAAgB,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QAC3C,MAAM,WAAW,GAAG,GAAG,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;QACtD,gBAAgB,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAC;QAExD,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,gBAAgB,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,GAAG,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;QAE7D,OAAO,CAAC,GAAG,CAAC,qCAAqC,gBAAgB,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IACzF,CAAC,CAAC,CAAC;IAEH,iBAAiB;IACjB,EAAE,CAAC,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;QACzC,MAAM,WAAW,GAAG,GAAG,CAAC,cAAc,CAAC,YAAY,EAAE,CAAC;QACtD,gBAAgB,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAC;QAExD,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,gBAAgB,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,GAAG,CAAC,cAAc,CAAC,MAAM,EAAE,CAAC;QAE7D,OAAO,CAAC,GAAG,CAAC,mCAAmC,gBAAgB,EAAE,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,mCAAmC;IACnC,EAAE,CAAC,YAAY,CAAC;QACd,IAAI,EAAE,kBAAkB;QACxB,iCAAiC;QACjC,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,2CAA2C;QACxD,8BAA8B;QAC9B,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAS;QACrD,KAAK,CAAC,OAAO;YACX,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAM;wBACZ,IAAI,EAAE,eAAe,gBAAgB,IAAI;4BACnC,gBAAgB,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI;4BAClD,iBAAiB,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,KAAK,EAAE;qBAC9D;iBACF;gBACD,OAAO,EAAE;oBACP,SAAS,EAAE,gBAAgB;oBAC3B,UAAU,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;iBAC3C;aACF,CAAC;QACJ,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,kFAAkF,CAAC,CAAC;AAClG,CAAC"}
@@ -0,0 +1,319 @@
1
+ /**
2
+ * Session Manager Extension
3
+ *
4
+ * Provides isolated sessions for each TUI/Discord instance.
5
+ * Sessions are identified by unique IDs and persisted to SQLite.
6
+ */
7
+ import { Database } from "bun:sqlite";
8
+ import { join } from "path";
9
+ import { homedir } from "os";
10
+ import { existsSync, mkdirSync } from "fs";
11
+ const KOBOLD_DIR = join(homedir(), ".0xkobold");
12
+ const SESSION_DB = join(KOBOLD_DIR, "sessions.db");
13
+ let db = null;
14
+ /**
15
+ * Initialize SQLite database for sessions
16
+ */
17
+ function initDatabase() {
18
+ if (db)
19
+ return db;
20
+ if (!existsSync(KOBOLD_DIR)) {
21
+ mkdirSync(KOBOLD_DIR, { recursive: true });
22
+ }
23
+ db = new Database(SESSION_DB);
24
+ db.run("PRAGMA journal_mode = WAL;");
25
+ // Sessions table
26
+ db.run(`
27
+ CREATE TABLE IF NOT EXISTS sessions (
28
+ id TEXT PRIMARY KEY,
29
+ type TEXT NOT NULL,
30
+ workspace TEXT NOT NULL,
31
+ created_at INTEGER NOT NULL,
32
+ last_activity INTEGER NOT NULL,
33
+ metadata TEXT,
34
+ is_active INTEGER DEFAULT 1
35
+ )
36
+ `);
37
+ // Messages table
38
+ db.run(`
39
+ CREATE TABLE IF NOT EXISTS session_messages (
40
+ id TEXT PRIMARY KEY,
41
+ session_id TEXT NOT NULL,
42
+ role TEXT NOT NULL,
43
+ content TEXT NOT NULL,
44
+ timestamp INTEGER NOT NULL,
45
+ metadata TEXT,
46
+ FOREIGN KEY (session_id) REFERENCES sessions(id) ON DELETE CASCADE
47
+ )
48
+ `);
49
+ // Create indexes
50
+ db.run(`
51
+ CREATE INDEX IF NOT EXISTS idx_messages_session
52
+ ON session_messages(session_id, timestamp)
53
+ `);
54
+ console.log("[SessionManager] Database initialized");
55
+ return db;
56
+ }
57
+ /**
58
+ * Generate unique session ID
59
+ */
60
+ function generateSessionId(type) {
61
+ return `${type}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
62
+ }
63
+ /**
64
+ * Session Manager Extension
65
+ */
66
+ export default function sessionManagerExtension(pi) {
67
+ const database = initDatabase();
68
+ let currentSession = null;
69
+ /**
70
+ * Create or resume a session
71
+ */
72
+ function createSession(type, workspace, resumeId) {
73
+ // Try to resume existing session
74
+ if (resumeId) {
75
+ const existing = database
76
+ .query("SELECT * FROM sessions WHERE id = ? AND type = ?")
77
+ // @ts-ignore SQLite binding
78
+ .get([resumeId, type]);
79
+ if (existing) {
80
+ // Reactivate session
81
+ // @ts-ignore SQLite binding
82
+ database.run("UPDATE sessions SET is_active = 1, last_activity = ? WHERE id = ?", [Date.now(),
83
+ resumeId]);
84
+ const session = {
85
+ id: existing.id,
86
+ type: existing.type,
87
+ workspace,
88
+ createdAt: existing.createdAt,
89
+ lastActivity: Date.now(),
90
+ metadata: JSON.parse(String(existing.metadata || "{}")),
91
+ isActive: true,
92
+ };
93
+ currentSession = session;
94
+ console.log(`[SessionManager] Resumed session: ${session.id}`);
95
+ return session;
96
+ }
97
+ }
98
+ // Create new session
99
+ const sessionId = generateSessionId(type);
100
+ const now = Date.now();
101
+ const session = {
102
+ id: sessionId,
103
+ type,
104
+ workspace,
105
+ createdAt: now,
106
+ lastActivity: now,
107
+ metadata: {
108
+ pid: process.pid,
109
+ platform: process.platform,
110
+ },
111
+ isActive: true,
112
+ };
113
+ // @ts-ignore SQLite binding
114
+ database.run(`INSERT INTO sessions (id, type, workspace, created_at, last_activity, metadata, is_active)
115
+ VALUES (?, ?, ?, ?, ?, ?, ?)`, [session.id,
116
+ session.type,
117
+ session.workspace,
118
+ session.createdAt,
119
+ session.lastActivity,
120
+ JSON.stringify(session.metadata),
121
+ 1]);
122
+ currentSession = session;
123
+ console.log(`[SessionManager] Created session: ${session.id}`);
124
+ return session;
125
+ }
126
+ /**
127
+ * Store a message in the session
128
+ */
129
+ function storeMessage(sessionId, role, content, metadata) {
130
+ const messageId = `msg-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
131
+ // @ts-ignore SQLite binding
132
+ database.run(`INSERT INTO session_messages (id, session_id, role, content, timestamp, metadata)
133
+ VALUES (?, ?, ?, ?, ?, ?)`, [messageId,
134
+ sessionId,
135
+ role,
136
+ content,
137
+ Date.now(),
138
+ JSON.stringify(metadata || {})]);
139
+ // Update session activity
140
+ // @ts-ignore SQLite binding
141
+ database.run("UPDATE sessions SET last_activity = ? WHERE id = ?", [Date.now(),
142
+ sessionId]);
143
+ }
144
+ /**
145
+ * Get conversation history for a session
146
+ */
147
+ function getSessionHistory(sessionId, limit = 100) {
148
+ const rows = database
149
+ .query(`SELECT * FROM session_messages
150
+ WHERE session_id = ?
151
+ ORDER BY timestamp DESC
152
+ LIMIT ?`)
153
+ .all(sessionId, limit);
154
+ return rows
155
+ .map((row) => ({
156
+ id: row.id,
157
+ sessionId: row.session_id,
158
+ role: row.role,
159
+ content: row.content,
160
+ timestamp: row.timestamp,
161
+ metadata: JSON.parse(String(row.metadata || "{}")),
162
+ }))
163
+ .reverse(); // Oldest first
164
+ }
165
+ /**
166
+ * List active sessions for a workspace
167
+ */
168
+ function listSessions(workspace) {
169
+ let query = "SELECT * FROM sessions WHERE is_active = 1";
170
+ const params = [];
171
+ if (workspace) {
172
+ query += " AND workspace = ?";
173
+ params.push(workspace);
174
+ }
175
+ query += " ORDER BY last_activity DESC";
176
+ const rows = database.query(query).all(...params);
177
+ return rows.map((row) => ({
178
+ id: row.id,
179
+ type: row.type,
180
+ workspace: row.workspace,
181
+ createdAt: row.created_at,
182
+ lastActivity: row.last_activity,
183
+ metadata: JSON.parse(String(row.metadata || "{}")),
184
+ isActive: row.is_active === 1,
185
+ }));
186
+ }
187
+ /**
188
+ * Deactivate a session (not delete, just mark inactive)
189
+ */
190
+ function deactivateSession(sessionId) {
191
+ // @ts-ignore SQLite binding
192
+ database.run("UPDATE sessions SET is_active = 0 WHERE id = ?", [sessionId]);
193
+ console.log(`[SessionManager] Deactivated session: ${sessionId}`);
194
+ }
195
+ // Hook into session start
196
+ pi.on("session_start", async (_event, ctx) => {
197
+ const workspace = process.env.KOBOLD_WORKING_DIR || process.cwd();
198
+ const sessionType = process.env.KOBOLD_SESSION_TYPE || "tui";
199
+ const resumeId = process.env.KOBOLD_RESUME_SESSION;
200
+ const session = createSession(sessionType, workspace, resumeId);
201
+ // Store session ID for later use
202
+ process.env.KOBOLD_SESSION_ID = session.id;
203
+ // Load conversation history
204
+ const history = getSessionHistory(session.id, 50);
205
+ if (history.length > 0) {
206
+ ctx.ui?.notify?.(`📝 Resumed session with ${history.length} previous messages`, "info");
207
+ }
208
+ // Set up message interception to store conversations
209
+ const originalSendMessage = pi.sendMessage.bind(pi);
210
+ pi.sendMessage = (msg) => {
211
+ // Store assistant messages
212
+ if (msg.content?.[0]?.text) {
213
+ storeMessage(session.id, "assistant", msg.content[0].text, msg.customType ? { type: msg.customType } : undefined);
214
+ }
215
+ return originalSendMessage(msg);
216
+ };
217
+ });
218
+ // Hook into shutdown
219
+ // @ts-ignore Event type
220
+ pi.on("shutdown", async () => {
221
+ if (currentSession) {
222
+ deactivateSession(currentSession.id);
223
+ }
224
+ });
225
+ // Register commands (renamed to avoid conflicts with pi-coding-agent built-ins)
226
+ pi.registerCommand("kobold-session", {
227
+ description: "Show current session info",
228
+ handler: async (_args, ctx) => {
229
+ if (!currentSession) {
230
+ ctx.ui?.notify?.("No active session", "warning");
231
+ return;
232
+ }
233
+ const history = getSessionHistory(currentSession.id);
234
+ ctx.ui?.notify?.(`📋 Session Info:\n` +
235
+ ` ID: ${currentSession.id}\n` +
236
+ ` Type: ${currentSession.type}\n` +
237
+ ` Workspace: ${currentSession.workspace}\n` +
238
+ ` Messages: ${history.length}\n` +
239
+ ` Started: ${new Date(currentSession.createdAt).toLocaleString()}`, "info");
240
+ },
241
+ });
242
+ pi.registerCommand("kobold-sessions", {
243
+ description: "List active sessions",
244
+ handler: async (_args, ctx) => {
245
+ const sessions = listSessions();
246
+ if (sessions.length === 0) {
247
+ ctx.ui?.notify?.("No active sessions", "info");
248
+ return;
249
+ }
250
+ const lines = sessions.map((s) => {
251
+ const time = new Date(s.lastActivity).toLocaleTimeString();
252
+ const current = s.id === currentSession?.id ? " 👈" : "";
253
+ return ` ${s.type} ${s.id.slice(0, 20)}... (${time})${current}`;
254
+ });
255
+ ctx.ui?.notify?.(`Active Sessions:\n${lines.join("\n")}`, "info");
256
+ },
257
+ });
258
+ pi.registerCommand("kobold-resume", {
259
+ description: "Resume a previous session (requires session ID)",
260
+ // @ts-ignore Command args property
261
+ args: [
262
+ { name: "sessionId", description: "Session ID to resume", required: true },
263
+ ],
264
+ handler: async (args, ctx) => {
265
+ const sessionId = args.sessionId;
266
+ if (!sessionId) {
267
+ ctx.ui?.notify?.("Usage: /resume <session-id>", "warning");
268
+ return;
269
+ }
270
+ const history = getSessionHistory(sessionId);
271
+ if (history.length === 0) {
272
+ ctx.ui?.notify?.("Session not found or empty", "warning");
273
+ return;
274
+ }
275
+ ctx.ui?.notify?.(`Resuming session with ${history.length} messages`,
276
+ // @ts-ignore Notify type
277
+ "success");
278
+ },
279
+ });
280
+ // Register session-aware gateway broadcast
281
+ pi.registerTool({
282
+ name: "session_broadcast",
283
+ description: "Broadcast a message to all clients in current session",
284
+ // @ts-ignore TSchema mismatch
285
+ parameters: {
286
+ type: "object",
287
+ properties: {
288
+ event: { type: "string" },
289
+ payload: { type: "object" },
290
+ },
291
+ required: ["event", "payload"],
292
+ },
293
+ async execute(args) {
294
+ if (!currentSession) {
295
+ return {
296
+ content: [{ type: "text", text: "No active session" }],
297
+ details: { error: "no_session" },
298
+ };
299
+ }
300
+ const { event, payload } = args;
301
+ // Broadcast with session ID
302
+ // @ts-ignore sendMessage type
303
+ // @ts-ignore sendMessage type
304
+ pi.sendMessage({
305
+ customType: "session.broadcast",
306
+ content: [{ type: "text", text: `Session event: ${event}` }],
307
+ // @ts-ignore Content type
308
+ display: { type: "text", text: `📡 ${event}` },
309
+ details: { sessionId: currentSession.id, event, payload },
310
+ });
311
+ return {
312
+ content: [{ type: "text", text: `Broadcasted to session ${currentSession.id}` }],
313
+ details: { sessionId: currentSession.id },
314
+ };
315
+ },
316
+ });
317
+ console.log("[SessionManager] Extension loaded");
318
+ }
319
+ //# sourceMappingURL=session-manager-extension.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-manager-extension.js","sourceRoot":"","sources":["../../../../src/extensions/core/session-manager-extension.ts"],"names":[],"mappings":"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"}