recker 1.0.14-next.cd6adc2 → 1.0.15-next.0e216c0

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 (50) hide show
  1. package/README.md +78 -100
  2. package/dist/bench/generator.d.ts.map +1 -1
  3. package/dist/bench/generator.js +2 -1
  4. package/dist/bench/stats.d.ts +15 -1
  5. package/dist/bench/stats.d.ts.map +1 -1
  6. package/dist/bench/stats.js +84 -5
  7. package/dist/cli/index.js +21 -0
  8. package/dist/cli/tui/load-dashboard.d.ts.map +1 -1
  9. package/dist/cli/tui/load-dashboard.js +62 -8
  10. package/dist/cli/tui/scroll-buffer.d.ts +43 -0
  11. package/dist/cli/tui/scroll-buffer.d.ts.map +1 -0
  12. package/dist/cli/tui/scroll-buffer.js +162 -0
  13. package/dist/cli/tui/search-panel.d.ts +41 -0
  14. package/dist/cli/tui/search-panel.d.ts.map +1 -0
  15. package/dist/cli/tui/search-panel.js +419 -0
  16. package/dist/cli/tui/shell.d.ts +11 -0
  17. package/dist/cli/tui/shell.d.ts.map +1 -1
  18. package/dist/cli/tui/shell.js +236 -46
  19. package/dist/contract/index.js +3 -2
  20. package/dist/dns/index.d.ts +1 -0
  21. package/dist/dns/index.d.ts.map +1 -1
  22. package/dist/dns/index.js +1 -0
  23. package/dist/dns/propagation.d.ts +19 -0
  24. package/dist/dns/propagation.d.ts.map +1 -0
  25. package/dist/dns/propagation.js +129 -0
  26. package/dist/index.d.ts +2 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +2 -0
  29. package/dist/mcp/embeddings-loader.d.ts +18 -0
  30. package/dist/mcp/embeddings-loader.d.ts.map +1 -0
  31. package/dist/mcp/embeddings-loader.js +152 -0
  32. package/dist/mcp/index.d.ts +1 -0
  33. package/dist/mcp/index.d.ts.map +1 -1
  34. package/dist/mcp/index.js +1 -0
  35. package/dist/mcp/search/hybrid-search.d.ts.map +1 -1
  36. package/dist/mcp/search/hybrid-search.js +7 -21
  37. package/dist/mcp/server.d.ts +2 -0
  38. package/dist/mcp/server.d.ts.map +1 -1
  39. package/dist/mcp/server.js +8 -1
  40. package/dist/recker.d.ts +47 -0
  41. package/dist/recker.d.ts.map +1 -0
  42. package/dist/recker.js +99 -0
  43. package/dist/utils/colors.d.ts +16 -0
  44. package/dist/utils/colors.d.ts.map +1 -1
  45. package/dist/utils/colors.js +16 -0
  46. package/dist/utils/tls-inspector.d.ts +6 -0
  47. package/dist/utils/tls-inspector.d.ts.map +1 -1
  48. package/dist/utils/tls-inspector.js +35 -1
  49. package/package.json +2 -2
  50. package/dist/mcp/data/embeddings.json +0 -1
@@ -0,0 +1,152 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { fileURLToPath } from 'url';
4
+ function getPackageVersionFromPkg() {
5
+ try {
6
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
+ const paths = [
8
+ join(__dirname, '..', '..', 'package.json'),
9
+ join(__dirname, '..', '..', '..', 'package.json'),
10
+ join(process.cwd(), 'package.json'),
11
+ ];
12
+ for (const pkgPath of paths) {
13
+ if (existsSync(pkgPath)) {
14
+ const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
15
+ if (pkg.name === 'recker') {
16
+ return pkg.version;
17
+ }
18
+ }
19
+ }
20
+ }
21
+ catch {
22
+ }
23
+ return '1.0.15';
24
+ }
25
+ let _packageVersion = null;
26
+ function getPackageVersion() {
27
+ if (!_packageVersion) {
28
+ _packageVersion = getPackageVersionFromPkg();
29
+ }
30
+ return _packageVersion;
31
+ }
32
+ const GITHUB_RELEASE_URL = 'https://github.com/forattini-dev/recker/releases/download';
33
+ function getCacheDir() {
34
+ const homeDir = process.env.HOME || process.env.USERPROFILE || '';
35
+ if (homeDir) {
36
+ return join(homeDir, '.cache', 'recker');
37
+ }
38
+ try {
39
+ const __dirname = dirname(fileURLToPath(import.meta.url));
40
+ return join(__dirname, '..', '..', 'node_modules', '.cache', 'recker');
41
+ }
42
+ catch {
43
+ return join(process.cwd(), 'node_modules', '.cache', 'recker');
44
+ }
45
+ }
46
+ export function getEmbeddingsCachePath(version) {
47
+ const cacheDir = getCacheDir();
48
+ const ver = version || getPackageVersion();
49
+ return join(cacheDir, `embeddings-${ver}.json`);
50
+ }
51
+ export function hasLocalEmbeddings(version) {
52
+ return existsSync(getEmbeddingsCachePath(version));
53
+ }
54
+ export function loadLocalEmbeddings(version) {
55
+ const cachePath = getEmbeddingsCachePath(version);
56
+ if (!existsSync(cachePath)) {
57
+ return null;
58
+ }
59
+ try {
60
+ const data = readFileSync(cachePath, 'utf-8');
61
+ return JSON.parse(data);
62
+ }
63
+ catch {
64
+ return null;
65
+ }
66
+ }
67
+ export function saveLocalEmbeddings(data, version) {
68
+ const cachePath = getEmbeddingsCachePath(version);
69
+ const cacheDir = dirname(cachePath);
70
+ if (!existsSync(cacheDir)) {
71
+ mkdirSync(cacheDir, { recursive: true });
72
+ }
73
+ writeFileSync(cachePath, JSON.stringify(data));
74
+ }
75
+ export async function downloadEmbeddings(version) {
76
+ const ver = version || getPackageVersion();
77
+ const url = `${GITHUB_RELEASE_URL}/v${ver}/embeddings.json`;
78
+ try {
79
+ const response = await fetch(url);
80
+ if (!response.ok) {
81
+ throw new Error(`Failed to download embeddings: ${response.status} ${response.statusText}`);
82
+ }
83
+ const data = await response.json();
84
+ saveLocalEmbeddings(data, ver);
85
+ return data;
86
+ }
87
+ catch (error) {
88
+ throw new Error(`Failed to download embeddings from ${url}: ${error}`);
89
+ }
90
+ }
91
+ export async function loadBundledEmbeddings() {
92
+ try {
93
+ const __dirname = dirname(fileURLToPath(import.meta.url));
94
+ const bundledPath = join(__dirname, 'data', 'embeddings.json');
95
+ if (existsSync(bundledPath)) {
96
+ const data = readFileSync(bundledPath, 'utf-8');
97
+ return JSON.parse(data);
98
+ }
99
+ const srcPath = join(__dirname, '..', 'mcp', 'data', 'embeddings.json');
100
+ if (existsSync(srcPath)) {
101
+ const data = readFileSync(srcPath, 'utf-8');
102
+ return JSON.parse(data);
103
+ }
104
+ }
105
+ catch {
106
+ }
107
+ return null;
108
+ }
109
+ export async function loadEmbeddings(options = {}) {
110
+ const { forceDownload = false, version, offline = false, debug = false } = options;
111
+ const log = (msg) => {
112
+ if (debug)
113
+ console.log(`[embeddings-loader] ${msg}`);
114
+ };
115
+ if (!forceDownload) {
116
+ const cached = loadLocalEmbeddings(version);
117
+ if (cached) {
118
+ log(`Loaded from cache: ${getEmbeddingsCachePath(version)}`);
119
+ return cached;
120
+ }
121
+ }
122
+ const bundled = await loadBundledEmbeddings();
123
+ if (bundled) {
124
+ log('Loaded bundled embeddings');
125
+ return bundled;
126
+ }
127
+ if (!offline) {
128
+ try {
129
+ log(`Downloading embeddings v${version || getPackageVersion()}...`);
130
+ const downloaded = await downloadEmbeddings(version);
131
+ log(`Downloaded and cached: ${downloaded.documents?.length || 0} documents`);
132
+ return downloaded;
133
+ }
134
+ catch (error) {
135
+ log(`Download failed: ${error}`);
136
+ }
137
+ }
138
+ log('No embeddings available');
139
+ return null;
140
+ }
141
+ export function clearEmbeddingsCache(version) {
142
+ const cachePath = getEmbeddingsCachePath(version);
143
+ try {
144
+ const fs = require('fs');
145
+ if (fs.existsSync(cachePath)) {
146
+ fs.unlinkSync(cachePath);
147
+ }
148
+ }
149
+ catch {
150
+ }
151
+ }
152
+ export { getPackageVersion };
@@ -1,4 +1,5 @@
1
1
  export * from './types.js';
2
2
  export * from './client.js';
3
3
  export * from './server.js';
4
+ export * from './embeddings-loader.js';
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAKA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mcp/index.ts"],"names":[],"mappings":"AAKA,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,wBAAwB,CAAC"}
package/dist/mcp/index.js CHANGED
@@ -1,3 +1,4 @@
1
1
  export * from './types.js';
2
2
  export * from './client.js';
3
3
  export * from './server.js';
4
+ export * from './embeddings-loader.js';
@@ -1 +1 @@
1
- {"version":3,"file":"hybrid-search.d.ts","sourceRoot":"","sources":["../../../src/mcp/search/hybrid-search.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,kBAAkB,EAGnB,MAAM,YAAY,CAAC;AAkBpB,qBAAa,YAAY;IACvB,OAAO,CAAC,IAAI,CAAiC;IAC7C,OAAO,CAAC,IAAI,CAAoB;IAChC,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAA+B;gBAEjC,MAAM,GAAE,kBAAuB;IAYrC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YA+BrC,yBAAyB;IAuDjC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAmDjF,OAAO,CAAC,WAAW;IAiCnB,OAAO,CAAC,cAAc;IA8GtB,OAAO,CAAC,cAAc;IAoDtB,OAAO,CAAC,MAAM,CAAC,UAAU,CAoCtB;IAKH,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,cAAc;IAmBtB,aAAa,IAAI,OAAO;IAOxB,QAAQ,IAAI;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB;IAYD,OAAO,CAAC,GAAG;CAKZ;AAKD,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,YAAY,CAE5E"}
1
+ {"version":3,"file":"hybrid-search.d.ts","sourceRoot":"","sources":["../../../src/mcp/search/hybrid-search.ts"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,UAAU,EACV,YAAY,EACZ,aAAa,EACb,kBAAkB,EAGnB,MAAM,YAAY,CAAC;AAkBpB,qBAAa,YAAY;IACvB,OAAO,CAAC,IAAI,CAAiC;IAC7C,OAAO,CAAC,IAAI,CAAoB;IAChC,OAAO,CAAC,OAAO,CAAoC;IACnD,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,MAAM,CAA+B;gBAEjC,MAAM,GAAE,kBAAuB;IAYrC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;YAmCrC,yBAAyB;IAoCjC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAmDjF,OAAO,CAAC,WAAW;IAiCnB,OAAO,CAAC,cAAc;IA8GtB,OAAO,CAAC,cAAc;IAoDtB,OAAO,CAAC,MAAM,CAAC,UAAU,CAoCtB;IAKH,OAAO,CAAC,UAAU;IAYlB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,cAAc;IAmBtB,aAAa,IAAI,OAAO;IAOxB,QAAQ,IAAI;QACV,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB;IAYD,OAAO,CAAC,GAAG;CAKZ;AAKD,wBAAgB,kBAAkB,CAAC,MAAM,CAAC,EAAE,kBAAkB,GAAG,YAAY,CAE5E"}
@@ -1,5 +1,6 @@
1
1
  import Fuse from 'fuse.js';
2
2
  import { cosineSimilarity, combineScores, levenshtein } from './math.js';
3
+ import { loadEmbeddings } from '../embeddings-loader.js';
3
4
  let cachedEmbeddings = null;
4
5
  export class HybridSearch {
5
6
  fuse = null;
@@ -43,27 +44,12 @@ export class HybridSearch {
43
44
  this.embeddingsData = cachedEmbeddings;
44
45
  }
45
46
  else {
46
- const embeddingsPath = new URL('../data/embeddings.json', import.meta.url);
47
- try {
48
- const response = await fetch(embeddingsPath);
49
- if (response.ok) {
50
- this.embeddingsData = (await response.json());
51
- cachedEmbeddings = this.embeddingsData;
52
- }
53
- }
54
- catch {
55
- try {
56
- const fs = await import('fs');
57
- const path = await import('path');
58
- const embeddingsFile = path.join(path.dirname(new URL(import.meta.url).pathname), '../data/embeddings.json');
59
- if (fs.existsSync(embeddingsFile)) {
60
- const data = fs.readFileSync(embeddingsFile, 'utf-8');
61
- this.embeddingsData = JSON.parse(data);
62
- cachedEmbeddings = this.embeddingsData;
63
- }
64
- }
65
- catch {
66
- }
47
+ const data = await loadEmbeddings({
48
+ debug: this.config.debug,
49
+ });
50
+ if (data) {
51
+ this.embeddingsData = data;
52
+ cachedEmbeddings = data;
67
53
  }
68
54
  }
69
55
  if (this.embeddingsData) {
@@ -21,6 +21,8 @@ export declare class MCPServer {
21
21
  private sseClients;
22
22
  private initialized;
23
23
  constructor(options?: MCPServerOptions);
24
+ private indexReady;
25
+ private ensureIndexReady;
24
26
  private log;
25
27
  private findDocsPath;
26
28
  private findExamplesPath;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAMhB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAExD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AA0CD,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,MAAM,CAAC,CAAkC;IACjD,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,eAAe,CAAwB;IAC/C,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,GAAE,gBAAqB;IAiB1C,OAAO,CAAC,GAAG;IAUX,OAAO,CAAC,YAAY;IAyBpB,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,WAAW;YAwBL,UAAU;YAoBV,SAAS;IAiCvB,OAAO,CAAC,iBAAiB;IA6BzB,OAAO,CAAC,gBAAgB;IAqCxB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,eAAe;IA4BvB,OAAO,CAAC,mBAAmB;IA6B3B,OAAO,CAAC,oBAAoB;IA8B5B,OAAO,CAAC,sBAAsB;IA0E9B,OAAO,CAAC,wBAAwB;IAoBhC,OAAO,CAAC,OAAO;IAyBf,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,eAAe;IAqBvB,OAAO,CAAC,QAAQ;IAkHhB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,cAAc;IAoBtB,OAAO,CAAC,UAAU;IA0ElB,OAAO,CAAC,cAAc;IA6BtB,OAAO,CAAC,MAAM;IAmCd,OAAO,CAAC,eAAe;IAgDvB,OAAO,CAAC,YAAY;IAmEpB,OAAO,CAAC,cAAc;IAmFtB,OAAO,CAAC,gBAAgB;IA+DxB,OAAO,CAAC,iBAAiB;IAuCzB,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,eAAe;IA8DnD,OAAO,CAAC,gBAAgB;YAOV,UAAU;YAgCV,SAAS;YA8CT,QAAQ;IAuFhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAatB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B,OAAO,IAAI,MAAM;IAIjB,YAAY,IAAI,MAAM;IAItB,gBAAgB,IAAI,MAAM;IAI1B,aAAa,IAAI,MAAM;IAIvB,YAAY,IAAI,gBAAgB;CAGjC;AAoBD,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAErE"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,cAAc,EACd,eAAe,EAMhB,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;AAExD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CACxB;AA0CD,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,MAAM,CAAC,CAAkC;IACjD,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,YAAY,CAAqB;IACzC,OAAO,CAAC,eAAe,CAAwB;IAC/C,OAAO,CAAC,UAAU,CAAkC;IACpD,OAAO,CAAC,WAAW,CAAS;gBAEhB,OAAO,GAAE,gBAAqB;IAsB1C,OAAO,CAAC,UAAU,CAA8B;YAKlC,gBAAgB;IAO9B,OAAO,CAAC,GAAG;IAUX,OAAO,CAAC,YAAY;IAyBpB,OAAO,CAAC,gBAAgB;IAiBxB,OAAO,CAAC,WAAW;YAwBL,UAAU;YAoBV,SAAS;IAiCvB,OAAO,CAAC,iBAAiB;IA6BzB,OAAO,CAAC,gBAAgB;IAqCxB,OAAO,CAAC,gBAAgB;IAOxB,OAAO,CAAC,YAAY;IA0BpB,OAAO,CAAC,eAAe;IA4BvB,OAAO,CAAC,mBAAmB;IA6B3B,OAAO,CAAC,oBAAoB;IA8B5B,OAAO,CAAC,sBAAsB;IA0E9B,OAAO,CAAC,wBAAwB;IAoBhC,OAAO,CAAC,OAAO;IAyBf,OAAO,CAAC,YAAY;IAKpB,OAAO,CAAC,eAAe;IAqBvB,OAAO,CAAC,QAAQ;IAkHhB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,cAAc;IAoBtB,OAAO,CAAC,UAAU;IA0ElB,OAAO,CAAC,cAAc;IA6BtB,OAAO,CAAC,MAAM;IAmCd,OAAO,CAAC,eAAe;IAgDvB,OAAO,CAAC,YAAY;IAmEpB,OAAO,CAAC,cAAc;IAmFtB,OAAO,CAAC,gBAAgB;IA+DxB,OAAO,CAAC,iBAAiB;IAuCzB,aAAa,CAAC,GAAG,EAAE,cAAc,GAAG,eAAe;IA8DnD,OAAO,CAAC,gBAAgB;YAOV,UAAU;YAgCV,SAAS;YA8CT,QAAQ;IAuFhB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAe3B,OAAO,IAAI,MAAM;IAIjB,YAAY,IAAI,MAAM;IAItB,gBAAgB,IAAI,MAAM;IAI1B,aAAa,IAAI,MAAM;IAIvB,YAAY,IAAI,gBAAgB;CAGjC;AAoBD,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAErE"}
@@ -26,7 +26,13 @@ export class MCPServer {
26
26
  toolsFilter: options.toolsFilter || [],
27
27
  };
28
28
  this.hybridSearch = createHybridSearch({ debug: this.options.debug });
29
- this.buildIndex();
29
+ }
30
+ indexReady = null;
31
+ async ensureIndexReady() {
32
+ if (!this.indexReady) {
33
+ this.indexReady = this.buildIndex();
34
+ }
35
+ await this.indexReady;
30
36
  }
31
37
  log(message, data) {
32
38
  if (this.options.debug) {
@@ -1112,6 +1118,7 @@ const client = createClient({
1112
1118
  });
1113
1119
  }
1114
1120
  async start() {
1121
+ await this.ensureIndexReady();
1115
1122
  switch (this.options.transport) {
1116
1123
  case 'stdio':
1117
1124
  return this.startStdio();
@@ -0,0 +1,47 @@
1
+ import { Client, type ExtendedClientOptions } from './core/client.js';
2
+ import { type RequestPromise } from './core/request-promise.js';
3
+ import type { RequestOptions } from './types/index.js';
4
+ import { type WebSocketOptions, type ReckerWebSocket } from './websocket/client.js';
5
+ import { createWhois, type WhoisResult, type WhoisOptions } from './utils/whois.js';
6
+ import { type DNSClientOptions, type DNSClient } from './dns/index.js';
7
+ import type { AIClientConfig } from './types/ai.js';
8
+ export declare function get(url: string, options?: RequestOptions): RequestPromise;
9
+ export declare function post(url: string, options?: RequestOptions): RequestPromise;
10
+ export declare function put(url: string, options?: RequestOptions): RequestPromise;
11
+ export declare function patch(url: string, options?: RequestOptions): RequestPromise;
12
+ export declare function del(url: string, options?: RequestOptions): RequestPromise;
13
+ export declare function head(url: string, options?: RequestOptions): RequestPromise;
14
+ export declare function options(url: string, options?: RequestOptions): RequestPromise;
15
+ export declare function whois(query: string, options?: WhoisOptions): Promise<WhoisResult>;
16
+ export declare function whoisAvailable(domain: string): Promise<boolean>;
17
+ export declare function dns(hostname: string, type?: 'A' | 'AAAA' | 'MX' | 'TXT' | 'NS' | 'CNAME'): Promise<string[]>;
18
+ export declare function dnsSecurity(domain: string): Promise<import("./utils/dns-toolkit.js").DnsSecurityRecords>;
19
+ export declare function ws(url: string, options?: WebSocketOptions): ReckerWebSocket;
20
+ export declare const recker: {
21
+ get: typeof get;
22
+ post: typeof post;
23
+ put: typeof put;
24
+ patch: typeof patch;
25
+ delete: typeof del;
26
+ head: typeof head;
27
+ options: typeof options;
28
+ whois: typeof whois;
29
+ whoisAvailable: typeof whoisAvailable;
30
+ dns: typeof dns;
31
+ dnsSecurity: typeof dnsSecurity;
32
+ ws: typeof ws;
33
+ ai: {
34
+ chat: (optionsOrPrompt: string | import("./types/ai.js").ChatOptions) => Promise<import("./types/ai.js").AIResponse<string>>;
35
+ stream: (options: import("./types/ai.js").ChatOptions) => Promise<import("./types/ai.js").AIStream>;
36
+ embed: (options: import("./types/ai.js").EmbedOptions) => Promise<import("./types/ai.js").EmbedResponse>;
37
+ extend: (defaults: Partial<import("./types/ai.js").ChatOptions>) => import("./types/ai.js").AIClient;
38
+ readonly metrics: import("./types/ai.js").AIMetrics;
39
+ };
40
+ client: (options?: ExtendedClientOptions) => Client;
41
+ dnsClient: (options?: DNSClientOptions) => DNSClient;
42
+ whoisClient: typeof createWhois;
43
+ aiClient: (options?: AIClientConfig) => import("./types/ai.js").AIClient;
44
+ reset: () => void;
45
+ };
46
+ export default recker;
47
+ //# sourceMappingURL=recker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recker.d.ts","sourceRoot":"","sources":["../src/recker.ts"],"names":[],"mappings":"AAwCA,OAAO,EAAE,MAAM,EAAgB,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACpF,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAmB,KAAK,gBAAgB,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACrG,OAAO,EAA2C,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC7H,OAAO,EAAa,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAElF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AA0CpD,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,cAAc,CAEzE;AAMD,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,cAAc,CAE1E;AAKD,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,cAAc,CAEzE;AAKD,wBAAgB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,cAAc,CAE3E;AAKD,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,cAAc,CAEzE;AAKD,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,cAAc,CAE1E;AAKD,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,cAAc,CAE7E;AAUD,wBAAsB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAEvF;AAMD,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAErE;AAMD,wBAAsB,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,GAAE,GAAG,GAAG,MAAM,GAAG,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,OAAa,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAEvH;AAMD,wBAAsB,WAAW,CAAC,MAAM,EAAE,MAAM,gEAE/C;AAMD,wBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,eAAe,CAE3E;AA8DD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;uBAgDE,qBAAqB;0BAKlB,gBAAgB;;yBAUjB,cAAc;;CAUpC,CAAC;AAGF,eAAe,MAAM,CAAC"}
package/dist/recker.js ADDED
@@ -0,0 +1,99 @@
1
+ import { createClient } from './core/client.js';
2
+ import { FetchTransport } from './transport/fetch.js';
3
+ import { createWebSocket } from './websocket/client.js';
4
+ import { whois as whoisLookup, isDomainAvailable, createWhois } from './utils/whois.js';
5
+ import { createDNS } from './dns/index.js';
6
+ import { createAI } from './ai/index.js';
7
+ let _defaultClient = null;
8
+ let _defaultDns = null;
9
+ let _defaultAi = null;
10
+ function getDefaultClient() {
11
+ if (!_defaultClient) {
12
+ _defaultClient = createClient({
13
+ transport: new FetchTransport(),
14
+ });
15
+ }
16
+ return _defaultClient;
17
+ }
18
+ function getDefaultDns() {
19
+ if (!_defaultDns) {
20
+ _defaultDns = createDNS();
21
+ }
22
+ return _defaultDns;
23
+ }
24
+ function getDefaultAi() {
25
+ if (!_defaultAi) {
26
+ _defaultAi = createAI();
27
+ }
28
+ return _defaultAi;
29
+ }
30
+ export function get(url, options) {
31
+ return getDefaultClient().get(url, options);
32
+ }
33
+ export function post(url, options) {
34
+ return getDefaultClient().post(url, options);
35
+ }
36
+ export function put(url, options) {
37
+ return getDefaultClient().put(url, options);
38
+ }
39
+ export function patch(url, options) {
40
+ return getDefaultClient().patch(url, options);
41
+ }
42
+ export function del(url, options) {
43
+ return getDefaultClient().delete(url, options);
44
+ }
45
+ export function head(url, options) {
46
+ return getDefaultClient().head(url, options);
47
+ }
48
+ export function options(url, options) {
49
+ return getDefaultClient().options(url, options);
50
+ }
51
+ export async function whois(query, options) {
52
+ return whoisLookup(query, options);
53
+ }
54
+ export async function whoisAvailable(domain) {
55
+ return isDomainAvailable(domain);
56
+ }
57
+ export async function dns(hostname, type = 'A') {
58
+ return getDefaultDns().resolve(hostname, type);
59
+ }
60
+ export async function dnsSecurity(domain) {
61
+ return getDefaultDns().getSecurityRecords(domain);
62
+ }
63
+ export function ws(url, options) {
64
+ return createWebSocket(url, options);
65
+ }
66
+ const aiNamespace = {
67
+ chat: (...args) => getDefaultAi().chat(...args),
68
+ stream: (...args) => getDefaultAi().stream(...args),
69
+ embed: (...args) => getDefaultAi().embed(...args),
70
+ extend: (...args) => getDefaultAi().extend(...args),
71
+ get metrics() {
72
+ return getDefaultAi().metrics;
73
+ },
74
+ };
75
+ export const recker = {
76
+ get,
77
+ post,
78
+ put,
79
+ patch,
80
+ delete: del,
81
+ head,
82
+ options,
83
+ whois,
84
+ whoisAvailable,
85
+ dns,
86
+ dnsSecurity,
87
+ ws,
88
+ ai: aiNamespace,
89
+ client: (options) => createClient(options),
90
+ dnsClient: (options) => createDNS(options),
91
+ whoisClient: createWhois,
92
+ aiClient: (options) => createAI(options),
93
+ reset: () => {
94
+ _defaultClient = null;
95
+ _defaultDns = null;
96
+ _defaultAi = null;
97
+ },
98
+ };
99
+ export default recker;
@@ -9,6 +9,14 @@ export declare const magenta: (s: string | number) => string;
9
9
  export declare const cyan: (s: string | number) => string;
10
10
  export declare const white: (s: string | number) => string;
11
11
  export declare const gray: (s: string | number) => string;
12
+ export declare const bgBlack: (s: string | number) => string;
13
+ export declare const bgRed: (s: string | number) => string;
14
+ export declare const bgGreen: (s: string | number) => string;
15
+ export declare const bgYellow: (s: string | number) => string;
16
+ export declare const bgBlue: (s: string | number) => string;
17
+ export declare const bgMagenta: (s: string | number) => string;
18
+ export declare const bgCyan: (s: string | number) => string;
19
+ export declare const bgWhite: (s: string | number) => string;
12
20
  declare const colors: {
13
21
  reset: (s: string) => string;
14
22
  bold: (s: string | number) => string;
@@ -21,6 +29,14 @@ declare const colors: {
21
29
  cyan: (s: string | number) => string;
22
30
  white: (s: string | number) => string;
23
31
  gray: (s: string | number) => string;
32
+ bgBlack: (s: string | number) => string;
33
+ bgRed: (s: string | number) => string;
34
+ bgGreen: (s: string | number) => string;
35
+ bgYellow: (s: string | number) => string;
36
+ bgBlue: (s: string | number) => string;
37
+ bgMagenta: (s: string | number) => string;
38
+ bgCyan: (s: string | number) => string;
39
+ bgWhite: (s: string | number) => string;
24
40
  grey: (s: string | number) => string;
25
41
  };
26
42
  export default colors;
@@ -1 +1 @@
1
- {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/utils/colors.ts"],"names":[],"mappings":"AA6CA,eAAO,MAAM,KAAK,MAAmB,MAAM,WAA4C,CAAC;AACxF,eAAO,MAAM,IAAI,MAfY,MAAM,GAAG,MAAM,WAeb,CAAC;AAGhC,eAAO,MAAM,KAAK,MAlBW,MAAM,GAAG,MAAM,WAkBX,CAAC;AAClC,eAAO,MAAM,GAAG,MAnBa,MAAM,GAAG,MAAM,WAmBb,CAAC;AAChC,eAAO,MAAM,KAAK,MApBW,MAAM,GAAG,MAAM,WAoBX,CAAC;AAClC,eAAO,MAAM,MAAM,MArBU,MAAM,GAAG,MAAM,WAqBV,CAAC;AACnC,eAAO,MAAM,IAAI,MAtBY,MAAM,GAAG,MAAM,WAsBZ,CAAC;AACjC,eAAO,MAAM,OAAO,MAvBS,MAAM,GAAG,MAAM,WAuBT,CAAC;AACpC,eAAO,MAAM,IAAI,MAxBY,MAAM,GAAG,MAAM,WAwBZ,CAAC;AACjC,eAAO,MAAM,KAAK,MAzBW,MAAM,GAAG,MAAM,WAyBX,CAAC;AAClC,eAAO,MAAM,IAAI,MA1BY,MAAM,GAAG,MAAM,WA0BZ,CAAC;AAGjC,QAAA,MAAM,MAAM;eAfyB,MAAM;cAdd,MAAM,GAAG,MAAM;eAAf,MAAM,GAAG,MAAM;aAAf,MAAM,GAAG,MAAM;eAAf,MAAM,GAAG,MAAM;gBAAf,MAAM,GAAG,MAAM;cAAf,MAAM,GAAG,MAAM;iBAAf,MAAM,GAAG,MAAM;cAAf,MAAM,GAAG,MAAM;eAAf,MAAM,GAAG,MAAM;cAAf,MAAM,GAAG,MAAM;cAAf,MAAM,GAAG,MAAM;CA2C3C,CAAC;AAEF,eAAe,MAAM,CAAC"}
1
+ {"version":3,"file":"colors.d.ts","sourceRoot":"","sources":["../../src/utils/colors.ts"],"names":[],"mappings":"AA6CA,eAAO,MAAM,KAAK,MAAmB,MAAM,WAA4C,CAAC;AACxF,eAAO,MAAM,IAAI,MAfY,MAAM,GAAG,MAAM,WAeb,CAAC;AAGhC,eAAO,MAAM,KAAK,MAlBW,MAAM,GAAG,MAAM,WAkBX,CAAC;AAClC,eAAO,MAAM,GAAG,MAnBa,MAAM,GAAG,MAAM,WAmBb,CAAC;AAChC,eAAO,MAAM,KAAK,MApBW,MAAM,GAAG,MAAM,WAoBX,CAAC;AAClC,eAAO,MAAM,MAAM,MArBU,MAAM,GAAG,MAAM,WAqBV,CAAC;AACnC,eAAO,MAAM,IAAI,MAtBY,MAAM,GAAG,MAAM,WAsBZ,CAAC;AACjC,eAAO,MAAM,OAAO,MAvBS,MAAM,GAAG,MAAM,WAuBT,CAAC;AACpC,eAAO,MAAM,IAAI,MAxBY,MAAM,GAAG,MAAM,WAwBZ,CAAC;AACjC,eAAO,MAAM,KAAK,MAzBW,MAAM,GAAG,MAAM,WAyBX,CAAC;AAClC,eAAO,MAAM,IAAI,MA1BY,MAAM,GAAG,MAAM,WA0BZ,CAAC;AAGjC,eAAO,MAAM,OAAO,MA7BS,MAAM,GAAG,MAAM,WA6BT,CAAC;AACpC,eAAO,MAAM,KAAK,MA9BW,MAAM,GAAG,MAAM,WA8BX,CAAC;AAClC,eAAO,MAAM,OAAO,MA/BS,MAAM,GAAG,MAAM,WA+BT,CAAC;AACpC,eAAO,MAAM,QAAQ,MAhCQ,MAAM,GAAG,MAAM,WAgCR,CAAC;AACrC,eAAO,MAAM,MAAM,MAjCU,MAAM,GAAG,MAAM,WAiCV,CAAC;AACnC,eAAO,MAAM,SAAS,MAlCO,MAAM,GAAG,MAAM,WAkCP,CAAC;AACtC,eAAO,MAAM,MAAM,MAnCU,MAAM,GAAG,MAAM,WAmCV,CAAC;AACnC,eAAO,MAAM,OAAO,MApCS,MAAM,GAAG,MAAM,WAoCT,CAAC;AAGpC,QAAA,MAAM,MAAM;eAzByB,MAAM;cAdd,MAAM,GAAG,MAAM;eAAf,MAAM,GAAG,MAAM;aAAf,MAAM,GAAG,MAAM;eAAf,MAAM,GAAG,MAAM;gBAAf,MAAM,GAAG,MAAM;cAAf,MAAM,GAAG,MAAM;iBAAf,MAAM,GAAG,MAAM;cAAf,MAAM,GAAG,MAAM;eAAf,MAAM,GAAG,MAAM;cAAf,MAAM,GAAG,MAAM;iBAAf,MAAM,GAAG,MAAM;eAAf,MAAM,GAAG,MAAM;iBAAf,MAAM,GAAG,MAAM;kBAAf,MAAM,GAAG,MAAM;gBAAf,MAAM,GAAG,MAAM;mBAAf,MAAM,GAAG,MAAM;gBAAf,MAAM,GAAG,MAAM;iBAAf,MAAM,GAAG,MAAM;cAAf,MAAM,GAAG,MAAM;CA8D3C,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -33,6 +33,14 @@ export const magenta = code(35, 39);
33
33
  export const cyan = code(36, 39);
34
34
  export const white = code(37, 39);
35
35
  export const gray = code(90, 39);
36
+ export const bgBlack = code(40, 49);
37
+ export const bgRed = code(41, 49);
38
+ export const bgGreen = code(42, 49);
39
+ export const bgYellow = code(43, 49);
40
+ export const bgBlue = code(44, 49);
41
+ export const bgMagenta = code(45, 49);
42
+ export const bgCyan = code(46, 49);
43
+ export const bgWhite = code(47, 49);
36
44
  const colors = {
37
45
  reset,
38
46
  bold,
@@ -45,6 +53,14 @@ const colors = {
45
53
  cyan,
46
54
  white,
47
55
  gray,
56
+ bgBlack,
57
+ bgRed,
58
+ bgGreen,
59
+ bgYellow,
60
+ bgBlue,
61
+ bgMagenta,
62
+ bgCyan,
63
+ bgWhite,
48
64
  grey: gray,
49
65
  };
50
66
  export default colors;
@@ -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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "recker",
3
- "version": "1.0.14-next.cd6adc2",
3
+ "version": "1.0.15-next.0e216c0",
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",
@@ -166,7 +166,7 @@
166
166
  "zod": "^3.24.0"
167
167
  },
168
168
  "scripts": {
169
- "build": "tsc && mkdir -p dist/mcp/data && cp src/mcp/data/embeddings.json dist/mcp/data/",
169
+ "build": "tsc",
170
170
  "build:embeddings": "tsx scripts/build-embeddings.ts",
171
171
  "test": "vitest run",
172
172
  "test:coverage": "vitest run --coverage",