0xkobold 0.7.2 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (252) hide show
  1. package/HEARTBEAT.md +239 -0
  2. package/IDENTITY.md +12 -0
  3. package/README.md +138 -4
  4. package/SOUL.md +21 -0
  5. package/dist/package.json +10 -5
  6. package/dist/src/agent/bootstrap-loader.js +295 -66
  7. package/dist/src/agent/bootstrap-loader.js.map +1 -1
  8. package/dist/src/agent/context-pruning.js +10 -5
  9. package/dist/src/agent/context-pruning.js.map +1 -1
  10. package/dist/src/agent/embedded-runner.js +29 -15
  11. package/dist/src/agent/embedded-runner.js.map +1 -1
  12. package/dist/src/agent/index.js +5 -2
  13. package/dist/src/agent/index.js.map +1 -1
  14. package/dist/src/agent/system-prompt.js +167 -20
  15. package/dist/src/agent/system-prompt.js.map +1 -1
  16. package/dist/src/agent/tools/spawn-agent.js +72 -5
  17. package/dist/src/agent/tools/spawn-agent.js.map +1 -1
  18. package/dist/src/channels/slack/webhook.js +2 -2
  19. package/dist/src/channels/slack/webhook.js.map +1 -1
  20. package/dist/src/channels/telegram/bot.js +4 -4
  21. package/dist/src/channels/telegram/bot.js.map +1 -1
  22. package/dist/src/channels/whatsapp/integration.js +4 -4
  23. package/dist/src/channels/whatsapp/integration.js.map +1 -1
  24. package/dist/src/cli/commands/gateway.js +9 -10
  25. package/dist/src/cli/commands/gateway.js.map +1 -1
  26. package/dist/src/cli/commands/init.js +90 -0
  27. package/dist/src/cli/commands/init.js.map +1 -1
  28. package/dist/src/cli/commands/setup.js +53 -0
  29. package/dist/src/cli/commands/setup.js.map +1 -1
  30. package/dist/src/cli/index.js +0 -0
  31. package/dist/src/config/unified-config.js +5 -0
  32. package/dist/src/config/unified-config.js.map +1 -1
  33. package/dist/src/cron/index.js +2 -0
  34. package/dist/src/cron/index.js.map +1 -1
  35. package/dist/src/cron/nl-parser.js +522 -0
  36. package/dist/src/cron/nl-parser.js.map +1 -0
  37. package/dist/src/cron/runner.js +6 -31
  38. package/dist/src/cron/runner.js.map +1 -1
  39. package/dist/src/event-bus/index.js.map +1 -1
  40. package/dist/src/extensions/core/agent-orchestrator-extension.js +200 -148
  41. package/dist/src/extensions/core/agent-orchestrator-extension.js.map +1 -1
  42. package/dist/src/extensions/core/diagnostics-extension.js +93 -56
  43. package/dist/src/extensions/core/diagnostics-extension.js.map +1 -1
  44. package/dist/src/extensions/core/draconic-safety-extension.js +256 -3
  45. package/dist/src/extensions/core/draconic-safety-extension.js.map +1 -1
  46. package/dist/src/extensions/core/heartbeat-extension.js +416 -150
  47. package/dist/src/extensions/core/heartbeat-extension.js.map +1 -1
  48. package/dist/src/extensions/core/{generative-agents-extension.js → learning-extension.js} +90 -128
  49. package/dist/src/extensions/core/learning-extension.js.map +1 -0
  50. package/dist/src/extensions/core/perennial-memory-extension.js +884 -87
  51. package/dist/src/extensions/core/perennial-memory-extension.js.map +1 -1
  52. package/dist/src/extensions/core/routed-ollama-extension.js +345 -0
  53. package/dist/src/extensions/core/routed-ollama-extension.js.map +1 -0
  54. package/dist/src/extensions/core/task-manager-extension.js +25 -2
  55. package/dist/src/extensions/core/task-manager-extension.js.map +1 -1
  56. package/dist/src/extensions/core/websearch-enhanced-extension.js +81 -23
  57. package/dist/src/extensions/core/websearch-enhanced-extension.js.map +1 -1
  58. package/dist/src/extensions/core/workspace-footer-extension.js +40 -63
  59. package/dist/src/extensions/core/workspace-footer-extension.js.map +1 -1
  60. package/dist/src/extensions/loader.js +5 -1
  61. package/dist/src/extensions/loader.js.map +1 -1
  62. package/dist/src/gateway/gateway-server.js +74 -3
  63. package/dist/src/gateway/gateway-server.js.map +1 -1
  64. package/dist/src/gateway/index.js +2 -2
  65. package/dist/src/gateway/index.js.map +1 -1
  66. package/dist/src/gateway/methods/agent.js +1 -1
  67. package/dist/src/gateway/methods/agent.js.map +1 -1
  68. package/dist/src/gateway/methods/index.js +4 -0
  69. package/dist/src/gateway/methods/index.js.map +1 -1
  70. package/dist/src/gateway/methods/node.js +261 -0
  71. package/dist/src/gateway/methods/node.js.map +1 -0
  72. package/dist/src/gateway/queue-modes.js +356 -0
  73. package/dist/src/gateway/queue-modes.js.map +1 -0
  74. package/dist/src/index.js +47 -6
  75. package/dist/src/index.js.map +1 -1
  76. package/dist/src/llm/community-analytics.js +569 -0
  77. package/dist/src/llm/community-analytics.js.map +1 -0
  78. package/dist/src/llm/index.js +28 -4
  79. package/dist/src/llm/index.js.map +1 -1
  80. package/dist/src/llm/model-discovery.js +335 -0
  81. package/dist/src/llm/model-discovery.js.map +1 -0
  82. package/dist/src/llm/model-popularity.js +566 -0
  83. package/dist/src/llm/model-popularity.js.map +1 -0
  84. package/dist/src/llm/model-scoring-db.js +553 -0
  85. package/dist/src/llm/model-scoring-db.js.map +1 -0
  86. package/dist/src/llm/multi-provider.js +258 -0
  87. package/dist/src/llm/multi-provider.js.map +1 -0
  88. package/dist/src/llm/ollama.js +133 -187
  89. package/dist/src/llm/ollama.js.map +1 -1
  90. package/dist/src/llm/router-commands.js +773 -0
  91. package/dist/src/llm/router-commands.js.map +1 -0
  92. package/dist/src/llm/router-core.js +600 -0
  93. package/dist/src/llm/router-core.js.map +1 -0
  94. package/dist/src/memory/checkpoint-manager.js +278 -0
  95. package/dist/src/memory/checkpoint-manager.js.map +1 -0
  96. package/dist/src/memory/conflict-detector.js +279 -0
  97. package/dist/src/memory/conflict-detector.js.map +1 -0
  98. package/dist/src/memory/context-graph.js +360 -0
  99. package/dist/src/memory/context-graph.js.map +1 -0
  100. package/dist/src/memory/dialectic/benchmark-cli.js +200 -0
  101. package/dist/src/memory/dialectic/benchmark-cli.js.map +1 -0
  102. package/dist/src/memory/dialectic/debug-reasoning.js +37 -0
  103. package/dist/src/memory/dialectic/debug-reasoning.js.map +1 -0
  104. package/dist/src/memory/dialectic/index.js +135 -0
  105. package/dist/src/memory/dialectic/index.js.map +1 -0
  106. package/dist/src/memory/dialectic/nudges.js +380 -0
  107. package/dist/src/memory/dialectic/nudges.js.map +1 -0
  108. package/dist/src/memory/dialectic/reasoning-engine.js +607 -0
  109. package/dist/src/memory/dialectic/reasoning-engine.js.map +1 -0
  110. package/dist/src/memory/dialectic/reasoning.js +390 -0
  111. package/dist/src/memory/dialectic/reasoning.js.map +1 -0
  112. package/dist/src/memory/dialectic/skill-creation.js +481 -0
  113. package/dist/src/memory/dialectic/skill-creation.js.map +1 -0
  114. package/dist/src/memory/dialectic/store.js +663 -0
  115. package/dist/src/memory/dialectic/store.js.map +1 -0
  116. package/dist/src/memory/dialectic/types.js +11 -0
  117. package/dist/src/memory/dialectic/types.js.map +1 -0
  118. package/dist/src/memory/index.js +24 -2
  119. package/dist/src/memory/index.js.map +1 -1
  120. package/dist/src/memory/memory-decay.js +350 -0
  121. package/dist/src/memory/memory-decay.js.map +1 -0
  122. package/dist/src/memory/memory-integration.js +5 -5
  123. package/dist/src/memory/memory-integration.js.map +1 -1
  124. package/dist/src/memory/migrate-memory-stream.js +97 -0
  125. package/dist/src/memory/migrate-memory-stream.js.map +1 -0
  126. package/dist/src/memory/session-memory-bridge.js +49 -5
  127. package/dist/src/memory/session-memory-bridge.js.map +1 -1
  128. package/dist/src/memory/session-store.js +123 -0
  129. package/dist/src/memory/session-store.js.map +1 -1
  130. package/dist/src/memory/smart-write-rules.js +164 -0
  131. package/dist/src/memory/smart-write-rules.js.map +1 -0
  132. package/dist/src/memory/tiered-memory.js +436 -0
  133. package/dist/src/memory/tiered-memory.js.map +1 -0
  134. package/dist/src/memory/types.js +6 -0
  135. package/dist/src/memory/types.js.map +1 -0
  136. package/dist/src/memory/verify-migration.js +99 -0
  137. package/dist/src/memory/verify-migration.js.map +1 -0
  138. package/dist/src/pi-config.js +11 -9
  139. package/dist/src/pi-config.js.map +1 -1
  140. package/dist/src/skills/conditional-skills.js +464 -0
  141. package/dist/src/skills/conditional-skills.js.map +1 -0
  142. package/dist/src/skills/index.js +5 -0
  143. package/dist/src/skills/index.js.map +1 -1
  144. package/dist/src/skills/loader.js +56 -0
  145. package/dist/src/skills/loader.js.map +1 -1
  146. package/dist/src/skills/skill-manage.js +417 -0
  147. package/dist/src/skills/skill-manage.js.map +1 -0
  148. package/dist/src/tui/commands/orchestration-commands.js +62 -0
  149. package/dist/src/tui/commands/orchestration-commands.js.map +1 -1
  150. package/package.json +10 -5
  151. package/skills/model-router-test.ts +65 -0
  152. package/dist/src/extensions/core/auto-security-scan-extension.js +0 -41
  153. package/dist/src/extensions/core/auto-security-scan-extension.js.map +0 -1
  154. package/dist/src/extensions/core/cloudflare-browser-extension.js +0 -389
  155. package/dist/src/extensions/core/cloudflare-browser-extension.js.map +0 -1
  156. package/dist/src/extensions/core/compaction-safeguard.js +0 -223
  157. package/dist/src/extensions/core/compaction-safeguard.js.map +0 -1
  158. package/dist/src/extensions/core/generative-agents-extension.js.map +0 -1
  159. package/dist/src/extensions/core/obsidian-bridge-extension.js +0 -488
  160. package/dist/src/extensions/core/obsidian-bridge-extension.js.map +0 -1
  161. package/dist/src/llm/router.js +0 -145
  162. package/dist/src/llm/router.js.map +0 -1
  163. package/skills/kobold-scan-skill/node_modules/.package-lock.json +0 -172
  164. package/skills/kobold-scan-skill/node_modules/ansi-styles/index.d.ts +0 -345
  165. package/skills/kobold-scan-skill/node_modules/ansi-styles/index.js +0 -163
  166. package/skills/kobold-scan-skill/node_modules/ansi-styles/license +0 -9
  167. package/skills/kobold-scan-skill/node_modules/ansi-styles/package.json +0 -56
  168. package/skills/kobold-scan-skill/node_modules/ansi-styles/readme.md +0 -152
  169. package/skills/kobold-scan-skill/node_modules/balanced-match/.github/FUNDING.yml +0 -2
  170. package/skills/kobold-scan-skill/node_modules/balanced-match/LICENSE.md +0 -21
  171. package/skills/kobold-scan-skill/node_modules/balanced-match/README.md +0 -97
  172. package/skills/kobold-scan-skill/node_modules/balanced-match/index.js +0 -62
  173. package/skills/kobold-scan-skill/node_modules/balanced-match/package.json +0 -48
  174. package/skills/kobold-scan-skill/node_modules/brace-expansion/.github/FUNDING.yml +0 -2
  175. package/skills/kobold-scan-skill/node_modules/brace-expansion/LICENSE +0 -21
  176. package/skills/kobold-scan-skill/node_modules/brace-expansion/README.md +0 -135
  177. package/skills/kobold-scan-skill/node_modules/brace-expansion/index.js +0 -203
  178. package/skills/kobold-scan-skill/node_modules/brace-expansion/package.json +0 -49
  179. package/skills/kobold-scan-skill/node_modules/chalk/index.d.ts +0 -415
  180. package/skills/kobold-scan-skill/node_modules/chalk/license +0 -9
  181. package/skills/kobold-scan-skill/node_modules/chalk/package.json +0 -68
  182. package/skills/kobold-scan-skill/node_modules/chalk/readme.md +0 -341
  183. package/skills/kobold-scan-skill/node_modules/chalk/source/index.js +0 -229
  184. package/skills/kobold-scan-skill/node_modules/chalk/source/templates.js +0 -134
  185. package/skills/kobold-scan-skill/node_modules/chalk/source/util.js +0 -39
  186. package/skills/kobold-scan-skill/node_modules/color-convert/CHANGELOG.md +0 -54
  187. package/skills/kobold-scan-skill/node_modules/color-convert/LICENSE +0 -21
  188. package/skills/kobold-scan-skill/node_modules/color-convert/README.md +0 -68
  189. package/skills/kobold-scan-skill/node_modules/color-convert/conversions.js +0 -839
  190. package/skills/kobold-scan-skill/node_modules/color-convert/index.js +0 -81
  191. package/skills/kobold-scan-skill/node_modules/color-convert/package.json +0 -48
  192. package/skills/kobold-scan-skill/node_modules/color-convert/route.js +0 -97
  193. package/skills/kobold-scan-skill/node_modules/color-name/LICENSE +0 -8
  194. package/skills/kobold-scan-skill/node_modules/color-name/README.md +0 -11
  195. package/skills/kobold-scan-skill/node_modules/color-name/index.js +0 -152
  196. package/skills/kobold-scan-skill/node_modules/color-name/package.json +0 -28
  197. package/skills/kobold-scan-skill/node_modules/commander/LICENSE +0 -22
  198. package/skills/kobold-scan-skill/node_modules/commander/Readme.md +0 -1129
  199. package/skills/kobold-scan-skill/node_modules/commander/esm.mjs +0 -16
  200. package/skills/kobold-scan-skill/node_modules/commander/index.js +0 -27
  201. package/skills/kobold-scan-skill/node_modules/commander/lib/argument.js +0 -147
  202. package/skills/kobold-scan-skill/node_modules/commander/lib/command.js +0 -2179
  203. package/skills/kobold-scan-skill/node_modules/commander/lib/error.js +0 -45
  204. package/skills/kobold-scan-skill/node_modules/commander/lib/help.js +0 -461
  205. package/skills/kobold-scan-skill/node_modules/commander/lib/option.js +0 -326
  206. package/skills/kobold-scan-skill/node_modules/commander/lib/suggestSimilar.js +0 -100
  207. package/skills/kobold-scan-skill/node_modules/commander/package-support.json +0 -16
  208. package/skills/kobold-scan-skill/node_modules/commander/package.json +0 -80
  209. package/skills/kobold-scan-skill/node_modules/commander/typings/index.d.ts +0 -891
  210. package/skills/kobold-scan-skill/node_modules/fs.realpath/LICENSE +0 -43
  211. package/skills/kobold-scan-skill/node_modules/fs.realpath/README.md +0 -33
  212. package/skills/kobold-scan-skill/node_modules/fs.realpath/index.js +0 -66
  213. package/skills/kobold-scan-skill/node_modules/fs.realpath/old.js +0 -303
  214. package/skills/kobold-scan-skill/node_modules/fs.realpath/package.json +0 -26
  215. package/skills/kobold-scan-skill/node_modules/glob/LICENSE +0 -15
  216. package/skills/kobold-scan-skill/node_modules/glob/README.md +0 -399
  217. package/skills/kobold-scan-skill/node_modules/glob/common.js +0 -244
  218. package/skills/kobold-scan-skill/node_modules/glob/glob.js +0 -790
  219. package/skills/kobold-scan-skill/node_modules/glob/package.json +0 -55
  220. package/skills/kobold-scan-skill/node_modules/glob/sync.js +0 -486
  221. package/skills/kobold-scan-skill/node_modules/has-flag/index.d.ts +0 -39
  222. package/skills/kobold-scan-skill/node_modules/has-flag/index.js +0 -8
  223. package/skills/kobold-scan-skill/node_modules/has-flag/license +0 -9
  224. package/skills/kobold-scan-skill/node_modules/has-flag/package.json +0 -46
  225. package/skills/kobold-scan-skill/node_modules/has-flag/readme.md +0 -89
  226. package/skills/kobold-scan-skill/node_modules/inflight/LICENSE +0 -15
  227. package/skills/kobold-scan-skill/node_modules/inflight/README.md +0 -37
  228. package/skills/kobold-scan-skill/node_modules/inflight/inflight.js +0 -54
  229. package/skills/kobold-scan-skill/node_modules/inflight/package.json +0 -29
  230. package/skills/kobold-scan-skill/node_modules/inherits/LICENSE +0 -16
  231. package/skills/kobold-scan-skill/node_modules/inherits/README.md +0 -42
  232. package/skills/kobold-scan-skill/node_modules/inherits/inherits.js +0 -9
  233. package/skills/kobold-scan-skill/node_modules/inherits/inherits_browser.js +0 -27
  234. package/skills/kobold-scan-skill/node_modules/inherits/package.json +0 -29
  235. package/skills/kobold-scan-skill/node_modules/minimatch/LICENSE +0 -15
  236. package/skills/kobold-scan-skill/node_modules/minimatch/README.md +0 -259
  237. package/skills/kobold-scan-skill/node_modules/minimatch/lib/path.js +0 -4
  238. package/skills/kobold-scan-skill/node_modules/minimatch/minimatch.js +0 -944
  239. package/skills/kobold-scan-skill/node_modules/minimatch/package.json +0 -35
  240. package/skills/kobold-scan-skill/node_modules/once/LICENSE +0 -15
  241. package/skills/kobold-scan-skill/node_modules/once/README.md +0 -79
  242. package/skills/kobold-scan-skill/node_modules/once/once.js +0 -42
  243. package/skills/kobold-scan-skill/node_modules/once/package.json +0 -33
  244. package/skills/kobold-scan-skill/node_modules/supports-color/browser.js +0 -5
  245. package/skills/kobold-scan-skill/node_modules/supports-color/index.js +0 -135
  246. package/skills/kobold-scan-skill/node_modules/supports-color/license +0 -9
  247. package/skills/kobold-scan-skill/node_modules/supports-color/package.json +0 -53
  248. package/skills/kobold-scan-skill/node_modules/supports-color/readme.md +0 -76
  249. package/skills/kobold-scan-skill/node_modules/wrappy/LICENSE +0 -15
  250. package/skills/kobold-scan-skill/node_modules/wrappy/README.md +0 -36
  251. package/skills/kobold-scan-skill/node_modules/wrappy/package.json +0 -29
  252. package/skills/kobold-scan-skill/node_modules/wrappy/wrappy.js +0 -33
@@ -1,41 +0,0 @@
1
- /**
2
- * Auto Security Scan Extension
3
- *
4
- * Automatically scans files for vulnerabilities when they're written.
5
- * Provides security feedback without blocking the agent.
6
- */
7
- import { eventBus } from "../../event-bus";
8
- import { execSync } from 'child_process';
9
- const KOBOLD_SCAN_PATH = '/home/moika/Documents/code/0xKobolds/skills/kobold-scan-skill';
10
- export function initAutoSecurityScan() {
11
- console.log('[AutoScan] Initializing automatic security scanning...');
12
- // Listen for file write events
13
- eventBus.on('file.written', async (event) => {
14
- const filePath = event.payload?.path;
15
- if (!filePath)
16
- return;
17
- // Only scan JS/TS/Solidity files
18
- if (!/\.(js|ts|sol|jsx|tsx)$/.test(filePath))
19
- return;
20
- console.log(`[AutoScan] Scanning ${filePath}...`);
21
- try {
22
- const cmd = `cd ${KOBOLD_SCAN_PATH} && node index.js scan "${filePath}" --severity medium --format json`;
23
- const result = execSync(cmd, { encoding: 'utf-8', timeout: 30000 });
24
- const parsed = JSON.parse(result);
25
- if (parsed.vulnerabilities?.length > 0) {
26
- // Emit security warning event
27
- eventBus.emit('security.issues_found', {
28
- file: filePath,
29
- issues: parsed.vulnerabilities,
30
- summary: `${parsed.vulnerabilities.length} security issues found`
31
- });
32
- console.log(`[AutoScan] āš ļø Found ${parsed.vulnerabilities.length} issues in ${filePath}`);
33
- }
34
- }
35
- catch (err) {
36
- // Ignore scan errors (file might not exist yet)
37
- }
38
- });
39
- console.log('[AutoScan] Active - scanning JS/TS/SOL files on write');
40
- }
41
- //# sourceMappingURL=auto-security-scan-extension.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auto-security-scan-extension.js","sourceRoot":"","sources":["../../../../src/extensions/core/auto-security-scan-extension.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAIzC,MAAM,gBAAgB,GAAG,+DAA+D,CAAC;AAEzF,MAAM,UAAU,oBAAoB;IAClC,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;IAEtE,+BAA+B;IAC/B,QAAQ,CAAC,EAAE,CAAC,cAAc,EAAE,KAAK,EAAE,KAAU,EAAE,EAAE;QAC/C,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;QACrC,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,iCAAiC;QACjC,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,QAAQ,CAAC;YAAE,OAAO;QAErD,OAAO,CAAC,GAAG,CAAC,uBAAuB,QAAQ,KAAK,CAAC,CAAC;QAElD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,gBAAgB,2BAA2B,QAAQ,mCAAmC,CAAC;YACzG,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YACpE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAElC,IAAI,MAAM,CAAC,eAAe,EAAE,MAAM,GAAG,CAAC,EAAE,CAAC;gBACvC,8BAA8B;gBAC9B,QAAQ,CAAC,IAAI,CAAC,uBAAuB,EAAE;oBACrC,IAAI,EAAE,QAAQ;oBACd,MAAM,EAAE,MAAM,CAAC,eAAe;oBAC9B,OAAO,EAAE,GAAG,MAAM,CAAC,eAAe,CAAC,MAAM,wBAAwB;iBAClE,CAAC,CAAC;gBAEH,OAAO,CAAC,GAAG,CAAC,uBAAuB,MAAM,CAAC,eAAe,CAAC,MAAM,cAAc,QAAQ,EAAE,CAAC,CAAC;YAC5F,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,gDAAgD;QAClD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;AACvE,CAAC"}
@@ -1,389 +0,0 @@
1
- /**
2
- * Cloudflare Browser Rendering Extension for 0xKobold
3
- *
4
- * Provides browser rendering capabilities via Cloudflare Browser Rendering API
5
- * Opt-in: Only loads if CLOUDFLARE_API_TOKEN exists in ~/.0xkobold/.env
6
- *
7
- * Endpoints:
8
- * - /crawl - Crawl web content (multi-page)
9
- * - /content - Fetch HTML from single URL
10
- * - /screenshot - Capture screenshot
11
- * - /pdf - Generate PDF
12
- * - /markdown - Extract markdown
13
- * - /json - Extract structured data with AI
14
- *
15
- * Requirements:
16
- * - CLOUDFLARE_API_TOKEN with "Browser Rendering - Edit" permission
17
- * - CLOUDFLARE_ACCOUNT_ID from Cloudflare dashboard
18
- */
19
- import { Type } from "@sinclair/typebox";
20
- import { homedir } from "os";
21
- import { join } from "path";
22
- async function loadConfig() {
23
- // Try environment first, then fallback to ~/.0xkobold/.env
24
- let apiToken = process.env.CLOUDFLARE_API_TOKEN || null;
25
- let accountId = process.env.CLOUDFLARE_ACCOUNT_ID || null;
26
- // If not in env, try to load from ~/.0xkobold/.env
27
- if (!apiToken || !accountId) {
28
- try {
29
- const envPath = join(homedir(), ".0xkobold", ".env");
30
- const envFile = Bun.file(envPath);
31
- if (await envFile.exists()) {
32
- const content = await envFile.text();
33
- const lines = content.split('\n');
34
- for (const line of lines) {
35
- const trimmed = line.trim();
36
- if (trimmed.startsWith('CLOUDFLARE_API_TOKEN=')) {
37
- apiToken = trimmed.slice('CLOUDFLARE_API_TOKEN='.length).replace(/^["']|["']$/g, '');
38
- }
39
- if (trimmed.startsWith('CLOUDFLARE_ACCOUNT_ID=')) {
40
- accountId = trimmed.slice('CLOUDFLARE_ACCOUNT_ID='.length).replace(/^["']|["']$/g, '');
41
- }
42
- }
43
- }
44
- }
45
- catch {
46
- // .env may not exist, that's ok
47
- }
48
- }
49
- return {
50
- apiToken,
51
- accountId,
52
- enabled: !!(apiToken && accountId)
53
- };
54
- }
55
- // ============================================================================
56
- // API CLIENT
57
- // ============================================================================
58
- class CloudflareClient {
59
- config;
60
- baseUrl;
61
- constructor(config) {
62
- this.config = config;
63
- this.baseUrl = `https://api.cloudflare.com/client/v4/accounts/${config.accountId}/browser-rendering`;
64
- }
65
- async request(endpoint, options) {
66
- const url = `${this.baseUrl}${endpoint}`;
67
- const response = await fetch(url, {
68
- ...options,
69
- headers: {
70
- 'Authorization': `Bearer ${this.config.apiToken}`,
71
- 'Content-Type': 'application/json',
72
- ...options.headers
73
- }
74
- });
75
- if (!response.ok) {
76
- const errorText = await response.text();
77
- throw new Error(`Cloudflare API error ${response.status}: ${errorText.slice(0, 200)}`);
78
- }
79
- const data = await response.json();
80
- if (!data.success) {
81
- throw new Error(`Cloudflare API failed: ${JSON.stringify(data.errors)}`);
82
- }
83
- return data.result;
84
- }
85
- /**
86
- * Crawl web content (async job)
87
- * Returns job ID immediately, use getCrawlResult to poll
88
- */
89
- async crawl(params) {
90
- const result = await this.request('/crawl', {
91
- method: 'POST',
92
- body: JSON.stringify(params)
93
- });
94
- return result.id;
95
- }
96
- /**
97
- * Get crawl job results
98
- */
99
- async getCrawlResult(jobId, limit) {
100
- const query = limit ? `?limit=${limit}` : '';
101
- return this.request(`/crawl/${jobId}${query}`, { method: 'GET' });
102
- }
103
- /**
104
- * Cancel running crawl job
105
- */
106
- async cancelCrawl(jobId) {
107
- await this.request(`/crawl/${jobId}`, { method: 'DELETE' });
108
- }
109
- /**
110
- * Fetch single page content
111
- */
112
- async fetchContent(url, options) {
113
- return this.request('/content', {
114
- method: 'POST',
115
- body: JSON.stringify({ url, ...options })
116
- });
117
- }
118
- /**
119
- * Take screenshot
120
- */
121
- async screenshot(url, options) {
122
- return this.request('/screenshot', {
123
- method: 'POST',
124
- body: JSON.stringify({ url, ...options })
125
- });
126
- }
127
- /**
128
- * Generate PDF
129
- */
130
- async pdf(url, options) {
131
- return this.request('/pdf', {
132
- method: 'POST',
133
- body: JSON.stringify({ url, ...options })
134
- });
135
- }
136
- }
137
- // ============================================================================
138
- // POLLING HELPER
139
- // ============================================================================
140
- async function pollCrawlJob(client, jobId, onUpdate) {
141
- const maxAttempts = 180;
142
- const delayMs = 5000;
143
- for (let i = 0; i < maxAttempts; i++) {
144
- const result = await client.getCrawlResult(jobId, 1);
145
- onUpdate?.(result.status, result.finished / result.total * 100 || 0);
146
- if (result.status !== 'running') {
147
- return client.getCrawlResult(jobId);
148
- }
149
- await new Promise(resolve => setTimeout(resolve, delayMs));
150
- }
151
- throw new Error('Crawl job did not complete within 15 minute timeout');
152
- }
153
- // ============================================================================
154
- // SAVES TO OBSIDIAN
155
- // ============================================================================
156
- async function saveToObsidian(type, data, sourceUrl, title) {
157
- const vaultPath = join(homedir(), '.0xkobold', 'obsidian_vault', 'Research');
158
- const dateStr = new Date().toISOString().split('T')[0];
159
- const safeTitle = (title || 'Untitled').replace(/[^a-zA-Z0-9]/g, '_').slice(0, 50);
160
- if (type === 'screenshot' || type === 'pdf') {
161
- const ext = type === 'screenshot' ? 'png' : 'pdf';
162
- const base64 = data[type === 'screenshot' ? 'screenshot' : 'pdf'];
163
- const filename = `${dateStr}_${safeTitle}.${ext}`;
164
- const filepath = join(vaultPath, filename);
165
- await Bun.write(filepath, Buffer.from(base64, 'base64'));
166
- return filepath;
167
- }
168
- else if (type === 'crawl') {
169
- const result = data;
170
- const filename = `${dateStr}_${safeTitle}_crawl.md`;
171
- const filepath = join(vaultPath, filename);
172
- let content = `# Crawled: ${title || sourceUrl}\n\n`;
173
- content += `**Source:** ${sourceUrl}\n`;
174
- content += `**Date:** ${dateStr}\n`;
175
- content += `**Pages:** ${result.finished}/${result.total}\n`;
176
- content += `**Status:** ${result.status}\n\n`;
177
- content += `---\n\n`;
178
- for (const record of result.records.slice(0, 50)) {
179
- if (record.markdown || record.html) {
180
- content += `## ${record.metadata.title}\n`;
181
- content += `**URL:** ${record.url}\n`;
182
- content += `**Status:** ${record.status} (${record.metadata.status})\n\n`;
183
- content += record.markdown || record.html?.slice(0, 5000) || '(no content)';
184
- content += `\n\n---\n\n`;
185
- }
186
- }
187
- await Bun.write(filepath, content);
188
- return filepath;
189
- }
190
- else {
191
- const result = data;
192
- const filename = `${dateStr}_${safeTitle}.md`;
193
- const filepath = join(vaultPath, filename);
194
- const content = `# ${result.metadata.title}\n\n**Source:** ${result.metadata.url}\n\n---\n\n${result.html}`;
195
- await Bun.write(filepath, content);
196
- return filepath;
197
- }
198
- }
199
- // ============================================================================
200
- // MAIN EXTENSION
201
- // ============================================================================
202
- export default async function cloudflareBrowserExtension(pi) {
203
- const config = await loadConfig();
204
- if (!config.enabled) {
205
- console.log('[CloudflareBrowser] Skipped - no CLOUDFLARE_API_TOKEN/CLOUDFLARE_ACCOUNT_ID');
206
- return;
207
- }
208
- const client = new CloudflareClient(config);
209
- console.log('[CloudflareBrowser] Extension loaded');
210
- console.log('[CloudflareBrowser] Account:', config.accountId?.slice(0, 8) + '...');
211
- // ========================================================================
212
- // TOOL: cloudflare_crawl - Crawl multiple pages
213
- // ========================================================================
214
- pi.registerTool({
215
- name: "cloudflare_crawl",
216
- label: "/cf_crawl",
217
- description: "Crawl website with Cloudflare Browser Rendering (multi-page)",
218
- parameters: Type.Object({
219
- url: Type.String({ description: "Starting URL to crawl" }),
220
- limit: Type.Number({ default: 10, description: "Max pages to crawl" }),
221
- depth: Type.Optional(Type.Number({ description: "Max link depth" })),
222
- formats: Type.Optional(Type.Array(Type.String({
223
- enum: ["html", "markdown", "json"]
224
- }))),
225
- render: Type.Boolean({ default: true, description: "Execute JavaScript" }),
226
- saveToObsidian: Type.Boolean({ default: true, description: "Save results" })
227
- }),
228
- async execute(_toolCallId, params, _signal, onUpdate, _ctx) {
229
- try {
230
- onUpdate?.({ content: [{ type: "text", text: `šŸ•øļø Starting crawl of ${params.url}...` }] });
231
- const jobId = await client.crawl({
232
- url: params.url,
233
- limit: params.limit || 10,
234
- depth: params.depth,
235
- formats: params.formats || ['markdown'],
236
- render: params.render ?? true
237
- });
238
- onUpdate?.({ content: [{ type: "text", text: `šŸ“‹ Crawl job: ${jobId}` }] });
239
- const result = await pollCrawlJob(client, jobId, (status, progress) => {
240
- onUpdate?.({ content: [{ type: "text", text: `${status} (${progress.toFixed(0)}%)` }] });
241
- });
242
- let savedPath;
243
- if (params.saveToObsidian !== false) {
244
- const firstRecord = result.records[0];
245
- savedPath = await saveToObsidian('crawl', result, params.url, firstRecord?.metadata?.title);
246
- }
247
- const completedPages = result.records.filter(r => r.status === 'completed').length;
248
- const summary = `āœ… Crawl ${result.status}\nšŸ“Š Pages: ${completedPages}/${result.total}\nā±ļø Browser: ${result.browserSecondsUsed.toFixed(1)}s` +
249
- (savedPath ? `\nšŸ’¾ Saved: ${savedPath.split('/').pop()}` : '');
250
- return {
251
- content: [{ type: "text", text: summary }],
252
- details: { jobId, status: result.status, total: result.total, savedPath }
253
- };
254
- }
255
- catch (error) {
256
- return {
257
- content: [{ type: "text", text: `āŒ ${error instanceof Error ? error.message : String(error)}` }],
258
- details: { error: String(error) }
259
- };
260
- }
261
- }
262
- });
263
- // ========================================================================
264
- // TOOL: cloudflare_screenshot
265
- // ========================================================================
266
- pi.registerTool({
267
- name: "cloudflare_screenshot",
268
- label: "/cf_screenshot",
269
- description: "Take screenshot with Cloudflare Browser Rendering (inline + saved)",
270
- parameters: Type.Object({
271
- url: Type.String({ description: "URL to screenshot" }),
272
- fullPage: Type.Boolean({ default: false, description: "Full page vs viewport" }),
273
- saveToObsidian: Type.Boolean({ default: true, description: "Save PNG to vault" })
274
- }),
275
- async execute(_toolCallId, params) {
276
- try {
277
- const result = await client.screenshot(params.url, { fullPage: params.fullPage });
278
- let savedPath;
279
- if (params.saveToObsidian !== false) {
280
- savedPath = await saveToObsidian('screenshot', result, params.url, result.metadata.title);
281
- }
282
- return {
283
- content: [
284
- { type: "text", text: `šŸ“ø Screenshot: ${result.metadata.title}\n🌐 ${result.metadata.url}` },
285
- // Inline image for immediate viewing
286
- { type: "image", data: result.screenshot, mimeType: "image/png" },
287
- ...(savedPath ? [{ type: "text", text: `šŸ’¾ Saved to: ${savedPath}` }] : [])
288
- ],
289
- details: {
290
- title: result.metadata.title,
291
- url: result.metadata.url,
292
- savedPath,
293
- imageSize: result.screenshot.length
294
- }
295
- };
296
- }
297
- catch (error) {
298
- return {
299
- content: [{ type: "text", text: `āŒ ${error instanceof Error ? error.message : String(error)}` }],
300
- details: { error: String(error) }
301
- };
302
- }
303
- }
304
- });
305
- // ========================================================================
306
- // TOOL: cloudflare_pdf
307
- // ========================================================================
308
- pi.registerTool({
309
- name: "cloudflare_pdf",
310
- label: "/cf_pdf",
311
- description: "Generate PDF from URL and save to Obsidian vault",
312
- parameters: Type.Object({
313
- url: Type.String({ description: "URL to convert to PDF" }),
314
- fullPage: Type.Boolean({ default: true, description: "Include full page" }),
315
- saveToObsidian: Type.Boolean({ default: true, description: "Save PDF to vault" })
316
- }),
317
- async execute(_toolCallId, params) {
318
- try {
319
- const result = await client.pdf(params.url, { fullPage: params.fullPage });
320
- let savedPath;
321
- if (params.saveToObsidian !== false) {
322
- savedPath = await saveToObsidian('pdf', result, params.url, result.metadata.title);
323
- }
324
- return {
325
- content: [
326
- { type: "text", text: `šŸ“„ PDF Generated: ${result.metadata.title}` },
327
- { type: "text", text: `🌐 Source: ${result.metadata.url}` },
328
- ...(savedPath ? [
329
- { type: "text", text: `šŸ’¾ Saved to: ${savedPath}` },
330
- { type: "text", text: `šŸ“ Tip: Use file viewer to open the PDF` }
331
- ] : [])
332
- ],
333
- details: {
334
- title: result.metadata.title,
335
- url: result.metadata.url,
336
- savedPath,
337
- pdfSize: result.pdf.length
338
- }
339
- };
340
- }
341
- catch (error) {
342
- return {
343
- content: [{ type: "text", text: `āŒ ${error instanceof Error ? error.message : String(error)}` }],
344
- details: { error: String(error) }
345
- };
346
- }
347
- }
348
- });
349
- // ========================================================================
350
- // TOOL: cloudflare_content (single page)
351
- // ========================================================================
352
- pi.registerTool({
353
- name: "cloudflare_content",
354
- label: "/cf_fetch",
355
- description: "Fetch rendered HTML with Cloudflare Browser Rendering",
356
- parameters: Type.Object({
357
- url: Type.String({ description: "URL to fetch" }),
358
- waitFor: Type.Optional(Type.Union([Type.String(), Type.Number()], { description: "Wait for selector or ms" })),
359
- saveToObsidian: Type.Boolean({ default: true, description: "Save to Obsidian" })
360
- }),
361
- async execute(_toolCallId, params) {
362
- try {
363
- const result = await client.fetchContent(params.url, { waitFor: params.waitFor });
364
- let savedPath;
365
- if (params.saveToObsidian !== false) {
366
- savedPath = await saveToObsidian('content', result, params.url, result.metadata.title);
367
- }
368
- return {
369
- content: [
370
- {
371
- type: "text",
372
- text: `šŸ“„ ${result.metadata.title}\nStatus: ${result.metadata.status}\n\n${result.html.slice(0, 3000)}${result.html.length > 3000 ? '...' : ''}`
373
- }
374
- ],
375
- details: { metadata: result.metadata, savedPath }
376
- };
377
- }
378
- catch (error) {
379
- return {
380
- content: [{ type: "text", text: `āŒ ${error instanceof Error ? error.message : String(error)}` }],
381
- details: { error: String(error) }
382
- };
383
- }
384
- }
385
- });
386
- console.log('[CloudflareBrowser] Tools registered: cloudflare_crawl, cloudflare_screenshot, cloudflare_pdf, cloudflare_content');
387
- }
388
- export { CloudflareClient, loadConfig };
389
- //# sourceMappingURL=cloudflare-browser-extension.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"cloudflare-browser-extension.js","sourceRoot":"","sources":["../../../../src/extensions/core/cloudflare-browser-extension.ts"],"names":[],"mappings":"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"}