mne-docs-mcp 1.0.0
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.
- package/LICENSE +21 -0
- package/README.md +140 -0
- package/dist/cache/manager.d.ts +41 -0
- package/dist/cache/manager.d.ts.map +1 -0
- package/dist/cache/manager.js +123 -0
- package/dist/cache/manager.js.map +1 -0
- package/dist/config.d.ts +75 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +120 -0
- package/dist/config.js.map +1 -0
- package/dist/forum/client.d.ts +9 -0
- package/dist/forum/client.d.ts.map +1 -0
- package/dist/forum/client.js +48 -0
- package/dist/forum/client.js.map +1 -0
- package/dist/github/client.d.ts +33 -0
- package/dist/github/client.d.ts.map +1 -0
- package/dist/github/client.js +198 -0
- package/dist/github/client.js.map +1 -0
- package/dist/github/types.d.ts +238 -0
- package/dist/github/types.d.ts.map +1 -0
- package/dist/github/types.js +2 -0
- package/dist/github/types.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +96 -0
- package/dist/index.js.map +1 -0
- package/dist/parser/bridge.d.ts +46 -0
- package/dist/parser/bridge.d.ts.map +1 -0
- package/dist/parser/bridge.js +225 -0
- package/dist/parser/bridge.js.map +1 -0
- package/dist/parser/types.d.ts +36 -0
- package/dist/parser/types.d.ts.map +1 -0
- package/dist/parser/types.js +2 -0
- package/dist/parser/types.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +218 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/findMneSymbol.d.ts +22 -0
- package/dist/tools/findMneSymbol.d.ts.map +1 -0
- package/dist/tools/findMneSymbol.js +74 -0
- package/dist/tools/findMneSymbol.js.map +1 -0
- package/dist/tools/getMneChangelog.d.ts +31 -0
- package/dist/tools/getMneChangelog.d.ts.map +1 -0
- package/dist/tools/getMneChangelog.js +233 -0
- package/dist/tools/getMneChangelog.js.map +1 -0
- package/dist/tools/getMneDoc.d.ts +19 -0
- package/dist/tools/getMneDoc.d.ts.map +1 -0
- package/dist/tools/getMneDoc.js +248 -0
- package/dist/tools/getMneDoc.js.map +1 -0
- package/dist/tools/getMneExample.d.ts +31 -0
- package/dist/tools/getMneExample.d.ts.map +1 -0
- package/dist/tools/getMneExample.js +212 -0
- package/dist/tools/getMneExample.js.map +1 -0
- package/dist/tools/getMneFile.d.ts +3 -0
- package/dist/tools/getMneFile.d.ts.map +1 -0
- package/dist/tools/getMneFile.js +60 -0
- package/dist/tools/getMneFile.js.map +1 -0
- package/dist/tools/getMneForumTopic.d.ts +33 -0
- package/dist/tools/getMneForumTopic.d.ts.map +1 -0
- package/dist/tools/getMneForumTopic.js +136 -0
- package/dist/tools/getMneForumTopic.js.map +1 -0
- package/dist/tools/getMneIssue.d.ts +7 -0
- package/dist/tools/getMneIssue.d.ts.map +1 -0
- package/dist/tools/getMneIssue.js +22 -0
- package/dist/tools/getMneIssue.js.map +1 -0
- package/dist/tools/getMneIssueComments.d.ts +10 -0
- package/dist/tools/getMneIssueComments.d.ts.map +1 -0
- package/dist/tools/getMneIssueComments.js +26 -0
- package/dist/tools/getMneIssueComments.js.map +1 -0
- package/dist/tools/getRelatedSymbols.d.ts +26 -0
- package/dist/tools/getRelatedSymbols.d.ts.map +1 -0
- package/dist/tools/getRelatedSymbols.js +120 -0
- package/dist/tools/getRelatedSymbols.js.map +1 -0
- package/dist/tools/getSymbolReferences.d.ts +11 -0
- package/dist/tools/getSymbolReferences.d.ts.map +1 -0
- package/dist/tools/getSymbolReferences.js +251 -0
- package/dist/tools/getSymbolReferences.js.map +1 -0
- package/dist/tools/listMneVersions.d.ts +8 -0
- package/dist/tools/listMneVersions.d.ts.map +1 -0
- package/dist/tools/listMneVersions.js +32 -0
- package/dist/tools/listMneVersions.js.map +1 -0
- package/dist/tools/lookupMneError.d.ts +59 -0
- package/dist/tools/lookupMneError.d.ts.map +1 -0
- package/dist/tools/lookupMneError.js +280 -0
- package/dist/tools/lookupMneError.js.map +1 -0
- package/dist/tools/searchMneDocs.d.ts +3 -0
- package/dist/tools/searchMneDocs.d.ts.map +1 -0
- package/dist/tools/searchMneDocs.js +58 -0
- package/dist/tools/searchMneDocs.js.map +1 -0
- package/dist/tools/searchMneForum.d.ts +9 -0
- package/dist/tools/searchMneForum.d.ts.map +1 -0
- package/dist/tools/searchMneForum.js +29 -0
- package/dist/tools/searchMneForum.js.map +1 -0
- package/dist/tools/searchMneIssues.d.ts +8 -0
- package/dist/tools/searchMneIssues.d.ts.map +1 -0
- package/dist/tools/searchMneIssues.js +23 -0
- package/dist/tools/searchMneIssues.js.map +1 -0
- package/dist/types.d.ts +140 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +35 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/docstring.d.ts +26 -0
- package/dist/utils/docstring.d.ts.map +1 -0
- package/dist/utils/docstring.js +261 -0
- package/dist/utils/docstring.js.map +1 -0
- package/dist/utils/logger.d.ts +19 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +73 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/metrics.d.ts +38 -0
- package/dist/utils/metrics.d.ts.map +1 -0
- package/dist/utils/metrics.js +57 -0
- package/dist/utils/metrics.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +18 -0
- package/dist/version.js.map +1 -0
- package/package.json +71 -0
- package/python/ast_extractor.py +422 -0
- package/python/parser.py +68 -0
- package/python/requirements.txt +2 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 weiyongxu
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# MNE Docs MCP Server
|
|
2
|
+
|
|
3
|
+
MCP server providing access to MNE-Python documentation, source code, GitHub issues, and community forum across the MNE ecosystem.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Clone and install
|
|
9
|
+
git clone https://github.com/weiyongxu/mne-docs-mcp.git
|
|
10
|
+
cd mne-docs-mcp
|
|
11
|
+
npm install
|
|
12
|
+
|
|
13
|
+
# Set GitHub token (required)
|
|
14
|
+
export MNE_GITHUB_TOKEN=ghp_your_token_here
|
|
15
|
+
|
|
16
|
+
# Start server
|
|
17
|
+
npm start
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Server runs on `http://localhost:8000`. Verify with `curl http://localhost:8000/health`.
|
|
21
|
+
|
|
22
|
+
## MCP Client Integration
|
|
23
|
+
|
|
24
|
+
### Claude Desktop / Kiro / Claude Code
|
|
25
|
+
|
|
26
|
+
Add to your MCP config (`claude_desktop_config.json`, `.kiro/settings/mcp.json`, or `~/.claude/settings.json`):
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"mcpServers": {
|
|
31
|
+
"mne-docs": {
|
|
32
|
+
"command": "node",
|
|
33
|
+
"args": ["/path/to/mne-docs-mcp/dist/index.js"],
|
|
34
|
+
"env": {
|
|
35
|
+
"MNE_GITHUB_TOKEN": "ghp_your_token_here",
|
|
36
|
+
"MNE_TRANSPORT": "stdio"
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
> **Windows:** Add `"MNE_PYTHON_PATH": "python"` to env.
|
|
44
|
+
|
|
45
|
+
### HTTP Mode
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
MNE_TRANSPORT=http npm start
|
|
49
|
+
# Connect to http://localhost:8000/mcp
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Docker
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
docker run -p 8000:8000 -e MNE_GITHUB_TOKEN=ghp_your_token mne-docs-mcp
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Docker Compose
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
# Set your token
|
|
62
|
+
export MNE_GITHUB_TOKEN=ghp_your_token_here
|
|
63
|
+
|
|
64
|
+
# Start
|
|
65
|
+
docker-compose up -d
|
|
66
|
+
|
|
67
|
+
# View logs
|
|
68
|
+
docker-compose logs -f
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Tools
|
|
72
|
+
|
|
73
|
+
| Tool | Description |
|
|
74
|
+
|------|-------------|
|
|
75
|
+
| `list_mne_versions` | List available MNE releases |
|
|
76
|
+
| `get_mne_file` | Fetch source code |
|
|
77
|
+
| `get_mne_doc` | Get symbol documentation |
|
|
78
|
+
| `find_mne_symbol` | Search for symbols |
|
|
79
|
+
| `search_mne_docs` | Unified code/docs search |
|
|
80
|
+
| `search_mne_issues` | Search GitHub issues |
|
|
81
|
+
| `get_mne_issue` | Get issue details |
|
|
82
|
+
| `get_mne_issue_comments` | Get issue comments |
|
|
83
|
+
| `search_mne_forum` | Search community forum |
|
|
84
|
+
| `get_mne_forum_topic` | Get full forum discussion |
|
|
85
|
+
| `get_symbol_references` | Get callees/callers |
|
|
86
|
+
| `get_related_symbols` | Find related functions |
|
|
87
|
+
| `get_mne_changelog` | Get version changes |
|
|
88
|
+
| `get_mne_example` | Get tutorial code |
|
|
89
|
+
| `lookup_mne_error` | Diagnose MNE errors |
|
|
90
|
+
|
|
91
|
+
All tools support a `package` parameter to query across the MNE ecosystem: `mne-python` (default), `mne-bids-pipeline`, `mne-bids`, `mne-connectivity`, `mne-nirs`, `mne-rsa`, `mne-icalabel`, `mne-realtime`, `mne-lsl`, `mne-gui-addons`.
|
|
92
|
+
|
|
93
|
+
## Configuration
|
|
94
|
+
|
|
95
|
+
| Variable | Description | Default |
|
|
96
|
+
|----------|-------------|---------|
|
|
97
|
+
| `MNE_GITHUB_TOKEN` | GitHub PAT (required) | - |
|
|
98
|
+
| `MNE_PORT` | Server port | `8000` |
|
|
99
|
+
| `MNE_TRANSPORT` | `http` or `stdio` | `http` |
|
|
100
|
+
| `MNE_PYTHON_PATH` | Python executable | `python3` |
|
|
101
|
+
| `MNE_LOG_LEVEL` | `debug`/`info`/`warn`/`error` | `info` |
|
|
102
|
+
|
|
103
|
+
See `.env.example` for all options including cache TTLs and timeouts.
|
|
104
|
+
|
|
105
|
+
## Architecture
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
┌─────────────────────────────────────────────────────────┐
|
|
109
|
+
│ TypeScript Server (Node.js) │
|
|
110
|
+
│ ├─ MCP Tools (McpServer API, SDK v1.18+) │
|
|
111
|
+
│ ├─ GitHub Client (rate limiting, caching) │
|
|
112
|
+
│ └─ Python Parser Bridge ──┐ │
|
|
113
|
+
└────────────────────────────┼────────────────────────────┘
|
|
114
|
+
▼
|
|
115
|
+
┌─────────────────┐
|
|
116
|
+
│ Python Parser │
|
|
117
|
+
│ (AST, stdlib) │
|
|
118
|
+
└─────────────────┘
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Built with the official [MCP TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk).
|
|
122
|
+
|
|
123
|
+
## Development
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
npm run dev # Watch mode
|
|
127
|
+
npm run build # Compile TypeScript
|
|
128
|
+
npm test # Run tests
|
|
129
|
+
npm run lint # ESLint
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Troubleshooting
|
|
133
|
+
|
|
134
|
+
- **Rate limits:** Ensure `MNE_GITHUB_TOKEN` is set
|
|
135
|
+
- **Parser fails:** Check Python 3 is installed; Windows users set `MNE_PYTHON_PATH=python`
|
|
136
|
+
- **Test setup:** Run `npx tsx examples/mcp-client.ts` to verify
|
|
137
|
+
|
|
138
|
+
## License
|
|
139
|
+
|
|
140
|
+
MIT
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Config } from '../config.js';
|
|
2
|
+
import { MneVersion, ParsedSymbol, SearchResult, ForumSearchItem } from '../types.js';
|
|
3
|
+
export interface CacheEntry<T> {
|
|
4
|
+
data: T;
|
|
5
|
+
expiresAt: number;
|
|
6
|
+
lastAccessed: number;
|
|
7
|
+
}
|
|
8
|
+
export interface CacheStats {
|
|
9
|
+
entries: number;
|
|
10
|
+
hits: number;
|
|
11
|
+
misses: number;
|
|
12
|
+
hitRate: number;
|
|
13
|
+
}
|
|
14
|
+
export declare class CacheManager {
|
|
15
|
+
private config;
|
|
16
|
+
private logger;
|
|
17
|
+
private versionTtlMs;
|
|
18
|
+
private versions;
|
|
19
|
+
private fileCache;
|
|
20
|
+
private symbolCache;
|
|
21
|
+
private searchCache;
|
|
22
|
+
private forumCache;
|
|
23
|
+
constructor(config: Config);
|
|
24
|
+
getVersions(): MneVersion[] | null;
|
|
25
|
+
setVersions(versions: MneVersion[]): void;
|
|
26
|
+
getFile(version: string, path: string): string | null;
|
|
27
|
+
setFile(version: string, path: string, content: string): void;
|
|
28
|
+
getSymbol(version: string, symbol: string): ParsedSymbol | null;
|
|
29
|
+
setSymbol(version: string, symbol: string, data: ParsedSymbol): void;
|
|
30
|
+
getSearch(version: string, query: string): SearchResult | null;
|
|
31
|
+
setSearch(version: string, query: string, data: SearchResult): void;
|
|
32
|
+
getForumSearch(query: string): ForumSearchItem[] | null;
|
|
33
|
+
setForumSearch(query: string, results: ForumSearchItem[]): void;
|
|
34
|
+
private getEntry;
|
|
35
|
+
private setEntry;
|
|
36
|
+
private recordHitMiss;
|
|
37
|
+
private pruneIfNeeded;
|
|
38
|
+
getStats(): CacheStats;
|
|
39
|
+
clear(): void;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/cache/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAItF,MAAM,WAAW,UAAU,CAAC,CAAC;IACzB,IAAI,EAAE,CAAC,CAAC;IACR,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,UAAU;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,YAAY;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAyC;IACzD,OAAO,CAAC,SAAS,CAA8C;IAC/D,OAAO,CAAC,WAAW,CAAoD;IACvE,OAAO,CAAC,WAAW,CAAoD;IACvE,OAAO,CAAC,UAAU,CAAyD;gBAE/D,MAAM,EAAE,MAAM;IAM1B,WAAW,IAAI,UAAU,EAAE,GAAG,IAAI;IAWlC,WAAW,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,IAAI;IASzC,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIrD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAK7D,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAI/D,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;IAKpE,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAI9D,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI;IAKnE,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,EAAE,GAAG,IAAI;IAIvD,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI;IAK/D,OAAO,CAAC,QAAQ;IAgBhB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,aAAa;IAYrB,QAAQ,IAAI,UAAU;IAUtB,KAAK,IAAI,IAAI;CAOhB"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { getLogger } from '../utils/logger.js';
|
|
2
|
+
import { metrics } from '../utils/metrics.js';
|
|
3
|
+
export class CacheManager {
|
|
4
|
+
config;
|
|
5
|
+
logger = getLogger();
|
|
6
|
+
versionTtlMs;
|
|
7
|
+
versions = null;
|
|
8
|
+
fileCache = new Map();
|
|
9
|
+
symbolCache = new Map();
|
|
10
|
+
searchCache = new Map();
|
|
11
|
+
forumCache = new Map();
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = config;
|
|
14
|
+
this.versionTtlMs = config.versionCacheTtlMinutes * 60 * 1000;
|
|
15
|
+
}
|
|
16
|
+
// Versions
|
|
17
|
+
getVersions() {
|
|
18
|
+
if (!this.versions || Date.now() > this.versions.expiresAt) {
|
|
19
|
+
this.versions = null;
|
|
20
|
+
this.recordHitMiss(false);
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
this.versions.lastAccessed = Date.now();
|
|
24
|
+
this.recordHitMiss(true);
|
|
25
|
+
return this.versions.data;
|
|
26
|
+
}
|
|
27
|
+
setVersions(versions) {
|
|
28
|
+
this.versions = {
|
|
29
|
+
data: versions,
|
|
30
|
+
expiresAt: Date.now() + this.versionTtlMs,
|
|
31
|
+
lastAccessed: Date.now(),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
// Files
|
|
35
|
+
getFile(version, path) {
|
|
36
|
+
return this.getEntry(this.fileCache, `file:${version}:${path}`);
|
|
37
|
+
}
|
|
38
|
+
setFile(version, path, content) {
|
|
39
|
+
this.setEntry(this.fileCache, `file:${version}:${path}`, content, this.config.fileCacheTtlMinutes);
|
|
40
|
+
}
|
|
41
|
+
// Symbols
|
|
42
|
+
getSymbol(version, symbol) {
|
|
43
|
+
return this.getEntry(this.symbolCache, `symbol:${version}:${symbol}`);
|
|
44
|
+
}
|
|
45
|
+
setSymbol(version, symbol, data) {
|
|
46
|
+
this.setEntry(this.symbolCache, `symbol:${version}:${symbol}`, data, this.config.symbolCacheTtlMinutes);
|
|
47
|
+
}
|
|
48
|
+
// Search
|
|
49
|
+
getSearch(version, query) {
|
|
50
|
+
return this.getEntry(this.searchCache, `search:${version}:${query}`);
|
|
51
|
+
}
|
|
52
|
+
setSearch(version, query, data) {
|
|
53
|
+
this.setEntry(this.searchCache, `search:${version}:${query}`, data, this.config.fileCacheTtlMinutes);
|
|
54
|
+
}
|
|
55
|
+
// Forum
|
|
56
|
+
getForumSearch(query) {
|
|
57
|
+
return this.getEntry(this.forumCache, `forum:${query}`);
|
|
58
|
+
}
|
|
59
|
+
setForumSearch(query, results) {
|
|
60
|
+
this.setEntry(this.forumCache, `forum:${query}`, results, 30);
|
|
61
|
+
}
|
|
62
|
+
// Generic helpers
|
|
63
|
+
getEntry(cache, key) {
|
|
64
|
+
const entry = cache.get(key);
|
|
65
|
+
if (!entry) {
|
|
66
|
+
this.recordHitMiss(false);
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
69
|
+
if (Date.now() > entry.expiresAt) {
|
|
70
|
+
cache.delete(key);
|
|
71
|
+
this.recordHitMiss(false);
|
|
72
|
+
return null;
|
|
73
|
+
}
|
|
74
|
+
entry.lastAccessed = Date.now();
|
|
75
|
+
this.recordHitMiss(true);
|
|
76
|
+
return entry.data;
|
|
77
|
+
}
|
|
78
|
+
setEntry(cache, key, data, ttlMinutes) {
|
|
79
|
+
cache.set(key, {
|
|
80
|
+
data,
|
|
81
|
+
expiresAt: Date.now() + ttlMinutes * 60 * 1000,
|
|
82
|
+
lastAccessed: Date.now(),
|
|
83
|
+
});
|
|
84
|
+
this.pruneIfNeeded();
|
|
85
|
+
}
|
|
86
|
+
recordHitMiss(hit) {
|
|
87
|
+
if (hit) {
|
|
88
|
+
metrics.recordCacheHit();
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
metrics.recordCacheMiss();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
pruneIfNeeded() {
|
|
95
|
+
const total = this.fileCache.size + this.symbolCache.size + this.searchCache.size + this.forumCache.size;
|
|
96
|
+
if (total > this.config.maxCacheEntries) {
|
|
97
|
+
this.logger.debug('Pruning cache', { totalEntries: total });
|
|
98
|
+
[this.fileCache, this.symbolCache, this.searchCache, this.forumCache].forEach(cache => {
|
|
99
|
+
for (const [key, entry] of cache.entries()) {
|
|
100
|
+
if (Date.now() > entry.expiresAt)
|
|
101
|
+
cache.delete(key);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
getStats() {
|
|
107
|
+
const m = metrics.getMetrics();
|
|
108
|
+
return {
|
|
109
|
+
entries: this.fileCache.size + this.symbolCache.size + this.searchCache.size + this.forumCache.size,
|
|
110
|
+
hits: m.cache.hits,
|
|
111
|
+
misses: m.cache.misses,
|
|
112
|
+
hitRate: m.cache.hitRate,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
clear() {
|
|
116
|
+
this.versions = null;
|
|
117
|
+
this.fileCache.clear();
|
|
118
|
+
this.symbolCache.clear();
|
|
119
|
+
this.searchCache.clear();
|
|
120
|
+
this.forumCache.clear();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/cache/manager.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* MNE Package metadata for multi-package support.
|
|
4
|
+
* Each package has its own GitHub repo, source path, and documentation URL.
|
|
5
|
+
*/
|
|
6
|
+
export interface MnePackageInfo {
|
|
7
|
+
repo: string;
|
|
8
|
+
sourcePath: string;
|
|
9
|
+
docsUrl: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Registry of supported MNE ecosystem packages.
|
|
13
|
+
*/
|
|
14
|
+
export declare const MNE_PACKAGES: Record<string, MnePackageInfo>;
|
|
15
|
+
export declare const MNE_PACKAGE_NAMES: string[];
|
|
16
|
+
export declare const DEFAULT_PACKAGE = "mne-python";
|
|
17
|
+
/**
|
|
18
|
+
* Get package info by name, with fallback to default.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getPackageInfo(packageName?: string): MnePackageInfo;
|
|
21
|
+
export declare const ConfigSchema: z.ZodObject<{
|
|
22
|
+
port: z.ZodDefault<z.ZodNumber>;
|
|
23
|
+
transport: z.ZodDefault<z.ZodEnum<["http", "stdio"]>>;
|
|
24
|
+
githubToken: z.ZodString;
|
|
25
|
+
githubApiBase: z.ZodDefault<z.ZodString>;
|
|
26
|
+
defaultPackage: z.ZodDefault<z.ZodString>;
|
|
27
|
+
githubTimeout: z.ZodDefault<z.ZodNumber>;
|
|
28
|
+
forumBaseUrl: z.ZodDefault<z.ZodString>;
|
|
29
|
+
forumTimeout: z.ZodDefault<z.ZodNumber>;
|
|
30
|
+
versionCacheTtlMinutes: z.ZodDefault<z.ZodNumber>;
|
|
31
|
+
symbolCacheTtlMinutes: z.ZodDefault<z.ZodNumber>;
|
|
32
|
+
fileCacheTtlMinutes: z.ZodDefault<z.ZodNumber>;
|
|
33
|
+
maxCacheEntries: z.ZodDefault<z.ZodNumber>;
|
|
34
|
+
pythonPath: z.ZodDefault<z.ZodString>;
|
|
35
|
+
parserTimeout: z.ZodDefault<z.ZodNumber>;
|
|
36
|
+
logLevel: z.ZodDefault<z.ZodEnum<["debug", "info", "warn", "error"]>>;
|
|
37
|
+
logJson: z.ZodDefault<z.ZodBoolean>;
|
|
38
|
+
}, "strip", z.ZodTypeAny, {
|
|
39
|
+
port: number;
|
|
40
|
+
transport: "http" | "stdio";
|
|
41
|
+
githubToken: string;
|
|
42
|
+
githubApiBase: string;
|
|
43
|
+
defaultPackage: string;
|
|
44
|
+
githubTimeout: number;
|
|
45
|
+
forumBaseUrl: string;
|
|
46
|
+
forumTimeout: number;
|
|
47
|
+
versionCacheTtlMinutes: number;
|
|
48
|
+
symbolCacheTtlMinutes: number;
|
|
49
|
+
fileCacheTtlMinutes: number;
|
|
50
|
+
maxCacheEntries: number;
|
|
51
|
+
pythonPath: string;
|
|
52
|
+
parserTimeout: number;
|
|
53
|
+
logLevel: "debug" | "info" | "warn" | "error";
|
|
54
|
+
logJson: boolean;
|
|
55
|
+
}, {
|
|
56
|
+
githubToken: string;
|
|
57
|
+
port?: number | undefined;
|
|
58
|
+
transport?: "http" | "stdio" | undefined;
|
|
59
|
+
githubApiBase?: string | undefined;
|
|
60
|
+
defaultPackage?: string | undefined;
|
|
61
|
+
githubTimeout?: number | undefined;
|
|
62
|
+
forumBaseUrl?: string | undefined;
|
|
63
|
+
forumTimeout?: number | undefined;
|
|
64
|
+
versionCacheTtlMinutes?: number | undefined;
|
|
65
|
+
symbolCacheTtlMinutes?: number | undefined;
|
|
66
|
+
fileCacheTtlMinutes?: number | undefined;
|
|
67
|
+
maxCacheEntries?: number | undefined;
|
|
68
|
+
pythonPath?: string | undefined;
|
|
69
|
+
parserTimeout?: number | undefined;
|
|
70
|
+
logLevel?: "debug" | "info" | "warn" | "error" | undefined;
|
|
71
|
+
logJson?: boolean | undefined;
|
|
72
|
+
}>;
|
|
73
|
+
export type Config = z.infer<typeof ConfigSchema>;
|
|
74
|
+
export declare function loadConfig(): Config;
|
|
75
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAmDvD,CAAC;AAEF,eAAO,MAAM,iBAAiB,UAA4B,CAAC;AAC3D,eAAO,MAAM,eAAe,eAAe,CAAC;AAE5C;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,cAAc,CAOnE;AAED,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBvB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,wBAAgB,UAAU,IAAI,MAAM,CAkCnC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Registry of supported MNE ecosystem packages.
|
|
4
|
+
*/
|
|
5
|
+
export const MNE_PACKAGES = {
|
|
6
|
+
'mne-python': {
|
|
7
|
+
repo: 'mne-tools/mne-python',
|
|
8
|
+
sourcePath: 'mne/',
|
|
9
|
+
docsUrl: 'https://mne.tools/stable/',
|
|
10
|
+
},
|
|
11
|
+
'mne-bids-pipeline': {
|
|
12
|
+
repo: 'mne-tools/mne-bids-pipeline',
|
|
13
|
+
sourcePath: 'mne_bids_pipeline/',
|
|
14
|
+
docsUrl: 'https://mne.tools/mne-bids-pipeline/stable/',
|
|
15
|
+
},
|
|
16
|
+
'mne-bids': {
|
|
17
|
+
repo: 'mne-tools/mne-bids',
|
|
18
|
+
sourcePath: 'mne_bids/',
|
|
19
|
+
docsUrl: 'https://mne.tools/mne-bids/stable/',
|
|
20
|
+
},
|
|
21
|
+
'mne-connectivity': {
|
|
22
|
+
repo: 'mne-tools/mne-connectivity',
|
|
23
|
+
sourcePath: 'mne_connectivity/',
|
|
24
|
+
docsUrl: 'https://mne.tools/mne-connectivity/stable/',
|
|
25
|
+
},
|
|
26
|
+
'mne-nirs': {
|
|
27
|
+
repo: 'mne-tools/mne-nirs',
|
|
28
|
+
sourcePath: 'mne_nirs/',
|
|
29
|
+
docsUrl: 'https://mne.tools/mne-nirs/stable/',
|
|
30
|
+
},
|
|
31
|
+
'mne-rsa': {
|
|
32
|
+
repo: 'mne-tools/mne-rsa',
|
|
33
|
+
sourcePath: 'mne_rsa/',
|
|
34
|
+
docsUrl: 'https://mne.tools/mne-rsa/stable/',
|
|
35
|
+
},
|
|
36
|
+
'mne-icalabel': {
|
|
37
|
+
repo: 'mne-tools/mne-icalabel',
|
|
38
|
+
sourcePath: 'mne_icalabel/',
|
|
39
|
+
docsUrl: 'https://mne.tools/mne-icalabel/stable/',
|
|
40
|
+
},
|
|
41
|
+
'mne-realtime': {
|
|
42
|
+
repo: 'mne-tools/mne-realtime',
|
|
43
|
+
sourcePath: 'mne_realtime/',
|
|
44
|
+
docsUrl: 'https://mne.tools/mne-realtime/',
|
|
45
|
+
},
|
|
46
|
+
'mne-lsl': {
|
|
47
|
+
repo: 'mne-tools/mne-lsl',
|
|
48
|
+
sourcePath: 'mne_lsl/',
|
|
49
|
+
docsUrl: 'https://mne.tools/mne-lsl/stable/',
|
|
50
|
+
},
|
|
51
|
+
'mne-gui-addons': {
|
|
52
|
+
repo: 'mne-tools/mne-gui-addons',
|
|
53
|
+
sourcePath: 'mne_gui_addons/',
|
|
54
|
+
docsUrl: 'https://mne.tools/mne-gui-addons/',
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
export const MNE_PACKAGE_NAMES = Object.keys(MNE_PACKAGES);
|
|
58
|
+
export const DEFAULT_PACKAGE = 'mne-python';
|
|
59
|
+
/**
|
|
60
|
+
* Get package info by name, with fallback to default.
|
|
61
|
+
*/
|
|
62
|
+
export function getPackageInfo(packageName) {
|
|
63
|
+
const name = packageName || DEFAULT_PACKAGE;
|
|
64
|
+
const info = MNE_PACKAGES[name];
|
|
65
|
+
if (!info) {
|
|
66
|
+
throw new Error(`Unknown MNE package: ${name}. Supported: ${MNE_PACKAGE_NAMES.join(', ')}`);
|
|
67
|
+
}
|
|
68
|
+
return info;
|
|
69
|
+
}
|
|
70
|
+
export const ConfigSchema = z.object({
|
|
71
|
+
port: z.coerce.number().default(8000),
|
|
72
|
+
transport: z.enum(['http', 'stdio']).default('http'),
|
|
73
|
+
githubToken: z.string().min(1),
|
|
74
|
+
githubApiBase: z.string().default('https://api.github.com'),
|
|
75
|
+
defaultPackage: z.string().default(DEFAULT_PACKAGE),
|
|
76
|
+
githubTimeout: z.coerce.number().default(15000),
|
|
77
|
+
forumBaseUrl: z.string().default('https://mne.discourse.group'),
|
|
78
|
+
forumTimeout: z.coerce.number().default(15000),
|
|
79
|
+
versionCacheTtlMinutes: z.coerce.number().default(60),
|
|
80
|
+
symbolCacheTtlMinutes: z.coerce.number().default(30),
|
|
81
|
+
fileCacheTtlMinutes: z.coerce.number().default(15),
|
|
82
|
+
maxCacheEntries: z.coerce.number().default(1000),
|
|
83
|
+
pythonPath: z.string().default('python3'),
|
|
84
|
+
parserTimeout: z.coerce.number().default(10000),
|
|
85
|
+
logLevel: z.enum(['debug', 'info', 'warn', 'error']).default('info'),
|
|
86
|
+
logJson: z.coerce.boolean().default(false),
|
|
87
|
+
});
|
|
88
|
+
export function loadConfig() {
|
|
89
|
+
const config = {
|
|
90
|
+
port: process.env.MNE_PORT,
|
|
91
|
+
transport: process.env.MNE_TRANSPORT,
|
|
92
|
+
githubToken: process.env.MNE_GITHUB_TOKEN,
|
|
93
|
+
githubApiBase: process.env.MNE_GITHUB_API_BASE,
|
|
94
|
+
defaultPackage: process.env.MNE_DEFAULT_PACKAGE,
|
|
95
|
+
githubTimeout: process.env.MNE_GITHUB_TIMEOUT,
|
|
96
|
+
forumBaseUrl: process.env.MNE_FORUM_BASE_URL,
|
|
97
|
+
forumTimeout: process.env.MNE_FORUM_TIMEOUT,
|
|
98
|
+
versionCacheTtlMinutes: process.env.MNE_CACHE_TTL_MINUTES, // Using generic TTL for version if not specific
|
|
99
|
+
symbolCacheTtlMinutes: process.env.MNE_SYMBOL_CACHE_TTL_MINUTES,
|
|
100
|
+
fileCacheTtlMinutes: process.env.MNE_FILE_CACHE_TTL_MINUTES,
|
|
101
|
+
maxCacheEntries: process.env.MNE_MAX_CACHE_ENTRIES,
|
|
102
|
+
pythonPath: process.env.MNE_PYTHON_PATH,
|
|
103
|
+
parserTimeout: process.env.MNE_PARSER_TIMEOUT,
|
|
104
|
+
logLevel: process.env.MNE_LOG_LEVEL,
|
|
105
|
+
logJson: process.env.MNE_LOG_JSON,
|
|
106
|
+
};
|
|
107
|
+
// Filter undefined values to allow Zod defaults to work
|
|
108
|
+
const cleanConfig = Object.fromEntries(Object.entries(config).filter(([_, v]) => v !== undefined));
|
|
109
|
+
try {
|
|
110
|
+
return ConfigSchema.parse(cleanConfig);
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
if (error instanceof z.ZodError) {
|
|
114
|
+
const issues = error.issues.map(i => `${i.path.join('.')}: ${i.message}`).join('\n');
|
|
115
|
+
throw new Error(`Configuration validation failed:\n${issues}\n\nMake sure MNE_GITHUB_TOKEN is set.`);
|
|
116
|
+
}
|
|
117
|
+
throw error;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ForumSearchItem } from '../types.js';
|
|
2
|
+
export declare class ForumClient {
|
|
3
|
+
readonly baseUrl: string;
|
|
4
|
+
readonly timeout: number;
|
|
5
|
+
private logger;
|
|
6
|
+
constructor(baseUrl: string, timeout: number);
|
|
7
|
+
search(query: string, limit?: number): Promise<ForumSearchItem[]>;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/forum/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAgE9C,qBAAa,WAAW;IACpB,SAAgB,OAAO,EAAE,MAAM,CAAC;IAChC,SAAgB,OAAO,EAAE,MAAM,CAAC;IAChC,OAAO,CAAC,MAAM,CAAe;gBAEjB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAKtC,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAU,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CA0C7E"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { getLogger } from '../utils/logger.js';
|
|
2
|
+
export class ForumClient {
|
|
3
|
+
baseUrl;
|
|
4
|
+
timeout;
|
|
5
|
+
logger = getLogger();
|
|
6
|
+
constructor(baseUrl, timeout) {
|
|
7
|
+
this.baseUrl = baseUrl;
|
|
8
|
+
this.timeout = timeout;
|
|
9
|
+
}
|
|
10
|
+
async search(query, limit = 5) {
|
|
11
|
+
const url = `${this.baseUrl}/search.json?q=${encodeURIComponent(query)}`;
|
|
12
|
+
try {
|
|
13
|
+
const response = await fetch(url, {
|
|
14
|
+
headers: { 'Accept': 'application/json' },
|
|
15
|
+
signal: AbortSignal.timeout(this.timeout),
|
|
16
|
+
});
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
this.logger.error('Forum search failed', { status: response.status });
|
|
19
|
+
return [];
|
|
20
|
+
}
|
|
21
|
+
const data = await response.json();
|
|
22
|
+
// Discourse returns topics and posts separately
|
|
23
|
+
// Posts contain the blurb/excerpt, topics contain metadata
|
|
24
|
+
const topics = data.topics || [];
|
|
25
|
+
const posts = data.posts || [];
|
|
26
|
+
// Create a map of topic_id -> first post blurb
|
|
27
|
+
const postBlurbs = new Map();
|
|
28
|
+
for (const post of posts) {
|
|
29
|
+
if (post.topic_id && post.blurb && !postBlurbs.has(post.topic_id)) {
|
|
30
|
+
postBlurbs.set(post.topic_id, post.blurb);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return topics.slice(0, limit).map((t) => ({
|
|
34
|
+
source: 'forum',
|
|
35
|
+
title: t.fancy_title || t.title,
|
|
36
|
+
url: `${this.baseUrl}/t/${t.slug}/${t.id}`,
|
|
37
|
+
blurb: postBlurbs.get(t.id) || t.excerpt || t.blurb || '',
|
|
38
|
+
postsCount: t.posts_count,
|
|
39
|
+
createdAt: t.created_at,
|
|
40
|
+
}));
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
this.logger.error('Forum search error', { error });
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/forum/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AA+D/C,MAAM,OAAO,WAAW;IACJ,OAAO,CAAS;IAChB,OAAO,CAAS;IACxB,MAAM,GAAG,SAAS,EAAE,CAAC;IAE7B,YAAY,OAAe,EAAE,OAAe;QACxC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,KAAa,EAAE,QAAgB,CAAC;QACzC,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,kBAAkB,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;QAEzE,IAAI,CAAC;YACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAC9B,OAAO,EAAE,EAAE,QAAQ,EAAE,kBAAkB,EAAE;gBACzC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC;aAC5C,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACf,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;gBACtE,OAAO,EAAE,CAAC;YACd,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAA6B,CAAC;YAE9D,gDAAgD;YAChD,2DAA2D;YAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC;YACjC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YAE/B,+CAA+C;YAC/C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;YAC7C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACvB,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAChE,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC9C,CAAC;YACL,CAAC;YAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;gBACtC,MAAM,EAAE,OAAgB;gBACxB,KAAK,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,KAAK;gBAC/B,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,MAAM,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,EAAE;gBAC1C,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,IAAI,EAAE;gBACzD,UAAU,EAAE,CAAC,CAAC,WAAW;gBACzB,SAAS,EAAE,CAAC,CAAC,UAAU;aAC1B,CAAC,CAAC,CAAC;QACR,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;YACnD,OAAO,EAAE,CAAC;QACd,CAAC;IACL,CAAC;CACJ"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Config } from '../config.js';
|
|
2
|
+
import { MneVersion, GithubIssueItem } from '../types.js';
|
|
3
|
+
import { GitHubSearchCodeResult, GitHubIssueDetail, GitHubIssueComment, RateLimitInfo } from './types.js';
|
|
4
|
+
export declare class GitHubClient {
|
|
5
|
+
readonly config: Config;
|
|
6
|
+
private logger;
|
|
7
|
+
private rateLimitInfo;
|
|
8
|
+
constructor(config: Config);
|
|
9
|
+
private getRepo;
|
|
10
|
+
getRateLimitInfo(): RateLimitInfo | null;
|
|
11
|
+
private updateRateLimit;
|
|
12
|
+
private handleRateLimit;
|
|
13
|
+
private request;
|
|
14
|
+
fetchVersions(limit?: number, packageName?: string): Promise<MneVersion[]>;
|
|
15
|
+
getLatestVersion(packageName?: string): Promise<string>;
|
|
16
|
+
fetchFile(path: string, version?: string, packageName?: string): Promise<string | null>;
|
|
17
|
+
fileExists(path: string, version?: string, packageName?: string): Promise<boolean>;
|
|
18
|
+
searchCode(query: string, options?: {
|
|
19
|
+
path?: string;
|
|
20
|
+
perPage?: number;
|
|
21
|
+
version?: string;
|
|
22
|
+
packageName?: string;
|
|
23
|
+
}): Promise<GitHubSearchCodeResult>;
|
|
24
|
+
searchIssues(query: string, options?: {
|
|
25
|
+
state?: 'open' | 'closed' | 'all';
|
|
26
|
+
labels?: string[];
|
|
27
|
+
perPage?: number;
|
|
28
|
+
packageName?: string;
|
|
29
|
+
}): Promise<GithubIssueItem[]>;
|
|
30
|
+
getIssue(issueNumber: number, packageName?: string): Promise<GitHubIssueDetail | null>;
|
|
31
|
+
getIssueComments(issueNumber: number, packageName?: string): Promise<GitHubIssueComment[]>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/github/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAkB,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EACgB,sBAAsB,EACpB,iBAAiB,EACtC,kBAAkB,EAAa,aAAa,EAC/C,MAAM,YAAY,CAAC;AAIpB,qBAAa,YAAY;IACrB,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,aAAa,CAA8B;gBAEvC,MAAM,EAAE,MAAM;IAI1B,OAAO,CAAC,OAAO;IAIf,gBAAgB,IAAI,aAAa,GAAG,IAAI;IAIxC,OAAO,CAAC,eAAe;YAkBT,eAAe;YAaf,OAAO;IAoCf,aAAa,CAAC,KAAK,GAAE,MAAW,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAU9E,gBAAgB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMvD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAyBvF,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIlF,UAAU,CACZ,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO,GAC1F,OAAO,CAAC,sBAAsB,CAAC;IAS5B,YAAY,CACd,KAAK,EAAE,MAAM,EACb,OAAO,GAAE;QAAE,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAO,GAC/G,OAAO,CAAC,eAAe,EAAE,CAAC;IA2BvB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAyBtF,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,EAAE,CAAC;CAkBnG"}
|