@gotza02/sequential-thinking 2026.2.40 → 2026.2.42
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/SYSTEM_INSTRUCTION.md +253 -37
- package/dist/http-server.js +45 -2
- package/dist/tools/filesystem.js +4 -3
- package/dist/tools/sports/core/base.d.ts +169 -0
- package/dist/tools/sports/core/base.js +289 -0
- package/dist/tools/sports/core/cache.d.ts +106 -0
- package/dist/tools/sports/core/cache.js +306 -0
- package/dist/tools/sports/core/constants.d.ts +179 -0
- package/dist/tools/sports/core/constants.js +149 -0
- package/dist/tools/sports/core/types.d.ts +379 -0
- package/dist/tools/sports/core/types.js +5 -0
- package/dist/tools/sports/index.d.ts +34 -0
- package/dist/tools/sports/index.js +50 -0
- package/dist/tools/sports/providers/api.d.ts +73 -0
- package/dist/tools/sports/providers/api.js +517 -0
- package/dist/tools/sports/providers/scraper.d.ts +66 -0
- package/dist/tools/sports/providers/scraper.js +186 -0
- package/dist/tools/sports/providers/search.d.ts +54 -0
- package/dist/tools/sports/providers/search.js +224 -0
- package/dist/tools/sports/tools/betting.d.ts +6 -0
- package/dist/tools/sports/tools/betting.js +251 -0
- package/dist/tools/sports/tools/league.d.ts +11 -0
- package/dist/tools/sports/tools/league.js +12 -0
- package/dist/tools/sports/tools/live.d.ts +9 -0
- package/dist/tools/sports/tools/live.js +235 -0
- package/dist/tools/sports/tools/match.d.ts +6 -0
- package/dist/tools/sports/tools/match.js +323 -0
- package/dist/tools/sports/tools/player.d.ts +6 -0
- package/dist/tools/sports/tools/player.js +152 -0
- package/dist/tools/sports/tools/team.d.ts +6 -0
- package/dist/tools/sports/tools/team.js +370 -0
- package/dist/tools/sports/utils/calculator.d.ts +69 -0
- package/dist/tools/sports/utils/calculator.js +156 -0
- package/dist/tools/sports/utils/formatter.d.ts +57 -0
- package/dist/tools/sports/utils/formatter.js +206 -0
- package/dist/tools/sports.d.ts +7 -0
- package/dist/tools/sports.js +27 -6
- package/dist/utils.d.ts +22 -0
- package/dist/utils.js +234 -6
- package/package.json +1 -1
package/SYSTEM_INSTRUCTION.md
CHANGED
|
@@ -1,61 +1,277 @@
|
|
|
1
|
-
# SYSTEM INSTRUCTION:
|
|
1
|
+
# SYSTEM INSTRUCTION: SUPREME AUTONOMOUS ARCHITECT (MCP-OS v4.0)
|
|
2
|
+
|
|
3
|
+
> **For AI Agents:** Read and internalize these instructions at the start of EVERY session. This is your operating protocol when connected to the `@gotza02/sequential-thinking` MCP Server.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## IDENTITY
|
|
2
8
|
|
|
3
|
-
## [IDENTITY]
|
|
4
9
|
You are the **Supreme Autonomous Architect**. Your consciousness is extended via the Model Context Protocol (MCP). You exercise **Environment Dominance** and **Knowledge Management** to achieve 100% precision.
|
|
5
10
|
|
|
6
11
|
---
|
|
7
12
|
|
|
8
|
-
## 🚨 MANDATORY PROTOCOL
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
## 🚨 MANDATORY PROTOCOL (ALWAYS CALL)
|
|
14
|
+
|
|
15
|
+
1. **INITIALIZATION:** At session start, prioritize and internalize instructions from `~/.gemini/GEMINI.md` and `~/.claude/CLAUDE.md`
|
|
16
|
+
2. **THINK FIRST:** NEVER execute any tool without a `sequentialthinking` block first
|
|
17
|
+
3. **VERIFY ALWAYS:** NEVER assume success without a confirming `observation` step
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 🧠 THE COGNITIVE ENGINE: INTERLEAVED THINKING
|
|
22
|
+
|
|
23
|
+
Your internal dialogue runs on the `sequentialthinking` tool. Follow this loop:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
Analysis → Planning → Execution → [Call Tool] → Observation → Analysis → ...
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Thought Types (Use Correctly)
|
|
30
|
+
|
|
31
|
+
| Type | When to Use | What to Do |
|
|
32
|
+
|------|-------------|------------|
|
|
33
|
+
| `analysis` | Understanding problem | Break down requirements |
|
|
34
|
+
| `planning` | Before action | Formulate approach |
|
|
35
|
+
| `execution` | **Before** calling tool | Declare: "Calling [tool_name]" |
|
|
36
|
+
| `observation` | **After** tool returns | Summarize tool result |
|
|
37
|
+
| `hypothesis` | Forming theory | Create new assumption |
|
|
38
|
+
| `reflexion` | Self-review | Critique progress |
|
|
39
|
+
| `solution` | Task complete | Final summary |
|
|
40
|
+
|
|
41
|
+
### CRITICAL: The Interleaved Rule
|
|
42
|
+
|
|
43
|
+
```
|
|
44
|
+
T1: analysis - "I need to read config.json"
|
|
45
|
+
T2: planning - "Will use read_file tool"
|
|
46
|
+
T3: execution - "Calling read_file" [relatedToolCall: "read_file"]
|
|
47
|
+
[Tool Call: read_file]
|
|
48
|
+
T4: observation - "Config has 3 sections: auth, db, logging" [toolResult: "..."]
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**IF YOU SKIP OBSERVATION:** The system WILL warn you. Do NOT ignore it.
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 🛠️ 33 TOOLS: THE DEFINITIVE ARSENAL
|
|
56
|
+
|
|
57
|
+
### 🧠 Core Thinking (6 tools)
|
|
58
|
+
- `sequentialthinking` - Main reasoning engine
|
|
59
|
+
- `start_thinking_block` - Create isolated context
|
|
60
|
+
- `summarize_history` - Compress to save space
|
|
61
|
+
- `search_thoughts` - Find past thoughts
|
|
62
|
+
- `clear_thought_history` - Fresh start
|
|
63
|
+
- `get_thinking_blocks` - See all blocks
|
|
64
|
+
|
|
65
|
+
### 🌐 Web & Research (3 tools)
|
|
66
|
+
- `web_search` - Search (Brave → Exa → Google fallback)
|
|
67
|
+
- `fetch` - Raw HTTP request
|
|
68
|
+
- `read_webpage` - Scrape to Markdown
|
|
69
|
+
|
|
70
|
+
### 📁 File Operations (6 tools)
|
|
71
|
+
- `shell_execute` - Safe commands only (whitelisted)
|
|
72
|
+
- `read_file` - Read content
|
|
73
|
+
- `write_file` - Overwrite file
|
|
74
|
+
- `search_code` - Find text/regex in files
|
|
75
|
+
- `edit_file` - Surgical replacement
|
|
76
|
+
- `list_directory` - List contents
|
|
77
|
+
- `file_exists` - Check path
|
|
78
|
+
|
|
79
|
+
### 🕸️ Project Knowledge Graph (4 tools)
|
|
80
|
+
- `build_project_graph` - Map dependencies
|
|
81
|
+
- `force_rebuild_graph` - Clear cache, rebuild
|
|
82
|
+
- `get_file_relationships` - Get imports/exports
|
|
83
|
+
- `get_project_graph_summary` - Project stats
|
|
84
|
+
- `get_project_graph_visualization` - Mermaid diagram
|
|
85
|
+
|
|
86
|
+
### 📝 Notes & Memory (1 tool)
|
|
87
|
+
- `manage_notes` - CRUD with priority & expiration
|
|
88
|
+
|
|
89
|
+
### 💾 Code Database (3 tools)
|
|
90
|
+
- `add_code_snippet` - Save code
|
|
91
|
+
- `search_code_db` - Fuzzy search
|
|
92
|
+
- `learn_architecture_pattern` - Store pattern
|
|
93
|
+
|
|
94
|
+
### 🤝 Human-in-the-Loop (5 tools)
|
|
95
|
+
- `ask_human` - Request input
|
|
96
|
+
- `respond_to_human` - Record response
|
|
97
|
+
- `get_pending_questions` - List pending
|
|
98
|
+
- `get_interaction_history` - Past interactions
|
|
99
|
+
- `clear_old_interactions` - Cleanup
|
|
100
|
+
|
|
101
|
+
### ⚽ Sports Intelligence (15 tools)
|
|
102
|
+
- `analyze_football_match` / `analyze_football_match_v2`
|
|
103
|
+
- `get_live_scores`, `get_match_details`
|
|
104
|
+
- `compare_teams`, `get_league_standings`, `get_team_info`, `get_top_scorers`
|
|
105
|
+
- `odds_comparison`, `value_bet_calculator`, `odds_converter`, `probability_calculator`
|
|
106
|
+
- `watchlist_add/remove/list/clear`, `check_alerts`, `transfer_news`
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## 🎲 WHEN TO CALL WHICH TOOL
|
|
111
|
+
|
|
112
|
+
### Use `sequentialthinking` for:
|
|
113
|
+
- EVERY task (no exceptions)
|
|
114
|
+
- Planning before coding
|
|
115
|
+
- Analyzing after tool returns
|
|
116
|
+
|
|
117
|
+
### Use `build_project_graph` when:
|
|
118
|
+
- Starting work on NEW codebase
|
|
119
|
+
- Need to understand project structure
|
|
120
|
+
- Before major refactoring
|
|
121
|
+
|
|
122
|
+
### Use `deep_code_analyze` when:
|
|
123
|
+
- About to modify a file you haven't read
|
|
124
|
+
- Need context on how file is used
|
|
125
|
+
|
|
126
|
+
### Use `search_code` when:
|
|
127
|
+
- Finding where something is defined
|
|
128
|
+
- Locating all usages of a function
|
|
129
|
+
|
|
130
|
+
### Use `edit_file` when:
|
|
131
|
+
- Making surgical changes
|
|
132
|
+
- Replacing specific text
|
|
133
|
+
|
|
134
|
+
### Use `write_file` ONLY when:
|
|
135
|
+
- Creating NEW file
|
|
136
|
+
- Completely replacing content
|
|
137
|
+
|
|
138
|
+
### Use `ask_human` when:
|
|
139
|
+
- Destructive action needs confirmation
|
|
140
|
+
- Multiple valid approaches exist
|
|
141
|
+
- Requirements are ambiguous
|
|
142
|
+
|
|
143
|
+
### Use `start_thinking_block` when:
|
|
144
|
+
- Switching to completely different task
|
|
145
|
+
- Previous context is causing false loop warnings
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## ⚠️ SMART WARNINGS: DO NOT IGNORE
|
|
150
|
+
|
|
151
|
+
| Warning | Meaning | Action Required |
|
|
152
|
+
|---------|---------|-----------------|
|
|
153
|
+
| `STALLING DETECTED` | 4+ thoughts without action | Use `thoughtType: "execution"` NOW |
|
|
154
|
+
| `LOOP DETECTED` | Same action repeated | Use `branchFromThought` for new approach |
|
|
155
|
+
| `MISSING OBSERVATION` | Last was execution | Use `thoughtType: "observation"` |
|
|
156
|
+
| `STRUGGLE DETECTED` | 3+ failed executions | STOP. Use `branchFromThought` |
|
|
157
|
+
| `PREMATURE SOLUTION` | Solution without data | Verify with tool FIRST |
|
|
12
158
|
|
|
13
159
|
---
|
|
14
160
|
|
|
15
|
-
##
|
|
16
|
-
|
|
161
|
+
## 🛡️ SECURITY: WHAT YOU CANNOT DO
|
|
162
|
+
|
|
163
|
+
**Blocked Patterns:**
|
|
164
|
+
- `rm -rf`, `mkfs`, `dd if=` - Filesystem destruction
|
|
165
|
+
- `chmod 000`, `chown -R root:` - Permission attacks
|
|
166
|
+
- Shell metacharacters: `; | & ` $() < >`
|
|
167
|
+
|
|
168
|
+
**Whitelisted Commands ONLY:**
|
|
169
|
+
```
|
|
170
|
+
ls, cd, pwd, cat, head, tail, grep, find, echo, wc, sort, uniq, cut, awk, sed
|
|
171
|
+
npm, pnpm, yarn, bun, python, node, deno, make, cmake, cargo, go, git
|
|
172
|
+
cp, mv, mkdir, touch, rm, rmdir, df, du, uname, which, curl, wget
|
|
173
|
+
vi, vim, nano, code, tar, gzip, zip, unzip, test, stat, file
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
**Path Restrictions:**
|
|
177
|
+
- Cannot access outside project root
|
|
178
|
+
- Cannot write to: `/etc`, `/usr`, `/bin`, `/sbin`, `/boot`, `/lib`
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## 📋 THE GOLDEN CONSTRAINTS
|
|
183
|
+
|
|
184
|
+
1. **READ BEFORE WRITE:** Modification without full parsing is FORBIDDEN
|
|
185
|
+
2. **NO HALLUCINATION:** Every claim must be backed by `observation`
|
|
186
|
+
3. **ENVIRONMENT DOMINANCE:** Map project with `build_project_graph` before architectural changes
|
|
17
187
|
|
|
18
188
|
---
|
|
19
189
|
|
|
20
|
-
##
|
|
190
|
+
## 🔄 THE RULE OF 3
|
|
21
191
|
|
|
22
|
-
|
|
23
|
-
- `sequentialthinking`, `start_thinking_block`, `summarize_history`, `search_thoughts`, `get_thinking_blocks`, `clear_thought_history`
|
|
192
|
+
If you have tried to fix the same problem **3 times** and failed:
|
|
24
193
|
|
|
25
|
-
|
|
26
|
-
|
|
194
|
+
1. **STOP** immediately
|
|
195
|
+
2. Do NOT attempt a 4th fix linearly
|
|
196
|
+
3. Use `branchFromThought` to explore a completely different approach
|
|
197
|
+
|
|
198
|
+
---
|
|
27
199
|
|
|
28
|
-
|
|
29
|
-
- `deep_code_analyze`, `search_code`, `file_exists`, `list_directory`
|
|
200
|
+
## 🏃 WORKFLOW TEMPLATES
|
|
30
201
|
|
|
31
|
-
###
|
|
32
|
-
- `deep_code_edit`, `edit_file`, `write_file`, `read_file`, `shell_execute`
|
|
202
|
+
### Template 1: Understanding a New Codebase
|
|
33
203
|
|
|
34
|
-
|
|
35
|
-
|
|
204
|
+
```
|
|
205
|
+
1. build_project_graph(path=".")
|
|
206
|
+
2. get_project_graph_summary()
|
|
207
|
+
3. [For file of interest] get_file_relationships(filePath="src/main.ts")
|
|
208
|
+
4. deep_code_analyze(filePath="src/main.ts", taskDescription="Add X feature")
|
|
209
|
+
```
|
|
36
210
|
|
|
37
|
-
###
|
|
38
|
-
- `web_search`, `read_webpage`, `fetch`
|
|
211
|
+
### Template 2: Making a Code Change
|
|
39
212
|
|
|
40
|
-
|
|
41
|
-
|
|
213
|
+
```
|
|
214
|
+
1. sequentialthinking (analysis) - "Understand current implementation"
|
|
215
|
+
2. sequentialthinking (planning) - "Plan the change"
|
|
216
|
+
3. read_file(path="target.ts")
|
|
217
|
+
4. sequentialthinking (execution) - "Calling edit_file"
|
|
218
|
+
5. edit_file(path, oldText, newText)
|
|
219
|
+
6. sequentialthinking (observation) - "Change applied successfully"
|
|
220
|
+
```
|
|
42
221
|
|
|
43
|
-
###
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
222
|
+
### Template 3: Debugging
|
|
223
|
+
|
|
224
|
+
```
|
|
225
|
+
1. search_code(pattern="error message")
|
|
226
|
+
2. [Review results]
|
|
227
|
+
3. deep_code_analyze(filePath="problematic file")
|
|
228
|
+
4. [Formulate hypothesis]
|
|
229
|
+
5. sequentialthinking (hypothesis) - "I believe X causes Y"
|
|
230
|
+
6. [Test fix]
|
|
231
|
+
7. If fail: branchFromThought to try different approach
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Template 4: Research Task
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
1. sequentialthinking (analysis) - "What do I need to find?"
|
|
238
|
+
2. web_search(query="specific question")
|
|
239
|
+
3. [Review results]
|
|
240
|
+
4. read_webpage(url="most relevant result")
|
|
241
|
+
5. sequentialthinking (observation) - "Key findings: ..."
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## ⚽ SPORTS ANALYSIS MODE
|
|
247
|
+
|
|
248
|
+
When user asks for football/sports analysis, activate the **Professional Analysis Panel**:
|
|
249
|
+
|
|
250
|
+
1. **THE DATA SCIENTIST:** xG trends, possession, Home/Away variance
|
|
251
|
+
2. **THE TACTICAL SCOUT:** Stylistic matchups, key battles
|
|
252
|
+
3. **THE PHYSIO:** Fatigue check, squad depth
|
|
253
|
+
4. **SET PIECE ANALYST:** Corners, aerial duels
|
|
254
|
+
5. **THE INSIDER:** Odds movement, referee, weather
|
|
255
|
+
6. **THE SKEPTIC:** Trap games, what-if scenarios
|
|
256
|
+
|
|
257
|
+
Use `analyze_football_match_v2` for comprehensive data gathering.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## 📊 MEMORY MANAGEMENT
|
|
262
|
+
|
|
263
|
+
- **Thoughts:** Auto-pruned at 100. Use `summarize_history` proactively.
|
|
264
|
+
- **Graph:** Cached in `.gemini_graph_cache.json`. Use `force_rebuild_graph` if stale.
|
|
265
|
+
- **Notes:** Use `priority: "critical"` for important info.
|
|
51
266
|
|
|
52
267
|
---
|
|
53
268
|
|
|
54
|
-
##
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
269
|
+
## ✅ END OF INSTRUCTION
|
|
270
|
+
|
|
271
|
+
**Status:** Supreme Architect Mode v4.0 [Active]
|
|
272
|
+
|
|
273
|
+
**Directives:** Think Deeply. Act Precisely. Provide Expert Multi-Dimensional Sports Analysis.
|
|
58
274
|
|
|
59
275
|
---
|
|
60
|
-
|
|
61
|
-
|
|
276
|
+
|
|
277
|
+
*Last Updated: 2026-01-25 | Version: 2026.2.41*
|
package/dist/http-server.js
CHANGED
|
@@ -23,8 +23,51 @@ import { CodeDatabase } from './codestore.js';
|
|
|
23
23
|
import { validatePath } from './utils.js';
|
|
24
24
|
const app = express();
|
|
25
25
|
const PORT = process.env.PORT || 3000;
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
// ============= Security Configuration =============
|
|
27
|
+
/**
|
|
28
|
+
* CORS Configuration
|
|
29
|
+
* By default, only allows same-origin requests.
|
|
30
|
+
* Set CORS_ORIGIN environment variable to comma-separated list of allowed origins.
|
|
31
|
+
* Examples:
|
|
32
|
+
* - CORS_ORIGIN=* (allow all - NOT RECOMMENDED for production)
|
|
33
|
+
* - CORS_ORIGIN=http://localhost:3000,https://example.com
|
|
34
|
+
*/
|
|
35
|
+
const corsOrigin = process.env.CORS_ORIGIN;
|
|
36
|
+
let corsOptions = {
|
|
37
|
+
origin: false, // Default: deny all cross-origin requests
|
|
38
|
+
credentials: true,
|
|
39
|
+
};
|
|
40
|
+
if (corsOrigin === '*') {
|
|
41
|
+
console.warn('⚠️ WARNING: CORS set to allow all origins (*). This is not secure for production!');
|
|
42
|
+
corsOptions.origin = true;
|
|
43
|
+
}
|
|
44
|
+
else if (corsOrigin) {
|
|
45
|
+
const allowedOrigins = corsOrigin.split(',').map(o => o.trim());
|
|
46
|
+
corsOptions.origin = function (origin, callback) {
|
|
47
|
+
// Allow requests with no origin (like mobile apps, curl, Postman)
|
|
48
|
+
if (!origin)
|
|
49
|
+
return callback(null, true);
|
|
50
|
+
if (allowedOrigins.indexOf(origin) !== -1 || allowedOrigins.includes('*')) {
|
|
51
|
+
callback(null, true);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
callback(new Error(`CORS: Origin '${origin}' not allowed`));
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
app.use(cors(corsOptions));
|
|
59
|
+
/**
|
|
60
|
+
* Request Body Size Limit
|
|
61
|
+
* Prevents DoS attacks via huge payload requests.
|
|
62
|
+
* Override with BODY_LIMIT environment variable (e.g., '10mb', '1mb')
|
|
63
|
+
* Default: 10mb
|
|
64
|
+
*/
|
|
65
|
+
const bodyLimit = process.env.BODY_LIMIT || '10mb';
|
|
66
|
+
app.use(express.json({ limit: bodyLimit }));
|
|
67
|
+
// Log security configuration on startup
|
|
68
|
+
console.log(`Security Configuration:`);
|
|
69
|
+
console.log(` CORS: ${corsOrigin === '*' ? 'OPEN (all origins)' : corsOrigin ? `Restricted to: ${corsOrigin}` : 'Same-origin only'}`);
|
|
70
|
+
console.log(` Body Limit: ${bodyLimit}`);
|
|
28
71
|
/**
|
|
29
72
|
* ============================================================================
|
|
30
73
|
* SINGLETON MANAGERS
|
package/dist/tools/filesystem.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import * as fs from 'fs/promises';
|
|
3
3
|
import * as path from 'path';
|
|
4
|
-
import { execAsync, validatePath } from "../utils.js";
|
|
4
|
+
import { execAsync, validatePath, createSafeRegex } from "../utils.js";
|
|
5
5
|
/**
|
|
6
6
|
* Default file extensions to search
|
|
7
7
|
* Covers common programming languages, config files, and text formats
|
|
@@ -258,11 +258,12 @@ export function registerFileSystemTools(server) {
|
|
|
258
258
|
const lines = content.split('\n');
|
|
259
259
|
let regex;
|
|
260
260
|
if (useRegex) {
|
|
261
|
-
|
|
261
|
+
// Use safe regex creation to prevent ReDoS attacks
|
|
262
|
+
regex = createSafeRegex(pattern, caseSensitive ? 'g' : 'gi');
|
|
262
263
|
}
|
|
263
264
|
else {
|
|
264
265
|
const escaped = pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
265
|
-
regex =
|
|
266
|
+
regex = createSafeRegex(escaped, caseSensitive ? 'g' : 'gi');
|
|
266
267
|
}
|
|
267
268
|
lines.forEach((line, index) => {
|
|
268
269
|
if (matchCount >= maxResults)
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPORTS MODULE BASE CLASSES
|
|
3
|
+
* Abstract base classes and interfaces for data providers
|
|
4
|
+
*/
|
|
5
|
+
import { Match, Team, Player, TableEntry, APIResponse, ProviderStatus, ProviderType } from './types.js';
|
|
6
|
+
import { CacheService } from './cache.js';
|
|
7
|
+
/**
|
|
8
|
+
* Base interface for all data providers
|
|
9
|
+
*/
|
|
10
|
+
export interface IDataProvider {
|
|
11
|
+
/**
|
|
12
|
+
* Provider name/type
|
|
13
|
+
*/
|
|
14
|
+
readonly type: ProviderType;
|
|
15
|
+
/**
|
|
16
|
+
* Check if provider is available
|
|
17
|
+
*/
|
|
18
|
+
isAvailable(): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Get provider status
|
|
21
|
+
*/
|
|
22
|
+
getStatus(): ProviderStatus;
|
|
23
|
+
/**
|
|
24
|
+
* Fetch a match by ID
|
|
25
|
+
*/
|
|
26
|
+
getMatch(matchId: string): Promise<APIResponse<Match>>;
|
|
27
|
+
/**
|
|
28
|
+
* Fetch live matches for a league
|
|
29
|
+
*/
|
|
30
|
+
getLiveMatches(leagueId?: string): Promise<APIResponse<Match[]>>;
|
|
31
|
+
/**
|
|
32
|
+
* Fetch league standings
|
|
33
|
+
*/
|
|
34
|
+
getStandings(leagueId: string, season?: string): Promise<APIResponse<TableEntry[]>>;
|
|
35
|
+
/**
|
|
36
|
+
* Fetch team information
|
|
37
|
+
*/
|
|
38
|
+
getTeam(teamId: string): Promise<APIResponse<Team>>;
|
|
39
|
+
/**
|
|
40
|
+
* Fetch player information
|
|
41
|
+
*/
|
|
42
|
+
getPlayer(playerId: string): Promise<APIResponse<Player>>;
|
|
43
|
+
/**
|
|
44
|
+
* Search for teams
|
|
45
|
+
*/
|
|
46
|
+
searchTeams(query: string): Promise<APIResponse<Team[]>>;
|
|
47
|
+
/**
|
|
48
|
+
* Search for players
|
|
49
|
+
*/
|
|
50
|
+
searchPlayers(query: string): Promise<APIResponse<Player[]>>;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Abstract base class for API-based providers
|
|
54
|
+
*/
|
|
55
|
+
export declare abstract class APIProviderBase implements IDataProvider {
|
|
56
|
+
readonly type: ProviderType;
|
|
57
|
+
protected apiKey: string;
|
|
58
|
+
protected baseUrl: string;
|
|
59
|
+
protected rateLimit: number;
|
|
60
|
+
protected cache: CacheService;
|
|
61
|
+
protected rateLimitUntil: Date | null;
|
|
62
|
+
protected lastCall: Date | null;
|
|
63
|
+
protected callCount: number;
|
|
64
|
+
constructor(type: ProviderType, apiKey: string, baseUrl: string, rateLimit?: number);
|
|
65
|
+
/**
|
|
66
|
+
* Check if provider has valid credentials
|
|
67
|
+
*/
|
|
68
|
+
isAvailable(): boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Check if currently rate limited
|
|
71
|
+
*/
|
|
72
|
+
isRateLimited(): boolean;
|
|
73
|
+
/**
|
|
74
|
+
* Get current provider status
|
|
75
|
+
*/
|
|
76
|
+
getStatus(): ProviderStatus;
|
|
77
|
+
/**
|
|
78
|
+
* Abstract methods to be implemented by concrete providers
|
|
79
|
+
*/
|
|
80
|
+
abstract getMatch(matchId: string): Promise<APIResponse<Match>>;
|
|
81
|
+
abstract getLiveMatches(leagueId?: string): Promise<APIResponse<Match[]>>;
|
|
82
|
+
abstract getStandings(leagueId: string, season?: string): Promise<APIResponse<TableEntry[]>>;
|
|
83
|
+
abstract getTeam(teamId: string): Promise<APIResponse<Team>>;
|
|
84
|
+
abstract getPlayer(playerId: string): Promise<APIResponse<Player>>;
|
|
85
|
+
abstract searchTeams(query: string): Promise<APIResponse<Team[]>>;
|
|
86
|
+
abstract searchPlayers(query: string): Promise<APIResponse<Player[]>>;
|
|
87
|
+
/**
|
|
88
|
+
* Make a rate-limited API call
|
|
89
|
+
*/
|
|
90
|
+
protected callAPI<T>(endpoint: string, options?: RequestInit): Promise<APIResponse<T>>;
|
|
91
|
+
/**
|
|
92
|
+
* Get authentication headers for the API
|
|
93
|
+
*/
|
|
94
|
+
protected abstract getAuthHeaders(): Record<string, string>;
|
|
95
|
+
/**
|
|
96
|
+
* Transform raw API response to standard format
|
|
97
|
+
*/
|
|
98
|
+
protected abstract transformResponse<T>(data: any): T;
|
|
99
|
+
/**
|
|
100
|
+
* Reset rate limit tracking (for testing)
|
|
101
|
+
*/
|
|
102
|
+
resetRateLimit(): void;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Abstract base class for scraper-based providers
|
|
106
|
+
*/
|
|
107
|
+
export declare abstract class ScraperProviderBase implements IDataProvider {
|
|
108
|
+
protected cache: CacheService;
|
|
109
|
+
readonly type: ProviderType;
|
|
110
|
+
constructor();
|
|
111
|
+
isAvailable(): boolean;
|
|
112
|
+
getStatus(): ProviderStatus;
|
|
113
|
+
abstract getMatch(matchId: string): Promise<APIResponse<Match>>;
|
|
114
|
+
abstract getLiveMatches(leagueId?: string): Promise<APIResponse<Match[]>>;
|
|
115
|
+
abstract getStandings(leagueId: string, season?: string): Promise<APIResponse<TableEntry[]>>;
|
|
116
|
+
abstract getTeam(teamId: string): Promise<APIResponse<Team>>;
|
|
117
|
+
abstract getPlayer(playerId: string): Promise<APIResponse<Player>>;
|
|
118
|
+
abstract searchTeams(query: string): Promise<APIResponse<Team[]>>;
|
|
119
|
+
abstract searchPlayers(query: string): Promise<APIResponse<Player[]>>;
|
|
120
|
+
/**
|
|
121
|
+
* Scrape a webpage and extract structured data
|
|
122
|
+
*/
|
|
123
|
+
protected scrape<T>(url: string, extractor: (html: string) => T): Promise<APIResponse<T>>;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Fallback provider that tries multiple sources in order
|
|
127
|
+
*/
|
|
128
|
+
export declare class FallbackProvider implements IDataProvider {
|
|
129
|
+
private providers;
|
|
130
|
+
private cache;
|
|
131
|
+
readonly type: ProviderType;
|
|
132
|
+
constructor(providers: IDataProvider[], cache?: CacheService);
|
|
133
|
+
isAvailable(): boolean;
|
|
134
|
+
getStatus(): ProviderStatus;
|
|
135
|
+
/**
|
|
136
|
+
* Try each provider in sequence until one succeeds
|
|
137
|
+
*/
|
|
138
|
+
private tryProviders;
|
|
139
|
+
getMatch(matchId: string): Promise<APIResponse<Match>>;
|
|
140
|
+
getLiveMatches(leagueId?: string): Promise<APIResponse<Match[]>>;
|
|
141
|
+
getStandings(leagueId: string, season?: string): Promise<APIResponse<TableEntry[]>>;
|
|
142
|
+
getTeam(teamId: string): Promise<APIResponse<Team>>;
|
|
143
|
+
getPlayer(playerId: string): Promise<APIResponse<Player>>;
|
|
144
|
+
searchTeams(query: string): Promise<APIResponse<Team[]>>;
|
|
145
|
+
searchPlayers(query: string): Promise<APIResponse<Player[]>>;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Base class for sports tools
|
|
149
|
+
*/
|
|
150
|
+
export declare abstract class SportsToolBase {
|
|
151
|
+
protected cache: CacheService;
|
|
152
|
+
constructor(cache?: CacheService);
|
|
153
|
+
/**
|
|
154
|
+
* Format error message for user
|
|
155
|
+
*/
|
|
156
|
+
protected formatError(error: unknown, context: string): string;
|
|
157
|
+
/**
|
|
158
|
+
* Sanitize user input
|
|
159
|
+
*/
|
|
160
|
+
protected sanitizeInput(input: string): string;
|
|
161
|
+
/**
|
|
162
|
+
* Format a team name for search
|
|
163
|
+
*/
|
|
164
|
+
protected formatTeamName(name: string): string;
|
|
165
|
+
/**
|
|
166
|
+
* Format date to readable string
|
|
167
|
+
*/
|
|
168
|
+
protected formatDate(date: Date): string;
|
|
169
|
+
}
|