@tyvm/knowhow 0.0.90 → 0.0.91

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 (262) hide show
  1. package/.depcheckrc +31 -0
  2. package/bin/knowhow.js +1 -1
  3. package/package.json +4 -32
  4. package/src/agents/tools/executeScript/index.ts +5 -0
  5. package/src/agents/tools/googleSearch.ts +2 -2
  6. package/src/agents/tools/index.ts +0 -3
  7. package/src/agents/tools/list.ts +0 -147
  8. package/src/agents/tools/loadWebpage.ts +3 -113
  9. package/src/auth/browserLogin.ts +10 -13
  10. package/src/cli.ts +63 -3
  11. package/src/clients/gemini.ts +96 -25
  12. package/src/clients/http.ts +7 -11
  13. package/src/clients/pricing/google.ts +122 -26
  14. package/src/conversion.ts +24 -54
  15. package/src/index.ts +8 -1
  16. package/src/login.ts +5 -6
  17. package/src/plugins/language.ts +0 -4
  18. package/src/plugins/plugins.ts +0 -14
  19. package/src/plugins/url.ts +31 -12
  20. package/src/services/GitHub.ts +2 -2
  21. package/src/services/KnowhowClient.ts +34 -34
  22. package/src/{plugins/downloader/downloader.ts → services/MediaProcessorService.ts} +109 -267
  23. package/src/services/S3.ts +16 -16
  24. package/src/services/index.ts +4 -4
  25. package/src/services/modules/index.ts +10 -2
  26. package/src/services/modules/types.ts +5 -2
  27. package/src/services/script-execution/ScriptExecutor.ts +29 -10
  28. package/src/services/script-execution/ScriptPolicy.ts +6 -2
  29. package/src/types.ts +1 -0
  30. package/src/utils/http.ts +127 -0
  31. package/src/workers/auth/PasskeySetup.ts +7 -11
  32. package/tests/clients/AIClient.test.ts +24 -21
  33. package/tests/manual/file-edits/figma.test.ts +3 -70
  34. package/tests/plugins/language/languagePlugin-content-triggers.test.ts +2 -0
  35. package/tests/plugins/language/languagePlugin.test.ts +2 -0
  36. package/tests/processors/ToolResponseCache.test.ts +2 -2
  37. package/tests/test.spec.ts +0 -14
  38. package/tests/unit/modules/moduleLoading.test.ts +7 -4
  39. package/tests/unit/plugins/pluginLoading.test.ts +6 -6
  40. package/ts_build/package.json +4 -32
  41. package/ts_build/src/agents/tools/ast/astAppendNode.d.ts +1 -1
  42. package/ts_build/src/agents/tools/ast/astAppendNode.js +2 -90
  43. package/ts_build/src/agents/tools/ast/astAppendNode.js.map +1 -1
  44. package/ts_build/src/agents/tools/ast/astDeleteNode.d.ts +1 -1
  45. package/ts_build/src/agents/tools/ast/astDeleteNode.js +2 -88
  46. package/ts_build/src/agents/tools/ast/astDeleteNode.js.map +1 -1
  47. package/ts_build/src/agents/tools/ast/astEditNode.d.ts +1 -1
  48. package/ts_build/src/agents/tools/ast/astEditNode.js +2 -90
  49. package/ts_build/src/agents/tools/ast/astEditNode.js.map +1 -1
  50. package/ts_build/src/agents/tools/ast/astGetPathForLine.d.ts +1 -1
  51. package/ts_build/src/agents/tools/ast/astGetPathForLine.js +2 -72
  52. package/ts_build/src/agents/tools/ast/astGetPathForLine.js.map +1 -1
  53. package/ts_build/src/agents/tools/ast/astListPaths.d.ts +1 -1
  54. package/ts_build/src/agents/tools/ast/astListPaths.js +2 -72
  55. package/ts_build/src/agents/tools/ast/astListPaths.js.map +1 -1
  56. package/ts_build/src/agents/tools/executeScript/index.d.ts +3 -2
  57. package/ts_build/src/agents/tools/executeScript/index.js +4 -1
  58. package/ts_build/src/agents/tools/executeScript/index.js.map +1 -1
  59. package/ts_build/src/agents/tools/googleSearch.js +2 -2
  60. package/ts_build/src/agents/tools/googleSearch.js.map +1 -1
  61. package/ts_build/src/agents/tools/index.d.ts +0 -3
  62. package/ts_build/src/agents/tools/index.js +0 -3
  63. package/ts_build/src/agents/tools/index.js.map +1 -1
  64. package/ts_build/src/agents/tools/list.js +0 -138
  65. package/ts_build/src/agents/tools/list.js.map +1 -1
  66. package/ts_build/src/agents/tools/loadWebpage.js +1 -89
  67. package/ts_build/src/agents/tools/loadWebpage.js.map +1 -1
  68. package/ts_build/src/agents/tools/textSearch.d.ts +1 -1
  69. package/ts_build/src/auth/browserLogin.js +7 -7
  70. package/ts_build/src/auth/browserLogin.js.map +1 -1
  71. package/ts_build/src/cli.d.ts +1 -1
  72. package/ts_build/src/cli.js +47 -1
  73. package/ts_build/src/cli.js.map +1 -1
  74. package/ts_build/src/clients/gemini.d.ts +1 -73
  75. package/ts_build/src/clients/gemini.js +57 -19
  76. package/ts_build/src/clients/gemini.js.map +1 -1
  77. package/ts_build/src/clients/http.js +5 -9
  78. package/ts_build/src/clients/http.js.map +1 -1
  79. package/ts_build/src/clients/pricing/google.d.ts +17 -73
  80. package/ts_build/src/clients/pricing/google.js +47 -10
  81. package/ts_build/src/clients/pricing/google.js.map +1 -1
  82. package/ts_build/src/conversion.d.ts +1 -4
  83. package/ts_build/src/conversion.js +12 -27
  84. package/ts_build/src/conversion.js.map +1 -1
  85. package/ts_build/src/index.d.ts +4 -0
  86. package/ts_build/src/index.js +7 -1
  87. package/ts_build/src/index.js.map +1 -1
  88. package/ts_build/src/login.js +5 -4
  89. package/ts_build/src/login.js.map +1 -1
  90. package/ts_build/src/plugins/downloader/downloader.js +3 -3
  91. package/ts_build/src/plugins/downloader/downloader.js.map +1 -1
  92. package/ts_build/src/plugins/language.js.map +1 -1
  93. package/ts_build/src/plugins/plugins.js +0 -14
  94. package/ts_build/src/plugins/plugins.js.map +1 -1
  95. package/ts_build/src/plugins/tree-sitter/editor.d.ts +3 -32
  96. package/ts_build/src/plugins/tree-sitter/editor.js +6 -208
  97. package/ts_build/src/plugins/tree-sitter/editor.js.map +1 -1
  98. package/ts_build/src/plugins/tree-sitter/parser.d.ts +19 -54
  99. package/ts_build/src/plugins/tree-sitter/parser.js +19 -293
  100. package/ts_build/src/plugins/tree-sitter/parser.js.map +1 -1
  101. package/ts_build/src/plugins/tree-sitter/simple-paths.d.ts +2 -15
  102. package/ts_build/src/plugins/tree-sitter/simple-paths.js +2 -324
  103. package/ts_build/src/plugins/tree-sitter/simple-paths.js.map +1 -1
  104. package/ts_build/src/plugins/url.js +27 -8
  105. package/ts_build/src/plugins/url.js.map +1 -1
  106. package/ts_build/src/services/GitHub.js +2 -2
  107. package/ts_build/src/services/GitHub.js.map +1 -1
  108. package/ts_build/src/services/KnowhowClient.d.ts +29 -29
  109. package/ts_build/src/services/KnowhowClient.js +33 -33
  110. package/ts_build/src/services/KnowhowClient.js.map +1 -1
  111. package/ts_build/src/services/MediaProcessorService.d.ts +22 -0
  112. package/ts_build/src/services/MediaProcessorService.js +215 -0
  113. package/ts_build/src/services/MediaProcessorService.js.map +1 -0
  114. package/ts_build/src/services/S3.js +12 -18
  115. package/ts_build/src/services/S3.js.map +1 -1
  116. package/ts_build/src/services/index.d.ts +3 -2
  117. package/ts_build/src/services/index.js +3 -3
  118. package/ts_build/src/services/index.js.map +1 -1
  119. package/ts_build/src/services/modules/index.js +10 -2
  120. package/ts_build/src/services/modules/index.js.map +1 -1
  121. package/ts_build/src/services/modules/types.d.ts +5 -2
  122. package/ts_build/src/services/script-execution/ScriptExecutor.js +22 -7
  123. package/ts_build/src/services/script-execution/ScriptExecutor.js.map +1 -1
  124. package/ts_build/src/services/script-execution/ScriptPolicy.d.ts +1 -1
  125. package/ts_build/src/services/script-execution/ScriptPolicy.js +4 -2
  126. package/ts_build/src/services/script-execution/ScriptPolicy.js.map +1 -1
  127. package/ts_build/src/types.d.ts +1 -0
  128. package/ts_build/src/types.js +1 -0
  129. package/ts_build/src/types.js.map +1 -1
  130. package/ts_build/src/utils/http.d.ts +27 -0
  131. package/ts_build/src/utils/http.js +98 -0
  132. package/ts_build/src/utils/http.js.map +1 -0
  133. package/ts_build/src/workers/auth/PasskeySetup.js +6 -7
  134. package/ts_build/src/workers/auth/PasskeySetup.js.map +1 -1
  135. package/ts_build/tests/clients/AIClient.test.js +11 -14
  136. package/ts_build/tests/clients/AIClient.test.js.map +1 -1
  137. package/ts_build/tests/manual/file-edits/figma.test.d.ts +0 -1
  138. package/ts_build/tests/manual/file-edits/figma.test.js +1 -46
  139. package/ts_build/tests/manual/file-edits/figma.test.js.map +1 -1
  140. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js +2 -0
  141. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js.map +1 -1
  142. package/ts_build/tests/plugins/language/languagePlugin.test.js +2 -0
  143. package/ts_build/tests/plugins/language/languagePlugin.test.js.map +1 -1
  144. package/ts_build/tests/processors/ToolResponseCache.test.js +2 -2
  145. package/ts_build/tests/processors/ToolResponseCache.test.js.map +1 -1
  146. package/ts_build/tests/test.spec.js +0 -14
  147. package/ts_build/tests/test.spec.js.map +1 -1
  148. package/ts_build/tests/tree-sitter/tree-sitter.test.d.ts +0 -1
  149. package/ts_build/tests/tree-sitter/tree-sitter.test.js +2 -183
  150. package/ts_build/tests/tree-sitter/tree-sitter.test.js.map +1 -1
  151. package/ts_build/tests/unit/modules/moduleLoading.test.js +6 -4
  152. package/ts_build/tests/unit/modules/moduleLoading.test.js.map +1 -1
  153. package/ts_build/tests/unit/plugins/pluginLoading.test.js +4 -4
  154. package/ts_build/tests/unit/plugins/pluginLoading.test.js.map +1 -1
  155. package/benchmarks/.dockerignore +0 -7
  156. package/benchmarks/README.md +0 -166
  157. package/benchmarks/docker/Dockerfile +0 -68
  158. package/benchmarks/example-config.yml +0 -27
  159. package/benchmarks/jest.config.js +0 -13
  160. package/benchmarks/package-lock.json +0 -4297
  161. package/benchmarks/package.json +0 -39
  162. package/benchmarks/results/27b0a06/2025-09-27/xai/xai-grok-code-fast-1.json +0 -2909
  163. package/benchmarks/results/4057aed/2025-08-14/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -1671
  164. package/benchmarks/results/4542435/2025-08-05/lms/lms-openai-gpt-oss-20b.json +0 -2814
  165. package/benchmarks/results/4542435/2025-08-05/lms/lms-qwen-qwen3-30b-a3b-2507.json +0 -2014
  166. package/benchmarks/results/4fb9125/2025-08-07/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -3121
  167. package/benchmarks/results/5766aee/2025-08-02/lms-qwen/qwen3-coder-30b.json +0 -98
  168. package/benchmarks/results/6d73808/2025-08-07/openai/openai-gpt-5.json +0 -3256
  169. package/benchmarks/results/77bf0a6/2025-08-02/lms-qwen/qwen3-30b-a3b-2507.json +0 -4298
  170. package/benchmarks/results/8c0d445/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -3031
  171. package/benchmarks/results/8c0d445/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +0 -2990
  172. package/benchmarks/results/ac6b2ab/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -3256
  173. package/benchmarks/results/ac6b2ab/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +0 -3007
  174. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +0 -3256
  175. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-mini-2025-04-14.json +0 -3036
  176. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-nano-2025-04-14.json +0 -3280
  177. package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-30b-a3b-2507.json +0 -1920
  178. package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-coder-30b.json +0 -3281
  179. package/benchmarks/results/b502ed9/2025-08-03/lms-qwen/qwen3-coder-30b.json +0 -2896
  180. package/benchmarks/results/d1a8129/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +0 -3011
  181. package/benchmarks/results/e60471c/2025-08-03/lms/qwen3-30b-a3b-2507.json +0 -3003
  182. package/benchmarks/scripts/build-and-run.sh +0 -47
  183. package/benchmarks/scripts/clone-exercism.sh +0 -92
  184. package/benchmarks/scripts/validate.sh +0 -48
  185. package/benchmarks/src/__tests__/runner.test.ts +0 -27
  186. package/benchmarks/src/cli.ts +0 -90
  187. package/benchmarks/src/evaluators/EvaluatorRegistry.ts +0 -64
  188. package/benchmarks/src/evaluators/JavaScriptEvaluator.ts +0 -183
  189. package/benchmarks/src/evaluators/index.ts +0 -3
  190. package/benchmarks/src/evaluators/types.ts +0 -22
  191. package/benchmarks/src/index.ts +0 -3
  192. package/benchmarks/src/providers.ts +0 -13
  193. package/benchmarks/src/runner.ts +0 -824
  194. package/benchmarks/src/types.ts +0 -63
  195. package/benchmarks/tsconfig.json +0 -19
  196. package/leaderboard/README.md +0 -148
  197. package/leaderboard/app/api/benchmark-data/route.ts +0 -131
  198. package/leaderboard/app/api/benchmark-detail/route.ts +0 -172
  199. package/leaderboard/app/details/[model]/[provider]/[language]/page.tsx +0 -501
  200. package/leaderboard/app/exercise/[model]/[provider]/[language]/[exercise]/page.tsx +0 -375
  201. package/leaderboard/app/globals.css +0 -27
  202. package/leaderboard/app/layout.tsx +0 -21
  203. package/leaderboard/app/page.tsx +0 -170
  204. package/leaderboard/components/LeaderboardTable.tsx +0 -168
  205. package/leaderboard/components/PerformanceChart.tsx +0 -109
  206. package/leaderboard/next-env.d.ts +0 -5
  207. package/leaderboard/next.config.js +0 -4
  208. package/leaderboard/package-lock.json +0 -6363
  209. package/leaderboard/package.json +0 -28
  210. package/leaderboard/postcss.config.js +0 -6
  211. package/leaderboard/tailwind.config.js +0 -17
  212. package/leaderboard/tsconfig.json +0 -28
  213. package/leaderboard/types/benchmark.ts +0 -67
  214. package/leaderboard/utils/dataProcessor.ts +0 -33
  215. package/src/agents/tools/asana/definitions.ts +0 -199
  216. package/src/agents/tools/asana/index.ts +0 -108
  217. package/src/agents/tools/ast/astAppendNode.ts +0 -90
  218. package/src/agents/tools/ast/astDeleteNode.ts +0 -88
  219. package/src/agents/tools/ast/astEditNode.ts +0 -95
  220. package/src/agents/tools/ast/astGetPathForLine.ts +0 -73
  221. package/src/agents/tools/ast/astListPaths.ts +0 -66
  222. package/src/agents/tools/ast/index.ts +0 -7
  223. package/src/agents/tools/github/definitions.ts +0 -89
  224. package/src/agents/tools/github/index.ts +0 -67
  225. package/src/chat-old.ts +0 -446
  226. package/src/plugins/asana.ts +0 -146
  227. package/src/plugins/downloader/plugin.ts +0 -103
  228. package/src/plugins/downloader/types.ts +0 -92
  229. package/src/plugins/figma.ts +0 -158
  230. package/src/plugins/github.ts +0 -219
  231. package/src/plugins/jira.ts +0 -115
  232. package/src/plugins/linear.ts +0 -230
  233. package/src/plugins/notion.ts +0 -179
  234. package/src/plugins/tree-sitter/editor.ts +0 -369
  235. package/src/plugins/tree-sitter/lang-packs/index.ts +0 -23
  236. package/src/plugins/tree-sitter/lang-packs/java.ts +0 -59
  237. package/src/plugins/tree-sitter/lang-packs/javascript.ts +0 -57
  238. package/src/plugins/tree-sitter/lang-packs/python.ts +0 -45
  239. package/src/plugins/tree-sitter/lang-packs/types.ts +0 -79
  240. package/src/plugins/tree-sitter/lang-packs/typescript.ts +0 -49
  241. package/src/plugins/tree-sitter/parser.ts +0 -470
  242. package/src/plugins/tree-sitter/simple-paths.ts +0 -467
  243. package/tests/tree-sitter/editor.test.ts +0 -113
  244. package/tests/tree-sitter/invalid.test.ts +0 -299
  245. package/tests/tree-sitter/paths/common-edits.test.ts +0 -564
  246. package/tests/tree-sitter/paths/debug-exact-position.test.ts +0 -44
  247. package/tests/tree-sitter/paths/debug-line-indexing.test.ts +0 -49
  248. package/tests/tree-sitter/paths/debug-paths.test.ts +0 -90
  249. package/tests/tree-sitter/paths/paths.test.ts +0 -170
  250. package/tests/tree-sitter/paths/simple-paths.test.ts +0 -367
  251. package/tests/tree-sitter/sample-after.ts +0 -48
  252. package/tests/tree-sitter/sample-before.ts +0 -25
  253. package/tests/tree-sitter/test-files/completely-broken.ts +0 -7
  254. package/tests/tree-sitter/test-files/duplicate-braces.ts +0 -39
  255. package/tests/tree-sitter/test-files/invalid-nesting.ts +0 -39
  256. package/tests/tree-sitter/test-files/malformed-signature.ts +0 -39
  257. package/tests/tree-sitter/test-files/mismatched-parens.ts +0 -39
  258. package/tests/tree-sitter/test-files/missing-semicolon.ts +0 -39
  259. package/tests/tree-sitter/test-files/partially-broken.ts +0 -20
  260. package/tests/tree-sitter/test-files/specific-errors.ts +0 -14
  261. package/tests/tree-sitter/test-files/unclosed-string.ts +0 -39
  262. package/tests/tree-sitter/tree-sitter.test.ts +0 -251
@@ -1,92 +0,0 @@
1
- export class AudioFormat {
2
- ext: string;
3
- width: number | null;
4
- height: number | null;
5
- tbr: number | null;
6
- format_id: string;
7
- url: string;
8
- vcodec: string;
9
- http_headers: Record<string, string>;
10
- protocol: string;
11
- resolution: string;
12
- aspect_ratio: number | null;
13
- audio_ext: string;
14
- video_ext: string;
15
- format: string;
16
- }
17
-
18
- export interface KeyframeInfo {
19
- path: string;
20
- description: string;
21
- timestamp: number;
22
- usd_cost: number | null;
23
- }
24
-
25
- export interface TranscriptChunk {
26
- chunkPath: string;
27
- text: string;
28
- usd_cost: number | null;
29
- }
30
-
31
- export class RequestedDownload {
32
- ext: string;
33
- format_id: string;
34
- url: string;
35
- vcodec: string;
36
- http_headers: Record<string, string>;
37
- protocol: string;
38
- resolution: string;
39
- audio_ext: string;
40
- video_ext: string;
41
- format: string;
42
- epoch: number;
43
- _filename: string;
44
- __write_download_archive: boolean;
45
- }
46
-
47
- export class DownloadInfo {
48
- id: string;
49
- title: string;
50
- timestamp: Date | null;
51
- description: string | null;
52
- thumbnail: string | null;
53
- age_limit: number;
54
- formats: AudioFormat[];
55
- subtitles: Record<string, string>;
56
- _old_archive_ids: string[];
57
- extractor: string;
58
- extractor_key: string;
59
- webpage_url: string;
60
- original_url: string;
61
- webpage_url_basename: string;
62
- webpage_url_domain: string;
63
- playlist: string | null;
64
- playlist_index: number | null;
65
- display_id: string;
66
- fulltitle: string;
67
- requested_subtitles: Record<string, string> | null;
68
- _has_drm: boolean | null;
69
- requested_downloads: RequestedDownload[];
70
- ext: string;
71
- width: number | null;
72
- height: number | null;
73
- tbr: number | null;
74
- format_id: string;
75
- url: string;
76
- vcodec: string;
77
- http_headers: Record<string, string>;
78
- protocol: string;
79
- resolution: string;
80
- aspect_ratio: number | null;
81
- audio_ext: string;
82
- video_ext: string;
83
- format: string;
84
- epoch: number;
85
- _type: string;
86
- _version: {
87
- version: string;
88
- current_git_head: string | null;
89
- release_git_head: string;
90
- repository: string;
91
- };
92
- }
@@ -1,158 +0,0 @@
1
- import { Client } from "figma-js";
2
- import qs from "qs"; // Assumed to be installed
3
- import { PluginBase, PluginMeta } from "./PluginBase";
4
- import { PluginContext } from "./types";
5
- import { Plugin } from "./types";
6
- import { MinimalEmbedding } from "../types";
7
-
8
- interface Node {}
9
-
10
- interface Component {}
11
-
12
- interface ComponentSet {}
13
-
14
- interface Style {}
15
-
16
- interface FigmaNodeData {
17
- document: Node;
18
- components: Map<string, Component>;
19
- componentSets: Map<string, ComponentSet>;
20
- schemaVersion: number;
21
- styles: Map<string, Style>;
22
- }
23
-
24
- interface FigmaApiResponse {
25
- name: string;
26
- role: string;
27
- lastModified: string;
28
- editorType: string;
29
- thumbnailUrl: string;
30
- err: string;
31
- nodes: Record<string, FigmaNodeData>;
32
- }
33
-
34
- export class FigmaPlugin extends PluginBase implements Plugin {
35
- private figmaToken: string;
36
- private client: ReturnType<typeof Client>;
37
-
38
- static readonly meta: PluginMeta = {
39
- key: "figma",
40
- name: "Figma Plugin",
41
- requires: ["FIGMA_API_KEY"],
42
- };
43
-
44
- meta = FigmaPlugin.meta;
45
-
46
- constructor(context: PluginContext = {}) {
47
- super(context);
48
- if (!this.isEnabled()) return;
49
-
50
- this.figmaToken = process.env.FIGMA_API_KEY;
51
- this.client = this.figmaToken
52
- ? Client({ personalAccessToken: this.figmaToken })
53
- : null;
54
- }
55
-
56
- customEnableCheck(): boolean {
57
- return !!this.figmaToken && !!this.client;
58
- }
59
-
60
- async loadFigmaData(url: string) {
61
- const fileId = this.extractFileIdFromUrl(url);
62
- const nodeIds = this.parseNodeIdsFromUrl(url);
63
- if (!fileId) {
64
- return null;
65
- }
66
- try {
67
- this.log(`Fetching figma data: ${JSON.stringify({ fileId, nodeIds })}`);
68
- const response = await this.client.fileImages(fileId, { ids: nodeIds });
69
- return { id: fileId, ...response.data };
70
- } catch (error) {
71
- this.log(`Error fetching Figma file data: ${error}`, "error");
72
- return null;
73
- }
74
- }
75
-
76
- extractFileIdFromUrl(url: string): string | null {
77
- const match = /https:\/\/www\.figma\.com\/file\/([A-Za-z0-9]+)/.exec(url);
78
- return match ? match[1] : null;
79
- }
80
-
81
- // New utility function for parsing node ids from Figma URL
82
- parseNodeIdsFromUrl(url: string): string[] | null {
83
- const queryIndex = url.indexOf("?");
84
- if (queryIndex === -1) return null;
85
- const queryStr = url.substring(queryIndex + 1);
86
- const queryParams = qs.parse(queryStr);
87
- const nodeParam = queryParams["node-id"];
88
- let nodeIds = [];
89
- if (Array.isArray(nodeParam)) {
90
- nodeIds = nodeParam;
91
- }
92
- if (typeof nodeParam === "string") {
93
- nodeIds = nodeParam.split(",");
94
- }
95
- return nodeIds || null;
96
- }
97
-
98
- extractUrls(userPrompt: string): string[] {
99
- const urlRegex = /https:\/\/www\.figma\.com\/file\/[^\s]+/g;
100
- const matches = userPrompt.match(urlRegex);
101
- return matches || [];
102
- }
103
-
104
- async embed(userPrompt: string): Promise<MinimalEmbedding[]> {
105
- const urls = this.extractUrls(userPrompt);
106
- const figmaData = await Promise.all(
107
- urls.map((url) => this.loadFigmaData(url))
108
- );
109
- const filteredData = figmaData.filter((data) => data !== null);
110
-
111
- return filteredData.map((data) => ({
112
- id: data.id,
113
- text: this.formatFigmaData(data),
114
- metadata: {},
115
- }));
116
- }
117
-
118
- formatFigmaData(data: any): string {
119
- return JSON.stringify(data);
120
- }
121
-
122
- async call(userPrompt: string): Promise<string> {
123
- const urls = this.extractUrls(userPrompt);
124
- if (!urls || urls.length === 0) {
125
- return "FIGMA PLUGIN: No Figma files found";
126
- }
127
-
128
- const figmaData = await Promise.all(
129
- urls.map((url) => this.loadFigmaData(url))
130
- );
131
- const figmaDataFiltered = figmaData.filter((data) => data !== null);
132
-
133
- if (figmaDataFiltered.length === 0) {
134
- return "FIGMA PLUGIN: Failed to fetch data for Figma files";
135
- }
136
-
137
- const responses = [];
138
- for (const data of figmaDataFiltered) {
139
- for (const nodeId in data.images) {
140
- if (!data.images.hasOwnProperty(nodeId)) continue;
141
-
142
- const imageUrl = data.images[nodeId];
143
- // Lazy import to break circular dependency
144
- const { askGptVision } = await import("../ai");
145
- const imageDescription = await askGptVision(
146
- imageUrl,
147
- `Describe the image with relavant information for this user question: ${userPrompt}`
148
- );
149
- this.log(`Image description: ${imageDescription.choices[0].message.content}`);
150
- responses.push({ nodeId, imageDescription });
151
- }
152
- }
153
-
154
- return `FIGMA PLUGIN: The following Figma files were loaded:\n\n${JSON.stringify(
155
- responses
156
- )}`;
157
- }
158
- }
@@ -1,219 +0,0 @@
1
- import { Octokit } from "@octokit/rest";
2
- import { PluginBase, PluginMeta } from "./PluginBase";
3
- import { PluginContext } from "./types";
4
- import { parseHunks, hunksToPatch } from "../agents/tools/patch";
5
- import { MinimalEmbedding } from "../types";
6
-
7
- export class GitHubPlugin extends PluginBase {
8
- static readonly meta: PluginMeta = {
9
- key: "github",
10
- name: "GitHub Plugin",
11
- requires: ["GITHUB_TOKEN"],
12
- };
13
-
14
- meta = GitHubPlugin.meta;
15
- octokit: Octokit;
16
-
17
- constructor(context: PluginContext) {
18
- super(context);
19
-
20
- const key = process.env.GITHUB_TOKEN;
21
- if (key && this.isEnabled()) {
22
- this.octokit = new Octokit({
23
- auth: key,
24
- });
25
- }
26
- }
27
-
28
- protected customEnableCheck(): boolean {
29
- // Additional check: ensure we can create the Octokit client
30
- try {
31
- const key = process.env.GITHUB_TOKEN;
32
- if (key) {
33
- this.octokit = new Octokit({ auth: key });
34
- return true;
35
- }
36
- return false;
37
- } catch (error) {
38
- this.log(`Failed to initialize Octokit client: ${error}`, "error");
39
- return false;
40
- }
41
- }
42
-
43
- async embed(userPrompt: string): Promise<MinimalEmbedding[]> {
44
- const urls = this.extractUrls(userPrompt);
45
- const diffs = await this.getParsedDiffs(urls);
46
- const diffsFiltered = diffs.filter((diff) => diff !== null);
47
-
48
- return diffsFiltered.map((diff, index) => {
49
- return {
50
- id: urls[index],
51
- text: JSON.stringify(diff),
52
- metadata: {},
53
- };
54
- });
55
- }
56
-
57
- extractUrls(userPrompt: string): string[] {
58
- const prUrlRegex =
59
- /https:\/\/github\.com\/([\w-]+)\/([\w-]+)\/pull\/(\d+)/g;
60
- const matches = userPrompt.match(prUrlRegex);
61
- return matches;
62
- }
63
-
64
- parseUrl(url: string) {
65
- const [owner, repo, _, pullNumber] = url.split("/").slice(-4);
66
- return {
67
- owner,
68
- repo,
69
- pullNumber,
70
- };
71
- }
72
-
73
- async getDiff(url: string) {
74
- try {
75
- const { owner, repo, pullNumber } = this.parseUrl(url);
76
- this.log(`Loading diff for ${owner}/${repo}#${pullNumber}`);
77
- const { data: diff } = await this.octokit.rest.pulls.get({
78
- owner,
79
- repo,
80
- pull_number: parseInt(pullNumber, 10),
81
- mediaType: {
82
- format: "diff",
83
- },
84
- });
85
-
86
- return diff;
87
- } catch (error) {
88
- this.log(`Failed to get diff for ${url}: ${error.message}`, "error");
89
- if (error.status === 401) {
90
- this.log("Authentication failed. Please check your GITHUB_TOKEN.", "error");
91
- }
92
- return null;
93
- }
94
- }
95
-
96
- async getPR(url: string) {
97
- try {
98
- const { owner, repo, pullNumber } = this.parseUrl(url);
99
- return await this.octokit.rest.pulls.get({
100
- owner,
101
- repo,
102
- pull_number: parseInt(pullNumber, 10),
103
- });
104
- } catch (error) {
105
- this.log(`Failed to get PR for ${url}: ${error.message}`, "error");
106
- if (error.status === 401) {
107
- this.log("Authentication failed. Please check your GITHUB_TOKEN.", "error");
108
- }
109
- return null;
110
- }
111
- }
112
-
113
- getLengthOfHunks(hunks: ReturnType<typeof parseHunks>) {
114
- const length = hunks
115
- .flatMap((hunk) => [...hunk.additions, ...hunk.subtractions])
116
- .reduce((acc, line) => acc + line.length, 0);
117
- this.log(`Length of hunks: ${length}`);
118
- return length;
119
- }
120
-
121
- async getParsedDiffs(urls: string[]) {
122
- return Promise.all(
123
- urls.map(async (url) => {
124
- try {
125
- const diff = await this.getDiff(url);
126
-
127
- // If getDiff returned null (auth error), skip this URL
128
- if (!diff) {
129
- this.log(`Skipping ${url} due to error`);
130
- return null;
131
- }
132
-
133
- let parsed = parseHunks(diff.toString());
134
-
135
- this.log(`Parsed ${parsed.length} hunks`);
136
-
137
- const averageHunkSize =
138
- parsed.reduce((acc, hunk) => acc + hunk.lines.length, 0) /
139
- parsed.length;
140
-
141
- const totalCharacters = parsed
142
- .flatMap((hunk) => [...hunk.additions, ...hunk.subtractions])
143
- .reduce((acc, line) => acc + line.length, 0);
144
-
145
- this.log(`Average hunk size: ${averageHunkSize}, total characters: ${totalCharacters}`);
146
-
147
- const MAX_CHARACTERS = 10000;
148
- const average = MAX_CHARACTERS / averageHunkSize;
149
- const PER_HUNK_LIMIT = Math.max(average, 2000);
150
-
151
- parsed = parsed.filter((hunk) => {
152
- return this.getLengthOfHunks([hunk]) <= PER_HUNK_LIMIT;
153
- });
154
-
155
- this.log(`Filtered to ${parsed.length} hunks. ${this.getLengthOfHunks(parsed)} characters`);
156
- return parsed;
157
- } catch (error) {
158
- this.log(`Error parsing diff for ${url}: ${error.message}`, "error");
159
- return null;
160
- }
161
- })
162
- );
163
- }
164
-
165
- formatDiff(diff: any) {
166
- return diff;
167
- }
168
-
169
- async call(userPrompt: string): Promise<string> {
170
- const urls = this.extractUrls(userPrompt);
171
-
172
- if (urls) {
173
- try {
174
- const prs = [];
175
- for (const url of urls) {
176
- const prResponse = await this.getPR(url);
177
-
178
- // Skip this PR if we couldn't get its data
179
- if (!prResponse) {
180
- this.log(`Skipping ${url} - could not fetch PR data`);
181
- continue;
182
- }
183
-
184
- const { data: pr } = prResponse;
185
- const responses = await this.getParsedDiffs([url]);
186
-
187
- // Format the diffs in Markdown
188
- const diffStrings = responses
189
- .filter(response => response !== null)
190
- .map(hunksToPatch);
191
-
192
- prs.push({
193
- description: pr.title,
194
- url: pr.html_url,
195
- body: pr.body,
196
- author: pr.user.login,
197
- diff: diffStrings,
198
- });
199
- }
200
-
201
- if (prs.length === 0) {
202
- return "Could not fetch any pull request data. Please check your GITHUB_TOKEN and permissions.";
203
- }
204
-
205
- const context = `These ${urls} have automatically been expanded to include the changes:\n\n${JSON.stringify(
206
- prs,
207
- null,
208
- 2
209
- )}`;
210
- this.log(context);
211
- return context;
212
- } catch (error) {
213
- return `Error fetching pull request data: ${error.message}`;
214
- }
215
- }
216
-
217
- return "No pull request URLs detected.";
218
- }
219
- }
@@ -1,115 +0,0 @@
1
- import JiraClient from "jira-client";
2
- import { PluginBase, PluginMeta } from "./PluginBase";
3
- import { PluginContext } from "./types";
4
- import { MinimalEmbedding } from "../types";
5
-
6
- export class JiraPlugin extends PluginBase {
7
- static readonly meta: PluginMeta = {
8
- key: "jira",
9
- name: "Jira Plugin",
10
- requires: ["JIRA_HOST", "JIRA_USER", "JIRA_PASSWORD"]
11
- };
12
-
13
- meta = JiraPlugin.meta;
14
- jiraClient: JiraClient;
15
-
16
- constructor(context: PluginContext) {
17
- super(context);
18
-
19
- if (!this.isEnabled()) return;
20
- this.jiraClient = new JiraClient({
21
- protocol: "https",
22
- host: process.env.JIRA_HOST,
23
- username: process.env.JIRA_USER,
24
- password: process.env.JIRA_PASSWORD,
25
- apiVersion: "2",
26
- strictSSL: true,
27
- });
28
- }
29
-
30
- async embed(userPrompt: string): Promise<MinimalEmbedding[]> {
31
- const urls = this.extractUrls(userPrompt);
32
- const tasks = await this.getTasksFromUrls(urls);
33
- const tasksFiltered = tasks.filter((task) => task !== null);
34
-
35
- return tasksFiltered.map((task, index) => {
36
- return {
37
- id: urls[index],
38
- text: JSON.stringify(task),
39
- metadata: {},
40
- };
41
- });
42
- }
43
-
44
- async getTasksFromUrls(urls: string[]) {
45
- const tasks = await Promise.all(
46
- urls.map(async (url) => {
47
- return this.getTaskFromUrl(url);
48
- })
49
- );
50
- return tasks;
51
- }
52
-
53
- async getTaskFromUrl(url: string) {
54
- const issueId = this.extractIdFromUrl(url);
55
- if (issueId) {
56
- this.log(`Fetching Jira issue ${issueId}`);
57
- return await this.getIssueData(issueId);
58
- }
59
- return null;
60
- }
61
-
62
- async getIssueData(issueId: string) {
63
- try {
64
- const issue = await this.jiraClient.findIssue(issueId);
65
- return issue;
66
- } catch (error) {
67
- this.log(`Error fetching Jira issue: ${error}`, "error");
68
- return null;
69
- }
70
- }
71
-
72
- // https://${process.env.JIRA_HOST}/browse/${issue.key}
73
- extractUrls(userPrompt: string): string[] {
74
- const host = process.env.JIRA_HOST;
75
- const regex = new RegExp(`https://${host}/browse/[A-Z]+-\\d+`, "g");
76
- const matches = userPrompt.match(regex);
77
- if (!matches) {
78
- return [];
79
- }
80
- return matches;
81
- }
82
-
83
- extractIdFromUrl(url: string): string {
84
- const host = process.env.JIRA_HOST;
85
- const regex = new RegExp(`https://${host}/browse/([A-Z]+-\\d+)`, "g");
86
- const matches = regex.exec(url);
87
- if (matches && matches[1]) {
88
- return matches[1];
89
- }
90
- return null;
91
- }
92
-
93
- getTaskString(task: any) {
94
- return `### Issue: ${task.key}\n- Summary: ${task.fields.summary}\n- URL: ${process.env.JIRA_HOST}/browse/${task.key} \n- Description: ${task.fields.description}`;
95
- }
96
-
97
- async call(userPrompt: string): Promise<string> {
98
- const urls = this.extractUrls(userPrompt);
99
- if (!urls) {
100
- return "JIRA PLUGIN: No issues found";
101
- }
102
-
103
- const issuesData = await this.getTasksFromUrls(urls);
104
- const issuesDataFiltered = issuesData.filter((issue) => issue !== null);
105
-
106
- if (issuesDataFiltered.length === 0) {
107
- return "JIRA PLUGIN: No issues found";
108
- }
109
-
110
- const markdownIssues = issuesDataFiltered
111
- .map((issue) => this.getTaskString(issue))
112
- .join("\n\n");
113
- return `JIRA PLUGIN: The following issues were loaded:\n\n${markdownIssues}`;
114
- }
115
- }