recker 1.0.15 → 1.0.17-next.316500c

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 (166) hide show
  1. package/README.md +86 -97
  2. package/dist/ai/providers/anthropic.d.ts.map +1 -1
  3. package/dist/ai/providers/anthropic.js +4 -1
  4. package/dist/ai/providers/base.d.ts.map +1 -1
  5. package/dist/ai/providers/base.js +7 -2
  6. package/dist/ai/rate-limiter.d.ts.map +1 -1
  7. package/dist/ai/rate-limiter.js +4 -1
  8. package/dist/bench/generator.d.ts.map +1 -1
  9. package/dist/bench/generator.js +8 -3
  10. package/dist/bench/stats.d.ts +15 -1
  11. package/dist/bench/stats.d.ts.map +1 -1
  12. package/dist/bench/stats.js +117 -5
  13. package/dist/cache/memory-storage.d.ts.map +1 -1
  14. package/dist/cache/memory-storage.js +3 -2
  15. package/dist/cli/handler.js +14 -14
  16. package/dist/cli/index.js +602 -48
  17. package/dist/cli/presets.js +5 -5
  18. package/dist/cli/tui/ai-chat.js +10 -10
  19. package/dist/cli/tui/load-dashboard.d.ts.map +1 -1
  20. package/dist/cli/tui/load-dashboard.js +127 -32
  21. package/dist/cli/tui/scroll-buffer.d.ts +43 -0
  22. package/dist/cli/tui/scroll-buffer.d.ts.map +1 -0
  23. package/dist/cli/tui/scroll-buffer.js +162 -0
  24. package/dist/cli/tui/search-panel.d.ts +41 -0
  25. package/dist/cli/tui/search-panel.d.ts.map +1 -0
  26. package/dist/cli/tui/search-panel.js +420 -0
  27. package/dist/cli/tui/shell.d.ts +14 -0
  28. package/dist/cli/tui/shell.d.ts.map +1 -1
  29. package/dist/cli/tui/shell.js +424 -46
  30. package/dist/cli/tui/websocket.js +17 -17
  31. package/dist/contract/index.d.ts.map +1 -1
  32. package/dist/contract/index.js +3 -2
  33. package/dist/core/client.d.ts.map +1 -1
  34. package/dist/core/client.js +18 -26
  35. package/dist/core/errors.d.ts +109 -1
  36. package/dist/core/errors.d.ts.map +1 -1
  37. package/dist/core/errors.js +214 -1
  38. package/dist/core/request-promise.d.ts.map +1 -1
  39. package/dist/core/request-promise.js +5 -6
  40. package/dist/core/response.d.ts.map +1 -1
  41. package/dist/core/response.js +5 -6
  42. package/dist/dns/index.d.ts +1 -0
  43. package/dist/dns/index.d.ts.map +1 -1
  44. package/dist/dns/index.js +1 -0
  45. package/dist/dns/propagation.d.ts +21 -0
  46. package/dist/dns/propagation.d.ts.map +1 -0
  47. package/dist/dns/propagation.js +169 -0
  48. package/dist/index.d.ts +3 -0
  49. package/dist/index.d.ts.map +1 -1
  50. package/dist/index.js +3 -0
  51. package/dist/mcp/client.d.ts.map +1 -1
  52. package/dist/mcp/client.js +10 -11
  53. package/dist/mcp/embeddings-loader.d.ts +18 -0
  54. package/dist/mcp/embeddings-loader.d.ts.map +1 -0
  55. package/dist/mcp/embeddings-loader.js +162 -0
  56. package/dist/mcp/geoip-loader.d.ts +11 -0
  57. package/dist/mcp/geoip-loader.d.ts.map +1 -0
  58. package/dist/mcp/geoip-loader.js +107 -0
  59. package/dist/mcp/index.d.ts +1 -0
  60. package/dist/mcp/index.d.ts.map +1 -1
  61. package/dist/mcp/index.js +1 -0
  62. package/dist/mcp/ip-intel.d.ts +28 -0
  63. package/dist/mcp/ip-intel.d.ts.map +1 -0
  64. package/dist/mcp/ip-intel.js +209 -0
  65. package/dist/mcp/search/hybrid-search.d.ts.map +1 -1
  66. package/dist/mcp/search/hybrid-search.js +59 -38
  67. package/dist/mcp/search/math.d.ts.map +1 -1
  68. package/dist/mcp/search/math.js +5 -1
  69. package/dist/mcp/server.d.ts +6 -0
  70. package/dist/mcp/server.d.ts.map +1 -1
  71. package/dist/mcp/server.js +122 -2
  72. package/dist/plugins/compression.js +4 -2
  73. package/dist/plugins/har-player.d.ts.map +1 -1
  74. package/dist/plugins/har-player.js +8 -11
  75. package/dist/plugins/odata.d.ts.map +1 -1
  76. package/dist/plugins/odata.js +5 -2
  77. package/dist/presets/aws.d.ts +20 -0
  78. package/dist/presets/aws.d.ts.map +1 -0
  79. package/dist/presets/aws.js +68 -0
  80. package/dist/presets/azure.d.ts +42 -0
  81. package/dist/presets/azure.d.ts.map +1 -0
  82. package/dist/presets/azure.js +104 -0
  83. package/dist/presets/gcp.d.ts +35 -0
  84. package/dist/presets/gcp.d.ts.map +1 -0
  85. package/dist/presets/gcp.js +91 -0
  86. package/dist/presets/index.d.ts +10 -0
  87. package/dist/presets/index.d.ts.map +1 -1
  88. package/dist/presets/index.js +10 -0
  89. package/dist/presets/mailgun.d.ts +8 -0
  90. package/dist/presets/mailgun.d.ts.map +1 -0
  91. package/dist/presets/mailgun.js +20 -0
  92. package/dist/presets/meta.d.ts +11 -0
  93. package/dist/presets/meta.d.ts.map +1 -0
  94. package/dist/presets/meta.js +33 -0
  95. package/dist/presets/oracle.d.ts +20 -0
  96. package/dist/presets/oracle.d.ts.map +1 -0
  97. package/dist/presets/oracle.js +117 -0
  98. package/dist/presets/registry.d.ts.map +1 -1
  99. package/dist/presets/registry.js +100 -0
  100. package/dist/presets/sinch.d.ts +10 -0
  101. package/dist/presets/sinch.d.ts.map +1 -0
  102. package/dist/presets/sinch.js +39 -0
  103. package/dist/presets/tiktok.d.ts +11 -0
  104. package/dist/presets/tiktok.d.ts.map +1 -0
  105. package/dist/presets/tiktok.js +38 -0
  106. package/dist/presets/vultr.d.ts +6 -0
  107. package/dist/presets/vultr.d.ts.map +1 -0
  108. package/dist/presets/vultr.js +16 -0
  109. package/dist/presets/youtube.d.ts +6 -0
  110. package/dist/presets/youtube.d.ts.map +1 -0
  111. package/dist/presets/youtube.js +20 -0
  112. package/dist/protocols/ftp.d.ts.map +1 -1
  113. package/dist/protocols/ftp.js +69 -16
  114. package/dist/protocols/sftp.d.ts.map +1 -1
  115. package/dist/protocols/sftp.js +13 -3
  116. package/dist/protocols/telnet.d.ts.map +1 -1
  117. package/dist/protocols/telnet.js +25 -6
  118. package/dist/recker.d.ts +47 -0
  119. package/dist/recker.d.ts.map +1 -0
  120. package/dist/recker.js +99 -0
  121. package/dist/transport/base-udp.d.ts.map +1 -1
  122. package/dist/transport/base-udp.js +7 -4
  123. package/dist/transport/udp-response.d.ts.map +1 -1
  124. package/dist/transport/udp-response.js +10 -3
  125. package/dist/transport/udp.d.ts.map +1 -1
  126. package/dist/transport/udp.js +5 -1
  127. package/dist/transport/undici.d.ts.map +1 -1
  128. package/dist/transport/undici.js +75 -63
  129. package/dist/utils/agent-manager.d.ts +1 -0
  130. package/dist/utils/agent-manager.d.ts.map +1 -1
  131. package/dist/utils/agent-manager.js +11 -0
  132. package/dist/utils/client-pool.d.ts.map +1 -1
  133. package/dist/utils/client-pool.js +4 -1
  134. package/dist/utils/colors.d.ts +16 -0
  135. package/dist/utils/colors.d.ts.map +1 -1
  136. package/dist/utils/colors.js +16 -0
  137. package/dist/utils/dns-toolkit.d.ts +88 -1
  138. package/dist/utils/dns-toolkit.d.ts.map +1 -1
  139. package/dist/utils/dns-toolkit.js +704 -6
  140. package/dist/utils/doh.d.ts.map +1 -1
  141. package/dist/utils/doh.js +13 -16
  142. package/dist/utils/download.d.ts.map +1 -1
  143. package/dist/utils/download.js +10 -11
  144. package/dist/utils/rdap.d.ts +9 -0
  145. package/dist/utils/rdap.d.ts.map +1 -1
  146. package/dist/utils/rdap.js +78 -9
  147. package/dist/utils/security-grader.d.ts +47 -0
  148. package/dist/utils/security-grader.d.ts.map +1 -0
  149. package/dist/utils/security-grader.js +637 -0
  150. package/dist/utils/sparkline.d.ts +18 -0
  151. package/dist/utils/sparkline.d.ts.map +1 -0
  152. package/dist/utils/sparkline.js +55 -0
  153. package/dist/utils/sse.d.ts.map +1 -1
  154. package/dist/utils/sse.js +5 -6
  155. package/dist/utils/system-metrics.d.ts +26 -0
  156. package/dist/utils/system-metrics.d.ts.map +1 -0
  157. package/dist/utils/system-metrics.js +81 -0
  158. package/dist/utils/tls-inspector.d.ts +6 -0
  159. package/dist/utils/tls-inspector.d.ts.map +1 -1
  160. package/dist/utils/tls-inspector.js +35 -1
  161. package/dist/webrtc/index.d.ts.map +1 -1
  162. package/dist/webrtc/index.js +21 -7
  163. package/dist/websocket/client.d.ts.map +1 -1
  164. package/dist/websocket/client.js +13 -16
  165. package/package.json +4 -3
  166. package/dist/mcp/data/embeddings.json +0 -1
@@ -0,0 +1,55 @@
1
+ const SPARK_CHARS = ['▁', '▂', '▃', '▄', '▅', '▆', '▇', '█'];
2
+ const EMPTY_CHAR = '·';
3
+ export function sparkline(data, options = {}) {
4
+ const { width = 30, min: fixedMin, max: fixedMax } = options;
5
+ if (width === 0)
6
+ return '';
7
+ if (data.length === 0)
8
+ return EMPTY_CHAR.repeat(width);
9
+ const start = Math.max(0, data.length - width);
10
+ const slice = data.slice(start);
11
+ const min = fixedMin ?? Math.min(...slice, 0);
12
+ const max = fixedMax ?? Math.max(...slice, 0);
13
+ const range = Math.max(max - min, Number.EPSILON);
14
+ let result = '';
15
+ const padding = Math.max(0, width - slice.length);
16
+ if (padding > 0) {
17
+ result += EMPTY_CHAR.repeat(padding);
18
+ }
19
+ for (const value of slice) {
20
+ const normalized = Math.max(0, Math.min(1, (value - min) / range));
21
+ const idx = Math.round(normalized * (SPARK_CHARS.length - 1));
22
+ result += SPARK_CHARS[Math.min(idx, SPARK_CHARS.length - 1)];
23
+ }
24
+ return result;
25
+ }
26
+ export class SparklineBuffer {
27
+ data = [];
28
+ capacity;
29
+ constructor(capacity = 60) {
30
+ this.capacity = capacity;
31
+ }
32
+ push(value) {
33
+ if (this.data.length >= this.capacity) {
34
+ this.data.shift();
35
+ }
36
+ this.data.push(value);
37
+ }
38
+ getData() {
39
+ return this.data;
40
+ }
41
+ render(options = {}) {
42
+ return sparkline(this.data, { width: this.capacity, ...options });
43
+ }
44
+ clear() {
45
+ this.data = [];
46
+ }
47
+ latest() {
48
+ return this.data[this.data.length - 1];
49
+ }
50
+ average() {
51
+ if (this.data.length === 0)
52
+ return 0;
53
+ return this.data.reduce((a, b) => a + b, 0) / this.data.length;
54
+ }
55
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/utils/sse.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,wBAAuB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAuF5E"}
1
+ {"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/utils/sse.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,wBAAuB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAAC,QAAQ,CAAC,CAoF5E"}
package/dist/utils/sse.js CHANGED
@@ -1,11 +1,10 @@
1
- import { ReckerError } from '../core/errors.js';
1
+ import { StreamError } from '../core/errors.js';
2
2
  export async function* parseSSE(response) {
3
3
  if (!response.body) {
4
- throw new ReckerError('Response body is empty; cannot parse SSE stream.', undefined, undefined, [
5
- 'Ensure the server is sending an SSE stream with a response body.',
6
- 'Check that the request was not a HEAD/204 response.',
7
- 'Verify connection was not closed before the body was received.'
8
- ]);
4
+ throw new StreamError('Response body is empty; cannot parse SSE stream.', {
5
+ streamType: 'sse',
6
+ retriable: true,
7
+ });
9
8
  }
10
9
  const reader = response.body.getReader();
11
10
  const decoder = new TextDecoder();
@@ -0,0 +1,26 @@
1
+ export interface SystemSnapshot {
2
+ cpu: number;
3
+ memory: number;
4
+ memoryUsed: number;
5
+ memoryTotal: number;
6
+ timestamp: number;
7
+ }
8
+ export declare class SystemMetrics {
9
+ private previousCpuTimes;
10
+ private intervalId;
11
+ private listeners;
12
+ getMemory(): {
13
+ used: number;
14
+ total: number;
15
+ percent: number;
16
+ };
17
+ private getCpuTimes;
18
+ getCpuUsage(): number;
19
+ getSnapshot(): SystemSnapshot;
20
+ startPolling(intervalMs?: number): void;
21
+ stopPolling(): void;
22
+ onSnapshot(callback: (snapshot: SystemSnapshot) => void): () => void;
23
+ static formatBytes(bytes: number): string;
24
+ static formatMemory(used: number, total: number): string;
25
+ }
26
+ //# sourceMappingURL=system-metrics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-metrics.d.ts","sourceRoot":"","sources":["../../src/utils/system-metrics.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAE7B,GAAG,EAAE,MAAM,CAAC;IAEZ,MAAM,EAAE,MAAM,CAAC;IAEf,UAAU,EAAE,MAAM,CAAC;IAEnB,WAAW,EAAE,MAAM,CAAC;IAEpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,qBAAa,aAAa;IACxB,OAAO,CAAC,gBAAgB,CAAgD;IACxE,OAAO,CAAC,UAAU,CAA+C;IACjE,OAAO,CAAC,SAAS,CAAsD;IAKvE,SAAS,IAAI;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;IAY7D,OAAO,CAAC,WAAW;IAgBnB,WAAW,IAAI,MAAM;IAsBrB,WAAW,IAAI,cAAc;IAgB7B,YAAY,CAAC,UAAU,GAAE,MAAa,GAAG,IAAI;IAiB7C,WAAW,IAAI,IAAI;IAUnB,UAAU,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,cAAc,KAAK,IAAI,GAAG,MAAM,IAAI;IAQpE,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAUzC,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM;CAGzD"}
@@ -0,0 +1,81 @@
1
+ import os from 'node:os';
2
+ export class SystemMetrics {
3
+ previousCpuTimes = null;
4
+ intervalId = null;
5
+ listeners = new Set();
6
+ getMemory() {
7
+ const total = os.totalmem();
8
+ const free = os.freemem();
9
+ const used = total - free;
10
+ const percent = (used / total) * 100;
11
+ return { used, total, percent };
12
+ }
13
+ getCpuTimes() {
14
+ const cpus = os.cpus();
15
+ let idle = 0;
16
+ let total = 0;
17
+ for (const cpu of cpus) {
18
+ idle += cpu.times.idle;
19
+ total += cpu.times.user + cpu.times.nice + cpu.times.sys + cpu.times.idle + cpu.times.irq;
20
+ }
21
+ return { idle, total };
22
+ }
23
+ getCpuUsage() {
24
+ const current = this.getCpuTimes();
25
+ if (!this.previousCpuTimes) {
26
+ this.previousCpuTimes = current;
27
+ return 0;
28
+ }
29
+ const idleDelta = current.idle - this.previousCpuTimes.idle;
30
+ const totalDelta = current.total - this.previousCpuTimes.total;
31
+ this.previousCpuTimes = current;
32
+ if (totalDelta === 0)
33
+ return 0;
34
+ const usage = 100 - (idleDelta / totalDelta) * 100;
35
+ return Math.max(0, Math.min(100, usage));
36
+ }
37
+ getSnapshot() {
38
+ const memory = this.getMemory();
39
+ const cpu = this.getCpuUsage();
40
+ return {
41
+ cpu,
42
+ memory: memory.percent,
43
+ memoryUsed: memory.used,
44
+ memoryTotal: memory.total,
45
+ timestamp: Date.now()
46
+ };
47
+ }
48
+ startPolling(intervalMs = 1000) {
49
+ if (this.intervalId)
50
+ return;
51
+ this.previousCpuTimes = this.getCpuTimes();
52
+ this.intervalId = setInterval(() => {
53
+ const snapshot = this.getSnapshot();
54
+ for (const listener of this.listeners) {
55
+ listener(snapshot);
56
+ }
57
+ }, intervalMs);
58
+ }
59
+ stopPolling() {
60
+ if (this.intervalId) {
61
+ clearInterval(this.intervalId);
62
+ this.intervalId = null;
63
+ }
64
+ }
65
+ onSnapshot(callback) {
66
+ this.listeners.add(callback);
67
+ return () => this.listeners.delete(callback);
68
+ }
69
+ static formatBytes(bytes) {
70
+ if (bytes < 1024)
71
+ return `${bytes}B`;
72
+ if (bytes < 1024 * 1024)
73
+ return `${(bytes / 1024).toFixed(1)}K`;
74
+ if (bytes < 1024 * 1024 * 1024)
75
+ return `${(bytes / 1024 / 1024).toFixed(1)}M`;
76
+ return `${(bytes / 1024 / 1024 / 1024).toFixed(1)}G`;
77
+ }
78
+ static formatMemory(used, total) {
79
+ return `${this.formatBytes(used)}/${this.formatBytes(total)}`;
80
+ }
81
+ }
@@ -16,6 +16,12 @@ export interface TLSInfo {
16
16
  } | null;
17
17
  authorized: boolean;
18
18
  authorizationError?: Error;
19
+ altNames?: string[];
20
+ pubkey: {
21
+ algo: string;
22
+ size: number;
23
+ } | null;
24
+ extKeyUsage?: string[];
19
25
  }
20
26
  export declare function inspectTLS(host: string, port?: number, options?: ConnectionOptions): Promise<TLSInfo>;
21
27
  //# sourceMappingURL=tls-inspector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tls-inspector.d.ts","sourceRoot":"","sources":["../../src/utils/tls-inspector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAEjE,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI,CAAC;IACT,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,CAAC,EAAE,KAAK,CAAC;CAC5B;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAY,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CA4C9G"}
1
+ {"version":3,"file":"tls-inspector.d.ts","sourceRoot":"","sources":["../../src/utils/tls-inspector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAsB,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAGjE,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,EAAE,IAAI,CAAC;IAChB,OAAO,EAAE,IAAI,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,GAAG,IAAI,CAAC;IACT,UAAU,EAAE,OAAO,CAAC;IACpB,kBAAkB,CAAC,EAAE,KAAK,CAAC;IAE3B,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,MAAY,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,OAAO,CAAC,CAkF9G"}
@@ -1,4 +1,5 @@
1
1
  import { connect } from 'node:tls';
2
+ import * as crypto from 'node:crypto';
2
3
  export function inspectTLS(host, port = 443, options = {}) {
3
4
  return new Promise((resolve, reject) => {
4
5
  const socket = connect(port, host, { ...options, servername: host }, () => {
@@ -11,6 +12,36 @@ export function inspectTLS(host, port = 443, options = {}) {
11
12
  const validTo = new Date(cert.valid_to);
12
13
  const now = new Date();
13
14
  const daysRemaining = Math.floor((validTo.getTime() - now.getTime()) / (1000 * 60 * 60 * 24));
15
+ const altNames = cert.subjectaltname
16
+ ? cert.subjectaltname.split(', ').map(s => s.replace(/^DNS:|^IP Address:/, '')).filter(Boolean)
17
+ : [];
18
+ let pubkey = null;
19
+ if (cert.pubkey) {
20
+ try {
21
+ const keyObject = crypto.createPublicKey(cert.pubkey);
22
+ let keySize;
23
+ const keyAlgo = keyObject.asymmetricKeyType || 'unknown';
24
+ if (keyObject.asymmetricKeyDetails) {
25
+ if (keyObject.asymmetricKeyDetails.modulusLength) {
26
+ keySize = keyObject.asymmetricKeyDetails.modulusLength;
27
+ }
28
+ else if (keyObject.asymmetricKeyDetails.namedCurve) {
29
+ const curve = keyObject.asymmetricKeyDetails.namedCurve;
30
+ if (curve.includes('256') || curve.includes('p256'))
31
+ keySize = 256;
32
+ else if (curve.includes('384') || curve.includes('p384'))
33
+ keySize = 384;
34
+ else if (curve.includes('521') || curve.includes('p521'))
35
+ keySize = 521;
36
+ }
37
+ }
38
+ if (keySize) {
39
+ pubkey = { algo: keyAlgo, size: keySize };
40
+ }
41
+ }
42
+ catch {
43
+ }
44
+ }
14
45
  const info = {
15
46
  valid: now >= validFrom && now <= validTo,
16
47
  validFrom,
@@ -24,7 +55,10 @@ export function inspectTLS(host, port = 443, options = {}) {
24
55
  protocol: socket.getProtocol(),
25
56
  cipher: socket.getCipher(),
26
57
  authorized: socket.authorized,
27
- authorizationError: socket.authorizationError
58
+ authorizationError: socket.authorizationError,
59
+ altNames,
60
+ pubkey,
61
+ extKeyUsage: cert.ext_key_usage || []
28
62
  };
29
63
  socket.end();
30
64
  resolve(info);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webrtc/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/webrtc/index.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { StateError, TimeoutError, ConnectionError, UnsupportedError, } from '../core/errors.js';
1
2
  import { EventEmitter } from 'node:events';
2
3
  export class SignalingChannel extends EventEmitter {
3
4
  options;
@@ -79,7 +80,10 @@ export class WebRTCClient extends EventEmitter {
79
80
  }
80
81
  async connect(remotePeerId) {
81
82
  if (this.connections.has(remotePeerId)) {
82
- throw new Error(`Already connected to peer: ${remotePeerId}`);
83
+ throw new StateError(`Already connected to peer: ${remotePeerId}`, {
84
+ expectedState: 'disconnected',
85
+ actualState: 'connected',
86
+ });
83
87
  }
84
88
  this.log(`Connecting to peer: ${remotePeerId}`);
85
89
  const pc = this.createPeerConnection(remotePeerId);
@@ -116,7 +120,10 @@ export class WebRTCClient extends EventEmitter {
116
120
  if (remotePeerId) {
117
121
  const dc = this.dataChannels.get(remotePeerId);
118
122
  if (!dc || dc.readyState !== 'open') {
119
- throw new Error(`No open data channel to peer: ${remotePeerId}`);
123
+ throw new StateError(`No open data channel to peer: ${remotePeerId}`, {
124
+ expectedState: 'open',
125
+ actualState: dc?.readyState ?? 'no-channel',
126
+ });
120
127
  }
121
128
  dc.send(message);
122
129
  }
@@ -132,7 +139,10 @@ export class WebRTCClient extends EventEmitter {
132
139
  if (remotePeerId) {
133
140
  const dc = this.dataChannels.get(remotePeerId);
134
141
  if (!dc || dc.readyState !== 'open') {
135
- throw new Error(`No open data channel to peer: ${remotePeerId}`);
142
+ throw new StateError(`No open data channel to peer: ${remotePeerId}`, {
143
+ expectedState: 'open',
144
+ actualState: dc?.readyState ?? 'no-channel',
145
+ });
136
146
  }
137
147
  dc.send(data);
138
148
  }
@@ -154,8 +164,7 @@ export class WebRTCClient extends EventEmitter {
154
164
  }
155
165
  createPeerConnection(remotePeerId) {
156
166
  if (typeof RTCPeerConnection === 'undefined') {
157
- throw new Error('RTCPeerConnection is not available. ' +
158
- 'In Node.js, install the "wrtc" package and ensure it\'s loaded before using WebRTC.');
167
+ throw new UnsupportedError('RTCPeerConnection is not available. In Node.js, install the "wrtc" package and ensure it\'s loaded before using WebRTC.', { feature: 'RTCPeerConnection' });
159
168
  }
160
169
  const pc = new RTCPeerConnection({
161
170
  iceServers: this.iceServers,
@@ -264,7 +273,10 @@ export class WebRTCClient extends EventEmitter {
264
273
  waitForConnection(remotePeerId) {
265
274
  return new Promise((resolve, reject) => {
266
275
  const timeout = setTimeout(() => {
267
- reject(new Error(`Connection timeout to peer: ${remotePeerId}`));
276
+ reject(new TimeoutError(undefined, {
277
+ phase: 'webrtc-connect',
278
+ timeout: this.connectionTimeout,
279
+ }));
268
280
  }, this.connectionTimeout);
269
281
  const checkConnection = () => {
270
282
  const dc = this.dataChannels.get(remotePeerId);
@@ -282,7 +294,9 @@ export class WebRTCClient extends EventEmitter {
282
294
  this.on('disconnected', (peerId) => {
283
295
  if (peerId === remotePeerId) {
284
296
  clearTimeout(timeout);
285
- reject(new Error(`Connection failed to peer: ${remotePeerId}`));
297
+ reject(new ConnectionError(`Connection failed to peer: ${remotePeerId}`, {
298
+ host: remotePeerId,
299
+ }));
286
300
  }
287
301
  });
288
302
  checkConnection();
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/websocket/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/websocket/client.ts"],"names":[],"mappings":"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"}
@@ -2,7 +2,7 @@ import { WebSocket } from 'undici';
2
2
  import { EventEmitter } from 'events';
3
3
  import { pipeline } from 'node:stream/promises';
4
4
  import { webToNodeStream } from '../utils/streaming.js';
5
- import { ReckerError } from '../core/errors.js';
5
+ import { StateError, StreamError, ConnectionError } from '../core/errors.js';
6
6
  export class ReckerWebSocket extends EventEmitter {
7
7
  ws = null;
8
8
  url;
@@ -83,11 +83,10 @@ export class ReckerWebSocket extends EventEmitter {
83
83
  this.ws.addEventListener('error', (event) => {
84
84
  const err = event.error instanceof Error
85
85
  ? event.error
86
- : new ReckerError('WebSocket connection error', undefined, undefined, [
87
- 'Verify the WebSocket endpoint URL and protocol (ws/wss).',
88
- 'Check proxy/TLS settings if connecting through a proxy.',
89
- 'Inspect server logs for handshake failures.'
90
- ]);
86
+ : new ConnectionError('WebSocket connection error', {
87
+ host: this.url,
88
+ retriable: true,
89
+ });
91
90
  this.emit('error', err);
92
91
  reject(err);
93
92
  });
@@ -99,11 +98,10 @@ export class ReckerWebSocket extends EventEmitter {
99
98
  }
100
99
  async send(data, options) {
101
100
  if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
102
- throw new ReckerError('WebSocket is not connected', undefined, undefined, [
103
- 'Call connect() before sending messages.',
104
- 'Listen to the open event to ensure the socket is ready.',
105
- 'Check for prior connection errors or closed states.'
106
- ]);
101
+ throw new StateError('WebSocket is not connected', {
102
+ expectedState: 'open',
103
+ actualState: this.ws ? 'closed' : 'not-created',
104
+ });
107
105
  }
108
106
  const awaitDrain = options?.awaitDrain ?? false;
109
107
  const highWaterMark = options?.highWaterMark ?? 16 * 1024;
@@ -169,11 +167,10 @@ export class ReckerWebSocket extends EventEmitter {
169
167
  async pipeTo(destination) {
170
168
  const readable = this.toReadable();
171
169
  if (!readable) {
172
- throw new ReckerError('WebSocket has no readable stream', undefined, undefined, [
173
- 'Ensure the WebSocket is connected before piping.',
174
- 'Verify the runtime supports readable streams on WebSocket.',
175
- 'Fallback to event-based message handling if streaming is unavailable.'
176
- ]);
170
+ throw new StreamError('WebSocket has no readable stream', {
171
+ streamType: 'websocket',
172
+ retriable: false,
173
+ });
177
174
  }
178
175
  await pipeline(readable, destination);
179
176
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "recker",
3
- "version": "1.0.15",
3
+ "version": "1.0.17-next.316500c",
4
4
  "description": "AI & DevX focused HTTP client for Node.js 18+",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -115,6 +115,7 @@
115
115
  "access": "public"
116
116
  },
117
117
  "dependencies": {
118
+ "@maxmind/geoip2-node": "^6.3.4",
118
119
  "cheerio": "^1.0.0",
119
120
  "commander": "^12.0.0",
120
121
  "fuse.js": "^7.1.0",
@@ -166,13 +167,13 @@
166
167
  "zod": "^3.24.0"
167
168
  },
168
169
  "scripts": {
169
- "build": "tsc && mkdir -p dist/mcp/data && cp src/mcp/data/embeddings.json dist/mcp/data/",
170
+ "build": "tsc",
170
171
  "build:embeddings": "tsx scripts/build-embeddings.ts",
171
172
  "test": "vitest run",
172
173
  "test:coverage": "vitest run --coverage",
173
174
  "bench": "tsx benchmark/index.ts",
174
175
  "bench:all": "tsx benchmark/run-all.ts",
175
- "docs": "npx docsify-cli serve docs -p 3000 -o",
176
+ "docs": "pnpm serve docs -p 3000",
176
177
  "lint": "echo \"No linting configured for this project.\" && exit 0",
177
178
  "cli": "tsx src/cli/index.ts",
178
179
  "mcp:start": "tsx src/mcp/cli.ts",