@imisbahk/hive 0.1.3 → 0.1.4

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 (81) hide show
  1. package/.gitattributes +7 -0
  2. package/.rocket/README.md +9 -9
  3. package/dist/agent/agent.d.ts +4 -0
  4. package/dist/agent/agent.d.ts.map +1 -1
  5. package/dist/agent/agent.js +40 -4
  6. package/dist/agent/agent.js.map +1 -1
  7. package/dist/cli/commands/chat.d.ts.map +1 -1
  8. package/dist/cli/commands/chat.js +642 -12
  9. package/dist/cli/commands/chat.js.map +1 -1
  10. package/dist/cli/commands/memory.d.ts +3 -0
  11. package/dist/cli/commands/memory.d.ts.map +1 -0
  12. package/dist/cli/commands/memory.js +104 -0
  13. package/dist/cli/commands/memory.js.map +1 -0
  14. package/dist/cli/index.js +3 -1
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/providers/api-key.js +1 -1
  17. package/dist/providers/api-key.js.map +1 -1
  18. package/dist/providers/base.js +1 -1
  19. package/dist/providers/base.js.map +1 -1
  20. package/dist/providers/openai-compatible.js +2 -2
  21. package/dist/providers/openai-compatible.js.map +1 -1
  22. package/dist/storage/db.d.ts +31 -2
  23. package/dist/storage/db.d.ts.map +1 -1
  24. package/dist/storage/db.js +165 -3
  25. package/dist/storage/db.js.map +1 -1
  26. package/dist/storage/schema.d.ts +12 -1
  27. package/dist/storage/schema.d.ts.map +1 -1
  28. package/dist/storage/schema.js +29 -1
  29. package/dist/storage/schema.js.map +1 -1
  30. package/package.json +8 -2
  31. package/.github/workflows/publish.yml +0 -31
  32. package/.rocket/ARCHITECTURE.md +0 -7
  33. package/.rocket/SYMBOLS.md +0 -425
  34. package/001-local-first-storage.md +0 -43
  35. package/003-memory-architechture.md +0 -71
  36. package/CONTRIBUTING.md +0 -150
  37. package/FEATURES.md +0 -63
  38. package/index.md +0 -16
  39. package/prompts/Behaviour.md +0 -23
  40. package/prompts/Browser.md +0 -13
  41. package/prompts/Code.md +0 -12
  42. package/prompts/Debugging.md +0 -15
  43. package/prompts/Execution.md +0 -13
  44. package/prompts/Memory.md +0 -11
  45. package/prompts/Planning.md +0 -13
  46. package/prompts/Product.md +0 -14
  47. package/prompts/Review.md +0 -15
  48. package/prompts/Safety.md +0 -12
  49. package/prompts/Search.md +0 -14
  50. package/prompts/System.md +0 -6
  51. package/prompts/Tools.md +0 -14
  52. package/prompts/Writing.md +0 -13
  53. package/releases/v1/v0.1/RELEASE-NOTES.md +0 -101
  54. package/src/agent/agent.ts +0 -595
  55. package/src/agent/index.ts +0 -2
  56. package/src/browser/browser.ts +0 -410
  57. package/src/cli/commands/chat.ts +0 -864
  58. package/src/cli/commands/config.ts +0 -610
  59. package/src/cli/commands/doctor.ts +0 -655
  60. package/src/cli/commands/init.ts +0 -288
  61. package/src/cli/commands/nuke.ts +0 -64
  62. package/src/cli/commands/status.ts +0 -170
  63. package/src/cli/helpers/providerPrompts.ts +0 -192
  64. package/src/cli/index.ts +0 -68
  65. package/src/cli/theme.ts +0 -88
  66. package/src/cli/ui.ts +0 -127
  67. package/src/providers/anthropic.ts +0 -146
  68. package/src/providers/api-key.ts +0 -23
  69. package/src/providers/base.ts +0 -409
  70. package/src/providers/google.ts +0 -21
  71. package/src/providers/groq.ts +0 -21
  72. package/src/providers/index.ts +0 -65
  73. package/src/providers/mistral.ts +0 -21
  74. package/src/providers/ollama.ts +0 -22
  75. package/src/providers/openai-compatible.ts +0 -82
  76. package/src/providers/openai.ts +0 -21
  77. package/src/providers/openrouter.ts +0 -21
  78. package/src/providers/together.ts +0 -21
  79. package/src/storage/db.ts +0 -476
  80. package/src/storage/schema.ts +0 -116
  81. package/tsconfig.json +0 -51
@@ -1,410 +0,0 @@
1
- import { chromium } from "playwright";
2
- import fetch from "node-fetch";
3
-
4
- const MAX_CONTENT_CHARS = 8000;
5
- const SEARCH_RESULT_LIMIT = 5;
6
- const SEARCH_SNIPPET_CHARS = 280;
7
- const SEARCH_WINDOW_CHARS = 2600;
8
- const BROWSER_TIMEOUT_MS = 30000;
9
- const DEFAULT_REQUEST_HEADERS = {
10
- "accept-language": "en-US,en;q=0.9",
11
- "user-agent":
12
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36",
13
- };
14
-
15
- export interface SearchResult {
16
- title: string;
17
- url: string;
18
- snippet: string;
19
- }
20
-
21
- export async function openPage(url: string): Promise<string> {
22
- try {
23
- return await openPageWithBrowser(url);
24
- } catch {
25
- return openPageWithHttp(url);
26
- }
27
- }
28
-
29
- export async function extractContent(url: string): Promise<string> {
30
- return openPage(url);
31
- }
32
-
33
- export async function search(query: string): Promise<SearchResult[]> {
34
- const trimmedQuery = query.trim();
35
- if (trimmedQuery.length === 0) {
36
- return [];
37
- }
38
-
39
- let browserResults: SearchResult[] = [];
40
- try {
41
- const browser = await launchBrowser();
42
-
43
- try {
44
- const page = await browser.newPage();
45
- const searchUrls = [
46
- `https://duckduckgo.com/html/?q=${encodeURIComponent(trimmedQuery)}`,
47
- `https://www.google.com/search?q=${encodeURIComponent(trimmedQuery)}&hl=en&num=10&pws=0`,
48
- ];
49
-
50
- for (const searchUrl of searchUrls) {
51
- try {
52
- await page.goto(searchUrl, {
53
- waitUntil: "domcontentloaded",
54
- timeout: BROWSER_TIMEOUT_MS,
55
- });
56
- } catch {
57
- continue;
58
- }
59
-
60
- const html = await page.content();
61
- const results =
62
- searchUrl.includes("duckduckgo.com")
63
- ? parseDuckDuckGoResults(html)
64
- : parseGoogleResults(html);
65
-
66
- if (results.length > 0) {
67
- browserResults = results;
68
- break;
69
- }
70
- }
71
- } finally {
72
- await browser.close();
73
- }
74
- } catch {
75
- // Continue to HTTP fallback below.
76
- }
77
-
78
- if (browserResults.length > 0) {
79
- return browserResults.slice(0, SEARCH_RESULT_LIMIT);
80
- }
81
-
82
- const fallbackResults = await searchWithHttp(trimmedQuery);
83
- return fallbackResults.slice(0, SEARCH_RESULT_LIMIT);
84
- }
85
-
86
- async function launchBrowser() {
87
- try {
88
- return await chromium.launch({ headless: true });
89
- } catch {
90
- return chromium.launch({ headless: true, channel: "chrome" });
91
- }
92
- }
93
-
94
- async function openPageWithBrowser(url: string): Promise<string> {
95
- const browser = await launchBrowser();
96
-
97
- try {
98
- const page = await browser.newPage();
99
- await page.goto(url, { waitUntil: "domcontentloaded", timeout: BROWSER_TIMEOUT_MS });
100
- const html = await page.content();
101
- return extractReadableText(html);
102
- } finally {
103
- await browser.close();
104
- }
105
- }
106
-
107
- async function openPageWithHttp(url: string): Promise<string> {
108
- const html = await fetchHtml(url);
109
- return extractReadableText(html);
110
- }
111
-
112
- async function searchWithHttp(query: string): Promise<SearchResult[]> {
113
- const searchUrls = [
114
- `https://duckduckgo.com/html/?q=${encodeURIComponent(query)}`,
115
- `https://www.google.com/search?q=${encodeURIComponent(query)}&hl=en&num=10&pws=0`,
116
- ];
117
- let lastError: unknown = null;
118
- let hadSuccessfulRequest = false;
119
-
120
- for (const searchUrl of searchUrls) {
121
- let html: string;
122
- try {
123
- html = await fetchHtml(searchUrl);
124
- } catch (error) {
125
- lastError = error;
126
- continue;
127
- }
128
- hadSuccessfulRequest = true;
129
-
130
- const results =
131
- searchUrl.includes("duckduckgo.com")
132
- ? parseDuckDuckGoResults(html)
133
- : parseGoogleResults(html);
134
- if (results.length > 0) {
135
- return results;
136
- }
137
- }
138
-
139
- if (!hadSuccessfulRequest && lastError) {
140
- throw lastError;
141
- }
142
-
143
- return [];
144
- }
145
-
146
- async function fetchHtml(url: string): Promise<string> {
147
- const response = await fetch(url, {
148
- headers: DEFAULT_REQUEST_HEADERS,
149
- });
150
-
151
- if (!response.ok) {
152
- throw new Error(`Request failed: HTTP ${response.status} ${response.statusText}`);
153
- }
154
-
155
- return response.text();
156
- }
157
-
158
- function parseGoogleResults(html: string): SearchResult[] {
159
- const results: SearchResult[] = [];
160
- const seenUrls = new Set<string>();
161
- const anchorPattern = /<a\b[^>]*href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/gi;
162
-
163
- let match: RegExpExecArray | null = anchorPattern.exec(html);
164
- while (match && results.length < SEARCH_RESULT_LIMIT) {
165
- const rawHref = decodeHtmlEntities(match[1]);
166
- const titleMatch = match[2].match(/<h3\b[^>]*>([\s\S]*?)<\/h3>/i);
167
-
168
- if (titleMatch) {
169
- const parsedUrl = normalizeGoogleResultUrl(rawHref);
170
- if (parsedUrl && !seenUrls.has(parsedUrl)) {
171
- const title = cleanupText(titleMatch[1]);
172
- if (title.length > 0) {
173
- const snippet = extractSnippetForMatch(html, match.index, [
174
- /<(?:div|span)\b[^>]*class="[^"]*(?:VwiC3b|aCOpRe|s3v9rd)[^"]*"[^>]*>([\s\S]*?)<\/(?:div|span)>/i,
175
- /<div\b[^>]*>([\s\S]{40,900}?)<\/div>/i,
176
- ]);
177
- results.push({
178
- title,
179
- url: parsedUrl,
180
- snippet,
181
- });
182
- seenUrls.add(parsedUrl);
183
- }
184
- }
185
- }
186
-
187
- match = anchorPattern.exec(html);
188
- }
189
-
190
- return results;
191
- }
192
-
193
- function parseDuckDuckGoResults(html: string): SearchResult[] {
194
- const results: SearchResult[] = [];
195
- const seenUrls = new Set<string>();
196
- const anchorPattern =
197
- /<a\b[^>]*class="[^"]*(?:result__a|result-link)[^"]*"[^>]*href="([^"]+)"[^>]*>([\s\S]*?)<\/a>/gi;
198
-
199
- let match: RegExpExecArray | null = anchorPattern.exec(html);
200
- while (match && results.length < SEARCH_RESULT_LIMIT) {
201
- const rawHref = decodeHtmlEntities(match[1]);
202
- const parsedUrl = normalizeDuckDuckGoResultUrl(rawHref);
203
-
204
- if (parsedUrl && !seenUrls.has(parsedUrl)) {
205
- const title = cleanupText(match[2]);
206
- if (title.length > 0) {
207
- const snippet = extractSnippetForMatch(html, match.index, [
208
- /<(?:a|div|span)\b[^>]*class="[^"]*(?:result__snippet|result-snippet)[^"]*"[^>]*>([\s\S]*?)<\/(?:a|div|span)>/i,
209
- /<div\b[^>]*>([\s\S]{40,900}?)<\/div>/i,
210
- ]);
211
- results.push({
212
- title,
213
- url: parsedUrl,
214
- snippet,
215
- });
216
- seenUrls.add(parsedUrl);
217
- }
218
- }
219
-
220
- match = anchorPattern.exec(html);
221
- }
222
-
223
- return results;
224
- }
225
-
226
- function normalizeGoogleResultUrl(rawHref: string): string | null {
227
- if (!rawHref) {
228
- return null;
229
- }
230
-
231
- if (rawHref.startsWith("/url?")) {
232
- const queryString = rawHref.split("?")[1] ?? "";
233
- const params = new URLSearchParams(queryString);
234
- const q = params.get("q") ?? params.get("url");
235
- if (!q) {
236
- return null;
237
- }
238
- return normalizeExternalUrl(q);
239
- }
240
-
241
- if (!/^https?:\/\//i.test(rawHref)) {
242
- return null;
243
- }
244
-
245
- return normalizeExternalUrl(rawHref);
246
- }
247
-
248
- function normalizeDuckDuckGoResultUrl(rawHref: string): string | null {
249
- if (!rawHref) {
250
- return null;
251
- }
252
-
253
- if (rawHref.startsWith("//duckduckgo.com/l/?")) {
254
- return extractDuckDuckGoRedirectTarget(`https:${rawHref}`);
255
- }
256
-
257
- if (rawHref.startsWith("/l/?")) {
258
- return extractDuckDuckGoRedirectTarget(`https://duckduckgo.com${rawHref}`);
259
- }
260
-
261
- if (/^https?:\/\/duckduckgo\.com\/l\/\?/i.test(rawHref)) {
262
- return extractDuckDuckGoRedirectTarget(rawHref);
263
- }
264
-
265
- if (rawHref.startsWith("//")) {
266
- return normalizeExternalUrl(`https:${rawHref}`);
267
- }
268
-
269
- if (!/^https?:\/\//i.test(rawHref)) {
270
- return null;
271
- }
272
-
273
- return normalizeExternalUrl(rawHref);
274
- }
275
-
276
- function extractDuckDuckGoRedirectTarget(redirectUrl: string): string | null {
277
- try {
278
- const parsed = new URL(redirectUrl);
279
- const target = parsed.searchParams.get("uddg") ?? parsed.searchParams.get("rut");
280
- if (!target) {
281
- return null;
282
- }
283
-
284
- return normalizeExternalUrl(target);
285
- } catch {
286
- return null;
287
- }
288
- }
289
-
290
- function normalizeExternalUrl(input: string): string | null {
291
- try {
292
- const url = new URL(input);
293
- const hostname = url.hostname.toLowerCase();
294
-
295
- if (
296
- hostname.endsWith(".google.com") ||
297
- hostname === "google.com" ||
298
- hostname.endsWith(".duckduckgo.com") ||
299
- hostname === "duckduckgo.com"
300
- ) {
301
- return null;
302
- }
303
-
304
- return url.toString();
305
- } catch {
306
- return null;
307
- }
308
- }
309
-
310
- function extractSnippetForMatch(
311
- html: string,
312
- startIndex: number,
313
- patterns: RegExp[],
314
- ): string {
315
- const window = html.slice(startIndex, startIndex + SEARCH_WINDOW_CHARS);
316
- let snippetMatch: RegExpMatchArray | null = null;
317
-
318
- for (const pattern of patterns) {
319
- snippetMatch = window.match(pattern);
320
- if (snippetMatch) {
321
- break;
322
- }
323
- }
324
-
325
- if (!snippetMatch) {
326
- return "";
327
- }
328
-
329
- const snippet = cleanupText(snippetMatch[1]);
330
- if (snippet.length <= SEARCH_SNIPPET_CHARS) {
331
- return snippet;
332
- }
333
-
334
- return `${snippet.slice(0, SEARCH_SNIPPET_CHARS - 3)}...`;
335
- }
336
-
337
- function extractReadableText(html: string): string {
338
- const body = firstCapture(html, /<body\b[^>]*>([\s\S]*?)<\/body>/i) ?? html;
339
- const withoutNoise = stripSections(body, ["script", "style", "noscript", "svg"]);
340
- const prioritized =
341
- firstCapture(withoutNoise, /<main\b[^>]*>([\s\S]*?)<\/main>/i) ??
342
- firstCapture(withoutNoise, /<article\b[^>]*>([\s\S]*?)<\/article>/i) ??
343
- withoutNoise;
344
- const withoutLayout = stripSections(prioritized, [
345
- "nav",
346
- "header",
347
- "footer",
348
- "aside",
349
- "form",
350
- ]);
351
- const text = cleanupText(withoutLayout);
352
-
353
- if (text.length <= MAX_CONTENT_CHARS) {
354
- return text;
355
- }
356
-
357
- return `${text.slice(0, MAX_CONTENT_CHARS - 3)}...`;
358
- }
359
-
360
- function firstCapture(value: string, pattern: RegExp): string | null {
361
- const match = value.match(pattern);
362
- return match?.[1] ?? null;
363
- }
364
-
365
- function stripSections(value: string, tagNames: string[]): string {
366
- let stripped = value;
367
- for (const tagName of tagNames) {
368
- const pattern = new RegExp(`<${tagName}\\b[^>]*>[\\s\\S]*?<\\/${tagName}>`, "gi");
369
- stripped = stripped.replace(pattern, " ");
370
- }
371
- return stripped;
372
- }
373
-
374
- function cleanupText(value: string): string {
375
- const withoutTags = value.replace(/<[^>]+>/g, " ");
376
- const decoded = decodeHtmlEntities(withoutTags);
377
- const normalized = decoded
378
- .replace(/\r/g, " ")
379
- .replace(/\n+/g, "\n")
380
- .replace(/[ \t]+/g, " ")
381
- .replace(/[ \t]*\n[ \t]*/g, "\n")
382
- .trim();
383
-
384
- return normalized;
385
- }
386
-
387
- function decodeHtmlEntities(value: string): string {
388
- const namedEntities: Record<string, string> = {
389
- amp: "&",
390
- lt: "<",
391
- gt: ">",
392
- quot: "\"",
393
- apos: "'",
394
- nbsp: " ",
395
- };
396
-
397
- return value.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z]+);/g, (_, entity: string) => {
398
- if (entity.startsWith("#x") || entity.startsWith("#X")) {
399
- const codePoint = Number.parseInt(entity.slice(2), 16);
400
- return Number.isNaN(codePoint) ? "" : String.fromCodePoint(codePoint);
401
- }
402
-
403
- if (entity.startsWith("#")) {
404
- const codePoint = Number.parseInt(entity.slice(1), 10);
405
- return Number.isNaN(codePoint) ? "" : String.fromCodePoint(codePoint);
406
- }
407
-
408
- return namedEntities[entity] ?? "";
409
- });
410
- }