@tyvm/knowhow 0.0.90 → 0.0.92

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 (272) hide show
  1. package/.depcheckrc +30 -0
  2. package/bin/knowhow.js +1 -1
  3. package/package.json +8 -34
  4. package/src/agents/configurable/ConfigAgent.ts +2 -2
  5. package/src/agents/tools/executeScript/index.ts +5 -0
  6. package/src/agents/tools/googleSearch.ts +2 -2
  7. package/src/agents/tools/index.ts +0 -3
  8. package/src/agents/tools/list.ts +0 -147
  9. package/src/agents/tools/loadWebpage.ts +3 -113
  10. package/src/auth/browserLogin.ts +10 -13
  11. package/src/chat/modules/AgentModule.ts +0 -1
  12. package/src/chat/types.ts +1 -1
  13. package/src/cli.ts +63 -3
  14. package/src/clients/gemini.ts +96 -25
  15. package/src/clients/http.ts +7 -11
  16. package/src/clients/pricing/google.ts +122 -26
  17. package/src/conversion.ts +24 -54
  18. package/src/index.ts +15 -20
  19. package/src/login.ts +5 -6
  20. package/src/plugins/language.ts +0 -4
  21. package/src/plugins/plugins.ts +0 -14
  22. package/src/plugins/url.ts +31 -12
  23. package/src/services/EmbeddingsService.ts +70 -0
  24. package/src/services/KnowhowClient.ts +34 -34
  25. package/src/{plugins/downloader/downloader.ts → services/MediaProcessorService.ts} +109 -267
  26. package/src/services/S3.ts +19 -87
  27. package/src/services/index.ts +8 -8
  28. package/src/services/modules/index.ts +12 -3
  29. package/src/services/modules/types.ts +8 -2
  30. package/src/services/script-execution/ScriptExecutor.ts +29 -10
  31. package/src/services/script-execution/ScriptPolicy.ts +6 -2
  32. package/src/types.ts +1 -0
  33. package/src/utils/http.ts +127 -0
  34. package/src/workers/auth/PasskeySetup.ts +7 -11
  35. package/tests/clients/AIClient.test.ts +24 -21
  36. package/tests/manual/file-edits/figma.test.ts +3 -70
  37. package/tests/plugins/language/languagePlugin-content-triggers.test.ts +2 -0
  38. package/tests/plugins/language/languagePlugin.test.ts +2 -0
  39. package/tests/processors/ToolResponseCache.test.ts +2 -2
  40. package/tests/test.spec.ts +0 -14
  41. package/tests/unit/modules/moduleLoading.test.ts +12 -4
  42. package/tests/unit/plugins/pluginLoading.test.ts +6 -6
  43. package/ts_build/package.json +8 -34
  44. package/ts_build/src/agents/tools/ast/astAppendNode.d.ts +1 -1
  45. package/ts_build/src/agents/tools/ast/astAppendNode.js +2 -90
  46. package/ts_build/src/agents/tools/ast/astAppendNode.js.map +1 -1
  47. package/ts_build/src/agents/tools/ast/astDeleteNode.d.ts +1 -1
  48. package/ts_build/src/agents/tools/ast/astDeleteNode.js +2 -88
  49. package/ts_build/src/agents/tools/ast/astDeleteNode.js.map +1 -1
  50. package/ts_build/src/agents/tools/ast/astEditNode.d.ts +1 -1
  51. package/ts_build/src/agents/tools/ast/astEditNode.js +2 -90
  52. package/ts_build/src/agents/tools/ast/astEditNode.js.map +1 -1
  53. package/ts_build/src/agents/tools/ast/astGetPathForLine.d.ts +1 -1
  54. package/ts_build/src/agents/tools/ast/astGetPathForLine.js +2 -72
  55. package/ts_build/src/agents/tools/ast/astGetPathForLine.js.map +1 -1
  56. package/ts_build/src/agents/tools/ast/astListPaths.d.ts +1 -1
  57. package/ts_build/src/agents/tools/ast/astListPaths.js +2 -72
  58. package/ts_build/src/agents/tools/ast/astListPaths.js.map +1 -1
  59. package/ts_build/src/agents/tools/executeScript/index.d.ts +3 -2
  60. package/ts_build/src/agents/tools/executeScript/index.js +4 -1
  61. package/ts_build/src/agents/tools/executeScript/index.js.map +1 -1
  62. package/ts_build/src/agents/tools/googleSearch.js +2 -2
  63. package/ts_build/src/agents/tools/googleSearch.js.map +1 -1
  64. package/ts_build/src/agents/tools/index.d.ts +0 -3
  65. package/ts_build/src/agents/tools/index.js +0 -3
  66. package/ts_build/src/agents/tools/index.js.map +1 -1
  67. package/ts_build/src/agents/tools/list.js +0 -138
  68. package/ts_build/src/agents/tools/list.js.map +1 -1
  69. package/ts_build/src/agents/tools/loadWebpage.js +1 -89
  70. package/ts_build/src/agents/tools/loadWebpage.js.map +1 -1
  71. package/ts_build/src/agents/tools/textSearch.d.ts +1 -1
  72. package/ts_build/src/auth/browserLogin.js +7 -7
  73. package/ts_build/src/auth/browserLogin.js.map +1 -1
  74. package/ts_build/src/chat/modules/AgentModule.js.map +1 -1
  75. package/ts_build/src/chat/types.d.ts +1 -1
  76. package/ts_build/src/cli.d.ts +1 -1
  77. package/ts_build/src/cli.js +47 -1
  78. package/ts_build/src/cli.js.map +1 -1
  79. package/ts_build/src/clients/gemini.d.ts +1 -73
  80. package/ts_build/src/clients/gemini.js +57 -19
  81. package/ts_build/src/clients/gemini.js.map +1 -1
  82. package/ts_build/src/clients/http.js +5 -9
  83. package/ts_build/src/clients/http.js.map +1 -1
  84. package/ts_build/src/clients/pricing/google.d.ts +17 -73
  85. package/ts_build/src/clients/pricing/google.js +47 -10
  86. package/ts_build/src/clients/pricing/google.js.map +1 -1
  87. package/ts_build/src/conversion.d.ts +1 -4
  88. package/ts_build/src/conversion.js +12 -27
  89. package/ts_build/src/conversion.js.map +1 -1
  90. package/ts_build/src/index.d.ts +4 -0
  91. package/ts_build/src/index.js +15 -14
  92. package/ts_build/src/index.js.map +1 -1
  93. package/ts_build/src/login.js +5 -4
  94. package/ts_build/src/login.js.map +1 -1
  95. package/ts_build/src/plugins/downloader/downloader.js +3 -3
  96. package/ts_build/src/plugins/downloader/downloader.js.map +1 -1
  97. package/ts_build/src/plugins/language.js.map +1 -1
  98. package/ts_build/src/plugins/plugins.js +0 -14
  99. package/ts_build/src/plugins/plugins.js.map +1 -1
  100. package/ts_build/src/plugins/tree-sitter/editor.d.ts +3 -32
  101. package/ts_build/src/plugins/tree-sitter/editor.js +6 -208
  102. package/ts_build/src/plugins/tree-sitter/editor.js.map +1 -1
  103. package/ts_build/src/plugins/tree-sitter/parser.d.ts +19 -54
  104. package/ts_build/src/plugins/tree-sitter/parser.js +19 -293
  105. package/ts_build/src/plugins/tree-sitter/parser.js.map +1 -1
  106. package/ts_build/src/plugins/tree-sitter/simple-paths.d.ts +2 -15
  107. package/ts_build/src/plugins/tree-sitter/simple-paths.js +2 -324
  108. package/ts_build/src/plugins/tree-sitter/simple-paths.js.map +1 -1
  109. package/ts_build/src/plugins/url.js +27 -8
  110. package/ts_build/src/plugins/url.js.map +1 -1
  111. package/ts_build/src/services/EmbeddingsService.d.ts +14 -0
  112. package/ts_build/src/services/EmbeddingsService.js +33 -0
  113. package/ts_build/src/services/EmbeddingsService.js.map +1 -0
  114. package/ts_build/src/services/GitHub.js +2 -2
  115. package/ts_build/src/services/GitHub.js.map +1 -1
  116. package/ts_build/src/services/KnowhowClient.d.ts +29 -29
  117. package/ts_build/src/services/KnowhowClient.js +33 -33
  118. package/ts_build/src/services/KnowhowClient.js.map +1 -1
  119. package/ts_build/src/services/MediaProcessorService.d.ts +22 -0
  120. package/ts_build/src/services/MediaProcessorService.js +215 -0
  121. package/ts_build/src/services/MediaProcessorService.js.map +1 -0
  122. package/ts_build/src/services/S3.d.ts +0 -4
  123. package/ts_build/src/services/S3.js +14 -60
  124. package/ts_build/src/services/S3.js.map +1 -1
  125. package/ts_build/src/services/index.d.ts +6 -5
  126. package/ts_build/src/services/index.js +6 -6
  127. package/ts_build/src/services/index.js.map +1 -1
  128. package/ts_build/src/services/modules/index.js +12 -3
  129. package/ts_build/src/services/modules/index.js.map +1 -1
  130. package/ts_build/src/services/modules/types.d.ts +8 -2
  131. package/ts_build/src/services/script-execution/ScriptExecutor.js +22 -7
  132. package/ts_build/src/services/script-execution/ScriptExecutor.js.map +1 -1
  133. package/ts_build/src/services/script-execution/ScriptPolicy.d.ts +1 -1
  134. package/ts_build/src/services/script-execution/ScriptPolicy.js +4 -2
  135. package/ts_build/src/services/script-execution/ScriptPolicy.js.map +1 -1
  136. package/ts_build/src/types.d.ts +1 -0
  137. package/ts_build/src/types.js +1 -0
  138. package/ts_build/src/types.js.map +1 -1
  139. package/ts_build/src/utils/http.d.ts +27 -0
  140. package/ts_build/src/utils/http.js +98 -0
  141. package/ts_build/src/utils/http.js.map +1 -0
  142. package/ts_build/src/workers/auth/PasskeySetup.js +6 -7
  143. package/ts_build/src/workers/auth/PasskeySetup.js.map +1 -1
  144. package/ts_build/tests/clients/AIClient.test.js +11 -14
  145. package/ts_build/tests/clients/AIClient.test.js.map +1 -1
  146. package/ts_build/tests/manual/file-edits/figma.test.d.ts +0 -1
  147. package/ts_build/tests/manual/file-edits/figma.test.js +1 -46
  148. package/ts_build/tests/manual/file-edits/figma.test.js.map +1 -1
  149. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js +2 -0
  150. package/ts_build/tests/plugins/language/languagePlugin-content-triggers.test.js.map +1 -1
  151. package/ts_build/tests/plugins/language/languagePlugin.test.js +2 -0
  152. package/ts_build/tests/plugins/language/languagePlugin.test.js.map +1 -1
  153. package/ts_build/tests/processors/ToolResponseCache.test.js +2 -2
  154. package/ts_build/tests/processors/ToolResponseCache.test.js.map +1 -1
  155. package/ts_build/tests/test.spec.js +0 -14
  156. package/ts_build/tests/test.spec.js.map +1 -1
  157. package/ts_build/tests/tree-sitter/tree-sitter.test.d.ts +0 -1
  158. package/ts_build/tests/tree-sitter/tree-sitter.test.js +2 -183
  159. package/ts_build/tests/tree-sitter/tree-sitter.test.js.map +1 -1
  160. package/ts_build/tests/unit/modules/moduleLoading.test.js +11 -4
  161. package/ts_build/tests/unit/modules/moduleLoading.test.js.map +1 -1
  162. package/ts_build/tests/unit/plugins/pluginLoading.test.js +4 -4
  163. package/ts_build/tests/unit/plugins/pluginLoading.test.js.map +1 -1
  164. package/benchmarks/.dockerignore +0 -7
  165. package/benchmarks/README.md +0 -166
  166. package/benchmarks/docker/Dockerfile +0 -68
  167. package/benchmarks/example-config.yml +0 -27
  168. package/benchmarks/jest.config.js +0 -13
  169. package/benchmarks/package-lock.json +0 -4297
  170. package/benchmarks/package.json +0 -39
  171. package/benchmarks/results/27b0a06/2025-09-27/xai/xai-grok-code-fast-1.json +0 -2909
  172. package/benchmarks/results/4057aed/2025-08-14/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -1671
  173. package/benchmarks/results/4542435/2025-08-05/lms/lms-openai-gpt-oss-20b.json +0 -2814
  174. package/benchmarks/results/4542435/2025-08-05/lms/lms-qwen-qwen3-30b-a3b-2507.json +0 -2014
  175. package/benchmarks/results/4fb9125/2025-08-07/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -3121
  176. package/benchmarks/results/5766aee/2025-08-02/lms-qwen/qwen3-coder-30b.json +0 -98
  177. package/benchmarks/results/6d73808/2025-08-07/openai/openai-gpt-5.json +0 -3256
  178. package/benchmarks/results/77bf0a6/2025-08-02/lms-qwen/qwen3-30b-a3b-2507.json +0 -4298
  179. package/benchmarks/results/8c0d445/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -3031
  180. package/benchmarks/results/8c0d445/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +0 -2990
  181. package/benchmarks/results/ac6b2ab/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +0 -3256
  182. package/benchmarks/results/ac6b2ab/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +0 -3007
  183. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +0 -3256
  184. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-mini-2025-04-14.json +0 -3036
  185. package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-nano-2025-04-14.json +0 -3280
  186. package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-30b-a3b-2507.json +0 -1920
  187. package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-coder-30b.json +0 -3281
  188. package/benchmarks/results/b502ed9/2025-08-03/lms-qwen/qwen3-coder-30b.json +0 -2896
  189. package/benchmarks/results/d1a8129/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +0 -3011
  190. package/benchmarks/results/e60471c/2025-08-03/lms/qwen3-30b-a3b-2507.json +0 -3003
  191. package/benchmarks/scripts/build-and-run.sh +0 -47
  192. package/benchmarks/scripts/clone-exercism.sh +0 -92
  193. package/benchmarks/scripts/validate.sh +0 -48
  194. package/benchmarks/src/__tests__/runner.test.ts +0 -27
  195. package/benchmarks/src/cli.ts +0 -90
  196. package/benchmarks/src/evaluators/EvaluatorRegistry.ts +0 -64
  197. package/benchmarks/src/evaluators/JavaScriptEvaluator.ts +0 -183
  198. package/benchmarks/src/evaluators/index.ts +0 -3
  199. package/benchmarks/src/evaluators/types.ts +0 -22
  200. package/benchmarks/src/index.ts +0 -3
  201. package/benchmarks/src/providers.ts +0 -13
  202. package/benchmarks/src/runner.ts +0 -824
  203. package/benchmarks/src/types.ts +0 -63
  204. package/benchmarks/tsconfig.json +0 -19
  205. package/leaderboard/README.md +0 -148
  206. package/leaderboard/app/api/benchmark-data/route.ts +0 -131
  207. package/leaderboard/app/api/benchmark-detail/route.ts +0 -172
  208. package/leaderboard/app/details/[model]/[provider]/[language]/page.tsx +0 -501
  209. package/leaderboard/app/exercise/[model]/[provider]/[language]/[exercise]/page.tsx +0 -375
  210. package/leaderboard/app/globals.css +0 -27
  211. package/leaderboard/app/layout.tsx +0 -21
  212. package/leaderboard/app/page.tsx +0 -170
  213. package/leaderboard/components/LeaderboardTable.tsx +0 -168
  214. package/leaderboard/components/PerformanceChart.tsx +0 -109
  215. package/leaderboard/next-env.d.ts +0 -5
  216. package/leaderboard/next.config.js +0 -4
  217. package/leaderboard/package-lock.json +0 -6363
  218. package/leaderboard/package.json +0 -28
  219. package/leaderboard/postcss.config.js +0 -6
  220. package/leaderboard/tailwind.config.js +0 -17
  221. package/leaderboard/tsconfig.json +0 -28
  222. package/leaderboard/types/benchmark.ts +0 -67
  223. package/leaderboard/utils/dataProcessor.ts +0 -33
  224. package/src/agents/tools/asana/definitions.ts +0 -199
  225. package/src/agents/tools/asana/index.ts +0 -108
  226. package/src/agents/tools/ast/astAppendNode.ts +0 -90
  227. package/src/agents/tools/ast/astDeleteNode.ts +0 -88
  228. package/src/agents/tools/ast/astEditNode.ts +0 -95
  229. package/src/agents/tools/ast/astGetPathForLine.ts +0 -73
  230. package/src/agents/tools/ast/astListPaths.ts +0 -66
  231. package/src/agents/tools/ast/index.ts +0 -7
  232. package/src/agents/tools/github/definitions.ts +0 -89
  233. package/src/agents/tools/github/index.ts +0 -67
  234. package/src/chat-old.ts +0 -446
  235. package/src/plugins/asana.ts +0 -146
  236. package/src/plugins/downloader/plugin.ts +0 -103
  237. package/src/plugins/downloader/types.ts +0 -92
  238. package/src/plugins/figma.ts +0 -158
  239. package/src/plugins/github.ts +0 -219
  240. package/src/plugins/jira.ts +0 -115
  241. package/src/plugins/linear.ts +0 -230
  242. package/src/plugins/notion.ts +0 -179
  243. package/src/plugins/tree-sitter/editor.ts +0 -369
  244. package/src/plugins/tree-sitter/lang-packs/index.ts +0 -23
  245. package/src/plugins/tree-sitter/lang-packs/java.ts +0 -59
  246. package/src/plugins/tree-sitter/lang-packs/javascript.ts +0 -57
  247. package/src/plugins/tree-sitter/lang-packs/python.ts +0 -45
  248. package/src/plugins/tree-sitter/lang-packs/types.ts +0 -79
  249. package/src/plugins/tree-sitter/lang-packs/typescript.ts +0 -49
  250. package/src/plugins/tree-sitter/parser.ts +0 -470
  251. package/src/plugins/tree-sitter/simple-paths.ts +0 -467
  252. package/src/services/GitHub.ts +0 -59
  253. package/tests/tree-sitter/editor.test.ts +0 -113
  254. package/tests/tree-sitter/invalid.test.ts +0 -299
  255. package/tests/tree-sitter/paths/common-edits.test.ts +0 -564
  256. package/tests/tree-sitter/paths/debug-exact-position.test.ts +0 -44
  257. package/tests/tree-sitter/paths/debug-line-indexing.test.ts +0 -49
  258. package/tests/tree-sitter/paths/debug-paths.test.ts +0 -90
  259. package/tests/tree-sitter/paths/paths.test.ts +0 -170
  260. package/tests/tree-sitter/paths/simple-paths.test.ts +0 -367
  261. package/tests/tree-sitter/sample-after.ts +0 -48
  262. package/tests/tree-sitter/sample-before.ts +0 -25
  263. package/tests/tree-sitter/test-files/completely-broken.ts +0 -7
  264. package/tests/tree-sitter/test-files/duplicate-braces.ts +0 -39
  265. package/tests/tree-sitter/test-files/invalid-nesting.ts +0 -39
  266. package/tests/tree-sitter/test-files/malformed-signature.ts +0 -39
  267. package/tests/tree-sitter/test-files/mismatched-parens.ts +0 -39
  268. package/tests/tree-sitter/test-files/missing-semicolon.ts +0 -39
  269. package/tests/tree-sitter/test-files/partially-broken.ts +0 -20
  270. package/tests/tree-sitter/test-files/specific-errors.ts +0 -14
  271. package/tests/tree-sitter/test-files/unclosed-string.ts +0 -39
  272. package/tests/tree-sitter/tree-sitter.test.ts +0 -251
package/src/index.ts CHANGED
@@ -5,7 +5,6 @@ import {
5
5
  getHashes,
6
6
  checkNoFilesChanged,
7
7
  } from "./hashes";
8
- import axios from "axios";
9
8
  import * as fs from "fs";
10
9
  import * as path from "path";
11
10
  import * as crypto from "crypto";
@@ -52,6 +51,14 @@ export * as types from "./types";
52
51
  export * as processors from "./processors";
53
52
  export * as ai from "./ai";
54
53
 
54
+ // Export module system types for external modules
55
+ export * from "./services/modules/types";
56
+ // Export plugin types for external plugins
57
+ export { PluginBase } from "./plugins/PluginBase";
58
+ export { PluginMeta, Plugin, PluginContext } from "./plugins/types";
59
+ // Export embedding types
60
+ export { MinimalEmbedding, Embeddable } from "./types";
61
+
55
62
  export async function embed() {
56
63
  // load config
57
64
  const config = await getConfig();
@@ -98,7 +105,7 @@ export async function purge(globPath: string) {
98
105
 
99
106
  export async function upload() {
100
107
  const config = await getConfig();
101
- const { AwsS3, knowhowApiClient } = services();
108
+ const { AwsS3, Embeddings, knowhowApiClient } = services();
102
109
 
103
110
  for (const source of config.embedSources) {
104
111
  const bucketName = source.remote;
@@ -118,16 +125,15 @@ export async function upload() {
118
125
  items,
119
126
  };
120
127
 
121
- if (source.remoteType === "s3") {
128
+ if (Embeddings.hasResolver(source.remoteType) && source.remoteType !== "knowhow") {
122
129
  console.log(
123
130
  "Uploading",
124
131
  source.output,
125
132
  "to",
126
133
  `${bucketName}/${embeddingName}.json`
127
134
  );
128
-
129
- const s3Key = `${embeddingName}.json`;
130
- await AwsS3.uploadFile(source.output, bucketName, s3Key);
135
+ const remoteKey = `${embeddingName}.json`;
136
+ await Embeddings.upload(source.remoteType, source.output, bucketName, remoteKey);
131
137
  } else if (source.remoteType === "knowhow") {
132
138
  if (!source.remoteId) {
133
139
  throw new Error("remoteId is required for knowhow uploads");
@@ -350,7 +356,7 @@ export async function handleSingleOutputGeneration(
350
356
 
351
357
  export async function download() {
352
358
  const config = await getConfig();
353
- const { AwsS3, GitHub, knowhowApiClient } = services();
359
+ const { AwsS3, Embeddings, knowhowApiClient } = services();
354
360
 
355
361
  for (const source of config.embedSources) {
356
362
  const { remote, remoteType } = source;
@@ -368,28 +374,17 @@ export async function download() {
368
374
  const fileName = `${name}.json`;
369
375
  const destinationPath = source.output;
370
376
 
371
- if (remoteType === "s3") {
372
- const bucketName = remote;
377
+ if (Embeddings.hasResolver(remoteType)) {
373
378
  console.log(
374
379
  "Downloading",
375
380
  fileName,
376
381
  `from ${remoteType}`,
377
- bucketName,
378
- "to",
379
- destinationPath
380
- );
381
- await AwsS3.downloadFile(bucketName, fileName, destinationPath);
382
- } else if (remoteType === "github") {
383
- console.log(
384
- "Downloading",
385
- fileName,
386
- "from GitHub repo",
387
382
  remote,
388
383
  "to",
389
384
  destinationPath
390
385
  );
391
386
  const embeddingPath = ".knowhow/embeddings/" + fileName;
392
- await GitHub.downloadFile(remote, embeddingPath, destinationPath);
387
+ await Embeddings.download(remoteType, remote, embeddingPath, destinationPath);
393
388
  } else if (remoteType === "knowhow") {
394
389
  if (!source.remoteId) {
395
390
  throw new Error("remoteId is required for knowhow downloads");
package/src/login.ts CHANGED
@@ -1,4 +1,4 @@
1
- import axios from "axios";
1
+ import http from "./utils/http";
2
2
  import fs from "fs";
3
3
  import path from "path";
4
4
  import { chmod } from "fs/promises";
@@ -68,11 +68,10 @@ export async function login(jwtFlag?: boolean): Promise<void> {
68
68
  await updateConfig(config);
69
69
  }
70
70
  } catch (error) {
71
- if (axios.isAxiosError(error) && error.response) {
71
+ if (http.isHttpError(error) && error.response) {
72
+ const errData = await error.response.json().catch(() => ({ message: "Unknown error" }));
72
73
  throw new Error(
73
- `Error: ${error.response.status} - ${
74
- error.response.data.message || "Unknown error"
75
- }`
74
+ `Error: ${error.status} - ${errData.message || "Unknown error"}`
76
75
  );
77
76
  }
78
77
  console.log(
@@ -98,7 +97,7 @@ export async function loadJwt(): Promise<string> {
98
97
  }
99
98
 
100
99
  export async function checkJwt(storedJwt: string) {
101
- const response = await axios.get(`${KNOWHOW_API_URL}/api/users/me`, {
100
+ const response = await http.get(`${KNOWHOW_API_URL}/api/users/me`, {
102
101
  headers: {
103
102
  Authorization: `Bearer ${storedJwt}`,
104
103
  },
@@ -6,10 +6,6 @@ import { getConfig, getLanguageConfig } from "../config";
6
6
  import { getEnabledPlugins } from "../types";
7
7
  import { PluginBase, PluginMeta } from "./PluginBase";
8
8
  import { Plugin, PluginContext } from "./types";
9
- import { GitHubPlugin } from "./github";
10
- import { AsanaPlugin } from "./asana";
11
- import { JiraPlugin } from "./jira";
12
- import { LinearPlugin } from "./linear";
13
9
  import { PluginService } from "./plugins";
14
10
 
15
11
  /**
@@ -4,13 +4,6 @@ import { VimPlugin } from "./vim";
4
4
  import { LinterPlugin } from "./LinterPlugin";
5
5
  import { LanguagePlugin } from "./language";
6
6
  import { EmbeddingPlugin } from "./embedding";
7
- import { GitHubPlugin } from "./github";
8
- import { AsanaPlugin } from "./asana";
9
- import { LinearPlugin } from "./linear";
10
- import { JiraPlugin } from "./jira";
11
- import { NotionPlugin } from "./notion";
12
- import { DownloaderPlugin } from "./downloader/plugin";
13
- import { FigmaPlugin } from "./figma";
14
7
  import { UrlPlugin } from "./url";
15
8
  import { GitPlugin } from "./GitPlugin";
16
9
  import { TmuxPlugin } from "./tmux";
@@ -33,13 +26,6 @@ export class PluginService {
33
26
  this.pluginMap.set("embeddings", new EmbeddingPlugin(context));
34
27
  this.pluginMap.set("vim", new VimPlugin(context));
35
28
  this.pluginMap.set("linter", new LinterPlugin(context));
36
- this.pluginMap.set("github", new GitHubPlugin(context));
37
- this.pluginMap.set("asana", new AsanaPlugin(context));
38
- this.pluginMap.set("linear", new LinearPlugin(context));
39
- this.pluginMap.set("jira", new JiraPlugin(context));
40
- this.pluginMap.set("notion", new NotionPlugin(context));
41
- this.pluginMap.set("download", new DownloaderPlugin(context));
42
- this.pluginMap.set("figma", new FigmaPlugin(context));
43
29
  this.pluginMap.set("language", new LanguagePlugin(context));
44
30
  this.pluginMap.set("url", new UrlPlugin(context));
45
31
  this.pluginMap.set("git", new GitPlugin(context));
@@ -1,9 +1,6 @@
1
1
  import { PluginBase, PluginMeta } from "./PluginBase";
2
2
  import { Plugin, PluginContext } from "./types";
3
3
  import { MinimalEmbedding } from "../types";
4
- import axios from "axios";
5
- import * as cheerio from "cheerio";
6
- import loadWebpage from "../agents/tools/loadWebpage";
7
4
 
8
5
  export class UrlPlugin extends PluginBase implements Plugin {
9
6
  static readonly meta: PluginMeta = {
@@ -20,22 +17,47 @@ export class UrlPlugin extends PluginBase implements Plugin {
20
17
 
21
18
  async embed(userPrompt: string): Promise<MinimalEmbedding[]> {
22
19
  const urls = this.extractUrls(userPrompt);
23
- const embeddings = await Promise.all(urls.map(this.fetchAndParseUrl));
20
+ const embeddings = await Promise.all(urls.map((url) => this.fetchAndParseUrl(url)));
24
21
  return embeddings.filter((e): e is MinimalEmbedding => e !== null);
25
22
  }
26
23
 
27
24
  extractUrls(userPrompt: string): string[] {
28
25
  const urlRegex = /(https?:\/\/[^\s]+)/g;
29
26
  const urls = userPrompt.match(urlRegex) || [];
30
-
31
27
  return Array.from(new Set(urls));
32
28
  }
33
29
 
34
30
  async fetchAndParseUrl(url: string): Promise<MinimalEmbedding | null> {
35
31
  try {
36
- const text = await loadWebpage(url);
32
+ const response = await fetch(url, {
33
+ headers: {
34
+ "User-Agent": "Mozilla/5.0 (compatible; KnowhowBot/1.0)",
35
+ "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
36
+ },
37
+ });
38
+
39
+ if (!response.ok) {
40
+ this.log(`URL PLUGIN: Failed to fetch ${url}: ${response.status}`, "warn");
41
+ return null;
42
+ }
43
+
44
+ const contentType = response.headers.get("content-type") || "";
45
+ let text = "";
46
+
47
+ if (contentType.includes("text/html") || contentType.includes("text/plain")) {
48
+ const html = await response.text();
49
+ // Simple HTML to text: strip tags
50
+ text = html
51
+ .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "")
52
+ .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "")
53
+ .replace(/<[^>]+>/g, " ")
54
+ .replace(/\s+/g, " ")
55
+ .trim();
56
+ } else {
57
+ text = await response.text();
58
+ }
37
59
 
38
- this.log(`URL PLUGIN: Fetched content from ${url}: ${text}`);
60
+ this.log(`URL PLUGIN: Fetched content from ${url}: ${text.substring(0, 100)}`);
39
61
 
40
62
  return {
41
63
  id: url + "-url",
@@ -58,7 +80,7 @@ export class UrlPlugin extends PluginBase implements Plugin {
58
80
  return "URL PLUGIN: Too many URLs detected. Skipping like unintentional bulk browse.";
59
81
  }
60
82
 
61
- const results = await Promise.all(urls.map(this.fetchAndParseUrl));
83
+ const results = await Promise.all(urls.map((url) => this.fetchAndParseUrl(url)));
62
84
  const validResults = results.filter(
63
85
  (r): r is MinimalEmbedding => r !== null
64
86
  );
@@ -70,10 +92,7 @@ export class UrlPlugin extends PluginBase implements Plugin {
70
92
  const formattedResults = validResults
71
93
  .map(
72
94
  (result) =>
73
- `URL: ${result.metadata.url}\n\nContent:\n${result.text.substring(
74
- 0,
75
- 500
76
- )}...`
95
+ `URL: ${result.metadata.url}\n\nContent:\n${result.text.substring(0, 500)}...`
77
96
  )
78
97
  .join("\n\n---\n\n");
79
98
 
@@ -0,0 +1,70 @@
1
+ type DownloaderFn = (
2
+ remote: string,
3
+ filePath: string,
4
+ destinationPath: string
5
+ ) => Promise<void>;
6
+
7
+ type UploaderFn = (
8
+ localPath: string,
9
+ remote: string,
10
+ remoteKey: string
11
+ ) => Promise<void>;
12
+
13
+ export interface EmbeddingsResolver {
14
+ download: DownloaderFn;
15
+ upload?: UploaderFn;
16
+ }
17
+
18
+ /**
19
+ * EmbeddingsService manages pluggable resolvers for remote embedding sources.
20
+ * Modules can register a resolver for a given remoteType (e.g. "github", "s3")
21
+ * via registerResolver(), and the core upload()/download() functions delegate to it.
22
+ */
23
+ export class EmbeddingsService {
24
+ private resolvers = new Map<string, EmbeddingsResolver>();
25
+
26
+ registerResolver(remoteType: string, resolver: EmbeddingsResolver): void {
27
+ this.resolvers.set(remoteType, resolver);
28
+ }
29
+
30
+ hasResolver(remoteType: string): boolean {
31
+ return this.resolvers.has(remoteType);
32
+ }
33
+
34
+ async download(
35
+ remoteType: string,
36
+ remote: string,
37
+ filePath: string,
38
+ destinationPath: string
39
+ ): Promise<void> {
40
+ const resolver = this.resolvers.get(remoteType);
41
+ if (!resolver) {
42
+ throw new Error(
43
+ `No resolver registered for remoteType: "${remoteType}". ` +
44
+ `Install and configure the appropriate knowhow module (e.g. @tyvm/knowhow-module-github).`
45
+ );
46
+ }
47
+ await resolver.download(remote, filePath, destinationPath);
48
+ }
49
+
50
+ async upload(
51
+ remoteType: string,
52
+ localPath: string,
53
+ remote: string,
54
+ remoteKey: string
55
+ ): Promise<void> {
56
+ const resolver = this.resolvers.get(remoteType);
57
+ if (!resolver) {
58
+ throw new Error(
59
+ `No resolver registered for remoteType: "${remoteType}". ` +
60
+ `Install and configure the appropriate knowhow module (e.g. @tyvm/knowhow-module-s3).`
61
+ );
62
+ }
63
+ if (!resolver.upload) {
64
+ throw new Error(
65
+ `Resolver for remoteType: "${remoteType}" does not support uploads.`
66
+ );
67
+ }
68
+ await resolver.upload(localPath, remote, remoteKey);
69
+ }
70
+ }
@@ -1,4 +1,4 @@
1
- import axios from "axios";
1
+ import http from "../utils/http";
2
2
  import fs from "fs";
3
3
  import { Message } from "../clients/types";
4
4
  import path from "path";
@@ -110,7 +110,7 @@ export const KNOWHOW_API_URL =
110
110
  process.env.KNOWHOW_API_URL || "https://api.knowhow.tyvm.ai";
111
111
 
112
112
  export class KnowhowSimpleClient {
113
- headers = {};
113
+ headers: Record<string, string> = {};
114
114
  jwtValidated = false;
115
115
 
116
116
  constructor(
@@ -156,7 +156,7 @@ export class KnowhowSimpleClient {
156
156
  throw new Error("No JWT found. Please login first.");
157
157
  }
158
158
 
159
- return axios.get(`${this.baseUrl}/api/users/me`, {
159
+ return http.get(`${this.baseUrl}/api/users/me`, {
160
160
  headers: this.headers,
161
161
  });
162
162
  }
@@ -164,7 +164,7 @@ export class KnowhowSimpleClient {
164
164
  async getPresignedUploadUrl(source: Config["embedSources"][0]) {
165
165
  await this.checkJwt();
166
166
  const id = source.remoteId;
167
- const presignedUrlResp = await axios.post(
167
+ const presignedUrlResp = await http.post(
168
168
  `${this.baseUrl}/api/org-embeddings/${id}/upload`,
169
169
  {},
170
170
  {
@@ -181,7 +181,7 @@ export class KnowhowSimpleClient {
181
181
  async getPresignedDownloadUrl(source: Config["embedSources"][0]) {
182
182
  await this.checkJwt();
183
183
  const id = source.remoteId;
184
- const presignedUrlResp = await axios.post(
184
+ const presignedUrlResp = await http.post(
185
185
  `${this.baseUrl}/api/org-embeddings/${id}/download`,
186
186
  {},
187
187
  {
@@ -203,7 +203,7 @@ export class KnowhowSimpleClient {
203
203
  }
204
204
  ) {
205
205
  await this.checkJwt();
206
- return axios.put(
206
+ return http.put(
207
207
  `${this.baseUrl}/api/org-embeddings/${id}`,
208
208
  data,
209
209
  {
@@ -214,7 +214,7 @@ export class KnowhowSimpleClient {
214
214
 
215
215
  async createChatCompletion(options: CompletionOptions) {
216
216
  await this.checkJwt();
217
- return axios.post<CompletionResponse>(
217
+ return http.post<CompletionResponse>(
218
218
  `${this.baseUrl}/api/proxy/v1/chat/completions`,
219
219
  options,
220
220
  {
@@ -225,7 +225,7 @@ export class KnowhowSimpleClient {
225
225
 
226
226
  async createEmbedding(options: EmbeddingOptions) {
227
227
  await this.checkJwt();
228
- return axios.post<EmbeddingResponse>(
228
+ return http.post<EmbeddingResponse>(
229
229
  `${this.baseUrl}/api/proxy/v1/embeddings`,
230
230
  options,
231
231
  {
@@ -236,7 +236,7 @@ export class KnowhowSimpleClient {
236
236
 
237
237
  async getModels() {
238
238
  await this.checkJwt();
239
- return axios.get(`${this.baseUrl}/api/proxy/v1/models?type=all`, {
239
+ return http.get(`${this.baseUrl}/api/proxy/v1/models?type=all`, {
240
240
  headers: this.headers,
241
241
  });
242
242
  }
@@ -262,7 +262,7 @@ export class KnowhowSimpleClient {
262
262
  if (options.temperature != null)
263
263
  formData.append("temperature", String(options.temperature));
264
264
 
265
- return axios.post<AudioTranscriptionResponse>(
265
+ return http.post<AudioTranscriptionResponse>(
266
266
  `${this.baseUrl}/api/proxy/v1/audio/transcriptions`,
267
267
  formData,
268
268
  { headers: { ...this.headers } }
@@ -271,7 +271,7 @@ export class KnowhowSimpleClient {
271
271
 
272
272
  async createAudioGeneration(options: AudioGenerationOptions) {
273
273
  await this.checkJwt();
274
- return axios.post<AudioGenerationResponse>(
274
+ return http.post<AudioGenerationResponse>(
275
275
  `${this.baseUrl}/api/proxy/v1/audio/generations`,
276
276
  options,
277
277
  { headers: this.headers }
@@ -280,7 +280,7 @@ export class KnowhowSimpleClient {
280
280
 
281
281
  async createImageGeneration(options: ImageGenerationOptions) {
282
282
  await this.checkJwt();
283
- return axios.post<ImageGenerationResponse>(
283
+ return http.post<ImageGenerationResponse>(
284
284
  `${this.baseUrl}/api/proxy/v1/images/generations`,
285
285
  options,
286
286
  { headers: this.headers }
@@ -289,7 +289,7 @@ export class KnowhowSimpleClient {
289
289
 
290
290
  async createVideoGeneration(options: VideoGenerationOptions) {
291
291
  await this.checkJwt();
292
- return axios.post<VideoGenerationResponse>(
292
+ return http.post<VideoGenerationResponse>(
293
293
  `${this.baseUrl}/api/proxy/v1/videos/generations`,
294
294
  options,
295
295
  { headers: this.headers }
@@ -299,7 +299,7 @@ export class KnowhowSimpleClient {
299
299
  async getVideoStatus(options: VideoStatusOptions) {
300
300
  await this.checkJwt();
301
301
  const { jobId, ...rest } = options;
302
- return axios.get<VideoStatusResponse>(
302
+ return http.get<VideoStatusResponse>(
303
303
  `${this.baseUrl}/api/proxy/v1/videos/${jobId}/status`,
304
304
  { headers: this.headers, params: rest }
305
305
  );
@@ -308,7 +308,7 @@ export class KnowhowSimpleClient {
308
308
  async downloadVideo(options: FileDownloadOptions) {
309
309
  await this.checkJwt();
310
310
  const { fileId } = options;
311
- return axios.get<ArrayBuffer>(
311
+ return http.get<ArrayBuffer>(
312
312
  `${this.baseUrl}/api/proxy/v1/videos/${fileId}/content`,
313
313
  { headers: this.headers, responseType: "arraybuffer" }
314
314
  );
@@ -323,7 +323,7 @@ export class KnowhowSimpleClient {
323
323
  fileName: options.fileName,
324
324
  displayName: options.displayName,
325
325
  };
326
- return axios.post<FileUploadResponse>(
326
+ return http.post<FileUploadResponse>(
327
327
  `${this.baseUrl}/api/proxy/v1/files`,
328
328
  body,
329
329
  { headers: this.headers }
@@ -333,7 +333,7 @@ export class KnowhowSimpleClient {
333
333
  async downloadFile(options: FileDownloadOptions) {
334
334
  await this.checkJwt();
335
335
  const { fileId } = options;
336
- return axios.get<ArrayBuffer>(
336
+ return http.get<ArrayBuffer>(
337
337
  `${this.baseUrl}/api/proxy/v1/files/${fileId}/content`,
338
338
  { headers: this.headers, responseType: "arraybuffer" }
339
339
  );
@@ -341,7 +341,7 @@ export class KnowhowSimpleClient {
341
341
 
342
342
  async createChatTask(request: CreateMessageTaskRequest) {
343
343
  await this.checkJwt();
344
- return axios.post<CreateMessageTaskResponse>(
344
+ return http.post<CreateMessageTaskResponse>(
345
345
  `${this.baseUrl}/api/chat/tasks`,
346
346
  request,
347
347
  {
@@ -352,7 +352,7 @@ export class KnowhowSimpleClient {
352
352
 
353
353
  async updateChatTask(taskId: string, updates: UpdateOrgTaskRequest) {
354
354
  await this.checkJwt();
355
- return axios.put<UpdateOrgTaskResponse>(
355
+ return http.put<UpdateOrgTaskResponse>(
356
356
  `${this.baseUrl}/api/chat/tasks/${taskId}`,
357
357
  updates,
358
358
  {
@@ -370,7 +370,7 @@ export class KnowhowSimpleClient {
370
370
  */
371
371
  async getTaskDetails(taskId: string) {
372
372
  await this.checkJwt();
373
- return axios.get<TaskDetailsResponse>(
373
+ return http.get<TaskDetailsResponse>(
374
374
  `${this.baseUrl}/api/org-agent-tasks/${taskId}`,
375
375
  {
376
376
  headers: this.headers,
@@ -383,7 +383,7 @@ export class KnowhowSimpleClient {
383
383
  */
384
384
  async getPendingMessages(taskId: string) {
385
385
  await this.checkJwt();
386
- return axios.get<PendingMessage[]>(
386
+ return http.get<PendingMessage[]>(
387
387
  `${this.baseUrl}/api/org-agent-tasks/${taskId}/pending-messages`,
388
388
  {
389
389
  headers: this.headers,
@@ -396,7 +396,7 @@ export class KnowhowSimpleClient {
396
396
  */
397
397
  async markMessagesAsProcessed(taskId: string, messageIds: string[]) {
398
398
  await this.checkJwt();
399
- return axios.post<MarkProcessedResponse>(
399
+ return http.post<MarkProcessedResponse>(
400
400
  `${this.baseUrl}/api/org-agent-tasks/${taskId}/pending-messages/mark-processed`,
401
401
  { messageIds },
402
402
  {
@@ -414,7 +414,7 @@ export class KnowhowSimpleClient {
414
414
  role: "user" | "system" = "user"
415
415
  ) {
416
416
  await this.checkJwt();
417
- return axios.post<SendMessageResponse>(
417
+ return http.post<SendMessageResponse>(
418
418
  `${this.baseUrl}/api/org-agent-tasks/${taskId}/messages`,
419
419
  { message, role },
420
420
  {
@@ -428,7 +428,7 @@ export class KnowhowSimpleClient {
428
428
  */
429
429
  async pauseAgent(taskId: string) {
430
430
  await this.checkJwt();
431
- return axios.post<StatusResponse>(
431
+ return http.post<StatusResponse>(
432
432
  `${this.baseUrl}/api/org-agent-tasks/${taskId}/pause`,
433
433
  {},
434
434
  {
@@ -442,7 +442,7 @@ export class KnowhowSimpleClient {
442
442
  */
443
443
  async resumeAgent(taskId: string) {
444
444
  await this.checkJwt();
445
- return axios.post<StatusResponse>(
445
+ return http.post<StatusResponse>(
446
446
  `${this.baseUrl}/api/org-agent-tasks/${taskId}/resume`,
447
447
  {},
448
448
  {
@@ -464,7 +464,7 @@ export class KnowhowSimpleClient {
464
464
  */
465
465
  async killAgent(taskId: string) {
466
466
  await this.checkJwt();
467
- return axios.post<StatusResponse>(
467
+ return http.post<StatusResponse>(
468
468
  `${this.baseUrl}/api/org-agent-tasks/${taskId}/kill`,
469
469
  {},
470
470
  {
@@ -483,7 +483,7 @@ export class KnowhowSimpleClient {
483
483
  */
484
484
  async listOrgFiles() {
485
485
  await this.checkJwt();
486
- return axios.get<
486
+ return http.get<
487
487
  { id: string; fileName: string; folderPath: string; name: string }[]
488
488
  >(`${this.baseUrl}/api/org-files`, { headers: this.headers });
489
489
  }
@@ -493,7 +493,7 @@ export class KnowhowSimpleClient {
493
493
  */
494
494
  async createOrgFile(fileName: string, folderPath: string) {
495
495
  await this.checkJwt();
496
- return axios.post<{
496
+ return http.post<{
497
497
  id: string;
498
498
  fileName: string;
499
499
  folderPath: string;
@@ -510,7 +510,7 @@ export class KnowhowSimpleClient {
510
510
  */
511
511
  async getOrgFileText(fileId: string) {
512
512
  await this.checkJwt();
513
- return axios.get<string>(`${this.baseUrl}/api/org-files/${fileId}/text`, {
513
+ return http.get<string>(`${this.baseUrl}/api/org-files/${fileId}/text`, {
514
514
  headers: this.headers,
515
515
  params: { reading: "true" },
516
516
  });
@@ -521,7 +521,7 @@ export class KnowhowSimpleClient {
521
521
  */
522
522
  async updateOrgFileText(fileId: string, text: string) {
523
523
  await this.checkJwt();
524
- return axios.put(
524
+ return http.put(
525
525
  `${this.baseUrl}/api/org-files/${fileId}/text`,
526
526
  { text },
527
527
  { headers: this.headers }
@@ -590,7 +590,7 @@ export class KnowhowSimpleClient {
590
590
  }
591
591
 
592
592
  // Get download URL using the file ID
593
- const response = await axios.post<{ downloadUrl: string }>(
593
+ const response = await http.post<{ downloadUrl: string }>(
594
594
  `${this.baseUrl}/api/org-files/download/${file.id}`,
595
595
  {},
596
596
  { headers: this.headers }
@@ -609,7 +609,7 @@ export class KnowhowSimpleClient {
609
609
  throw new Error(`File not found: ${filePath}`);
610
610
  }
611
611
 
612
- await axios.post(`${this.baseUrl}/api/org-files/upload/${file.id}/complete`, {}, { headers: this.headers });
612
+ await http.post(`${this.baseUrl}/api/org-files/upload/${file.id}/complete`, {}, { headers: this.headers });
613
613
  }
614
614
 
615
615
  /**
@@ -627,7 +627,7 @@ export class KnowhowSimpleClient {
627
627
  const fileName = lastSlash >= 0 ? filePath.substring(lastSlash + 1) : filePath;
628
628
 
629
629
  // Get upload URL using the file ID
630
- const response = await axios.post<{ uploadUrl: string }>(
630
+ const response = await http.post<{ uploadUrl: string }>(
631
631
  `${this.baseUrl}/api/org-files/upload/${file.id}`,
632
632
  { fileName },
633
633
  { headers: this.headers }
@@ -641,7 +641,7 @@ export class KnowhowSimpleClient {
641
641
  */
642
642
  async getGitCredential(repo: string): Promise<GitCredentialResponse> {
643
643
  await this.checkJwt();
644
- const response = await axios.post<GitCredentialResponse>(
644
+ const response = await http.post<GitCredentialResponse>(
645
645
  `${this.baseUrl}/api/github/git-credential`,
646
646
  { repo },
647
647
  { headers: this.headers }