@matimo/core 0.1.0-alpha.10
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 +252 -0
- package/destructive-keywords.yaml +70 -0
- package/dist/approval/approval-handler.d.ts +74 -0
- package/dist/approval/approval-handler.d.ts.map +1 -0
- package/dist/approval/approval-handler.js +210 -0
- package/dist/approval/approval-handler.js.map +1 -0
- package/dist/auth/oauth2-config.d.ts +104 -0
- package/dist/auth/oauth2-config.d.ts.map +1 -0
- package/dist/auth/oauth2-config.js +38 -0
- package/dist/auth/oauth2-config.js.map +1 -0
- package/dist/auth/oauth2-handler.d.ts +130 -0
- package/dist/auth/oauth2-handler.d.ts.map +1 -0
- package/dist/auth/oauth2-handler.js +265 -0
- package/dist/auth/oauth2-handler.js.map +1 -0
- package/dist/auth/oauth2-provider-loader.d.ts +68 -0
- package/dist/auth/oauth2-provider-loader.d.ts.map +1 -0
- package/dist/auth/oauth2-provider-loader.js +120 -0
- package/dist/auth/oauth2-provider-loader.js.map +1 -0
- package/dist/core/schema.d.ts +259 -0
- package/dist/core/schema.d.ts.map +1 -0
- package/dist/core/schema.js +187 -0
- package/dist/core/schema.js.map +1 -0
- package/dist/core/tool-loader.d.ts +57 -0
- package/dist/core/tool-loader.d.ts.map +1 -0
- package/dist/core/tool-loader.js +250 -0
- package/dist/core/tool-loader.js.map +1 -0
- package/dist/core/tool-registry.d.ts +48 -0
- package/dist/core/tool-registry.d.ts.map +1 -0
- package/dist/core/tool-registry.js +93 -0
- package/dist/core/tool-registry.js.map +1 -0
- package/dist/core/types.d.ts +162 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/decorators/index.d.ts +2 -0
- package/dist/decorators/index.d.ts.map +1 -0
- package/dist/decorators/index.js +2 -0
- package/dist/decorators/index.js.map +1 -0
- package/dist/decorators/tool-decorator.d.ts +97 -0
- package/dist/decorators/tool-decorator.d.ts.map +1 -0
- package/dist/decorators/tool-decorator.js +157 -0
- package/dist/decorators/tool-decorator.js.map +1 -0
- package/dist/encodings/parameter-encoding.d.ts +51 -0
- package/dist/encodings/parameter-encoding.d.ts.map +1 -0
- package/dist/encodings/parameter-encoding.js +124 -0
- package/dist/encodings/parameter-encoding.js.map +1 -0
- package/dist/errors/matimo-error.d.ts +41 -0
- package/dist/errors/matimo-error.d.ts.map +1 -0
- package/dist/errors/matimo-error.js +71 -0
- package/dist/errors/matimo-error.js.map +1 -0
- package/dist/executors/command-executor.d.ts +19 -0
- package/dist/executors/command-executor.d.ts.map +1 -0
- package/dist/executors/command-executor.js +98 -0
- package/dist/executors/command-executor.js.map +1 -0
- package/dist/executors/function-executor.d.ts +23 -0
- package/dist/executors/function-executor.d.ts.map +1 -0
- package/dist/executors/function-executor.js +181 -0
- package/dist/executors/function-executor.js.map +1 -0
- package/dist/executors/http-executor.d.ts +78 -0
- package/dist/executors/http-executor.d.ts.map +1 -0
- package/dist/executors/http-executor.js +279 -0
- package/dist/executors/http-executor.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/langchain.d.ts +46 -0
- package/dist/integrations/langchain.d.ts.map +1 -0
- package/dist/integrations/langchain.js +197 -0
- package/dist/integrations/langchain.js.map +1 -0
- package/dist/logging/index.d.ts +3 -0
- package/dist/logging/index.d.ts.map +1 -0
- package/dist/logging/index.js +3 -0
- package/dist/logging/index.js.map +1 -0
- package/dist/logging/logger.d.ts +96 -0
- package/dist/logging/logger.d.ts.map +1 -0
- package/dist/logging/logger.js +53 -0
- package/dist/logging/logger.js.map +1 -0
- package/dist/logging/winston-logger.d.ts +29 -0
- package/dist/logging/winston-logger.d.ts.map +1 -0
- package/dist/logging/winston-logger.js +73 -0
- package/dist/logging/winston-logger.js.map +1 -0
- package/dist/matimo-instance.d.ts +140 -0
- package/dist/matimo-instance.d.ts.map +1 -0
- package/dist/matimo-instance.js +412 -0
- package/dist/matimo-instance.js.map +1 -0
- package/package.json +96 -0
- package/tools/calculator/calculator.ts +145 -0
- package/tools/calculator/definition.yaml +70 -0
- package/tools/edit/definition.yaml +115 -0
- package/tools/edit/edit.ts +187 -0
- package/tools/execute/definition.yaml +90 -0
- package/tools/execute/execute.ts +207 -0
- package/tools/read/definition.yaml +106 -0
- package/tools/read/read.ts +118 -0
- package/tools/search/definition.yaml +148 -0
- package/tools/search/search.ts +192 -0
- package/tools/web/definition.yaml +132 -0
- package/tools/web/web.ts +134 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 tallclub
|
|
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,252 @@
|
|
|
1
|
+
# @matimo/core — Core SDK for Matimo
|
|
2
|
+
|
|
3
|
+
Matimo core provides the TypeScript SDK that loads, validates, and executes YAML-defined tools across frameworks.
|
|
4
|
+
|
|
5
|
+
## 📦 Installation
|
|
6
|
+
|
|
7
|
+
Install the unified package (includes core exports):
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# install unscope package which includes core and cli
|
|
11
|
+
npm install matimo
|
|
12
|
+
pnpm add matimo
|
|
13
|
+
# or install scoped core package directly
|
|
14
|
+
npm insatll @matimo/core
|
|
15
|
+
pnpm add @matimo/core
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## 🔧 Purpose
|
|
19
|
+
|
|
20
|
+
`@matimo/core` contains:
|
|
21
|
+
|
|
22
|
+
- `MatimoInstance` — initialization, discovery, registry, and execution API
|
|
23
|
+
- **Executors** — Command (shell), HTTP (REST with object/array embedding), Function (JS/TS)
|
|
24
|
+
- Decorator utilities (`@tool`, `setGlobalMatimoInstance`)
|
|
25
|
+
- Zod-based schema validation for YAML tool definitions
|
|
26
|
+
- **Structured error handling** — `MatimoError` with error chaining via optional `cause` field
|
|
27
|
+
- OAuth2 authentication support (provider integrations in separate packages)
|
|
28
|
+
|
|
29
|
+
This package is intended to be imported by applications, CLIs, and provider packages.
|
|
30
|
+
|
|
31
|
+
## 🚀 Quick Start
|
|
32
|
+
|
|
33
|
+
```typescript
|
|
34
|
+
import { MatimoInstance } from 'matimo';
|
|
35
|
+
|
|
36
|
+
// Auto-discover installed @matimo/* tool packages
|
|
37
|
+
const matimo = await MatimoInstance.init({ autoDiscover: true });
|
|
38
|
+
|
|
39
|
+
// List tools
|
|
40
|
+
console.log('Loaded', matimo.listTools().length, 'tools');
|
|
41
|
+
|
|
42
|
+
// Execute a tool
|
|
43
|
+
await matimo.execute('calculator', { operation: 'add', a: 1, b: 2 });
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## 🛠 Included Core Tools
|
|
47
|
+
|
|
48
|
+
`@matimo/core` includes 6 built-in tools for common operations:
|
|
49
|
+
|
|
50
|
+
- **`execute`** — Run shell commands with output capture, timeout, and working directory control
|
|
51
|
+
- **`read`** — Read files with line range support and encoding detection
|
|
52
|
+
- **`edit`** — Edit/replace content in files with backup
|
|
53
|
+
- **`search`** — Search files with grep patterns and context
|
|
54
|
+
- **`web`** — Fetch and parse web content
|
|
55
|
+
- **`calculator`** — Basic arithmetic operations
|
|
56
|
+
|
|
57
|
+
All core tools use **function-based execution** (not shell commands) for better performance and reliability.
|
|
58
|
+
|
|
59
|
+
## 🧩 Usage Patterns
|
|
60
|
+
|
|
61
|
+
- Factory pattern: `MatimoInstance.init()` + `matimo.execute()`
|
|
62
|
+
- Decorator pattern: use `@tool()` and `setGlobalMatimoInstance()` for class-based code
|
|
63
|
+
- LangChain integration: convert Matimo tools to LangChain function schemas
|
|
64
|
+
|
|
65
|
+
See the full SDK docs: [docs/api-reference/SDK.md](../../docs/api-reference/SDK.md)
|
|
66
|
+
|
|
67
|
+
## ⚙️ Executors
|
|
68
|
+
|
|
69
|
+
`@matimo/core` provides three execution engines:
|
|
70
|
+
|
|
71
|
+
### FunctionExecutor (Recommended for Core Tools)
|
|
72
|
+
Executes TypeScript/JavaScript functions with type-safe parameters:
|
|
73
|
+
- ✅ **Direct execution** — No subprocess overhead
|
|
74
|
+
- ✅ **Better performance** — Direct async function calls
|
|
75
|
+
- ✅ **Type safety** — Proper TypeScript integration
|
|
76
|
+
- ✅ **Error handling** — Native exception handling
|
|
77
|
+
|
|
78
|
+
**Core tools** (`execute`, `read`, `edit`, `search`, `web`, `calculator`) all use function-based execution:
|
|
79
|
+
```yaml
|
|
80
|
+
# Tool YAML:
|
|
81
|
+
execution:
|
|
82
|
+
type: function
|
|
83
|
+
code: './execute.ts' # Relative path to implementation
|
|
84
|
+
|
|
85
|
+
# File: execute.ts
|
|
86
|
+
export default async function execute(params: {
|
|
87
|
+
command: string
|
|
88
|
+
args?: string[]
|
|
89
|
+
cwd?: string
|
|
90
|
+
timeout?: number
|
|
91
|
+
}): Promise<{ success: boolean; stdout: string; stderr: string; exitCode: number }> {
|
|
92
|
+
// Implementation here
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### HttpExecutor
|
|
97
|
+
Makes HTTP requests with automatic parameter embedding and response validation:
|
|
98
|
+
```yaml
|
|
99
|
+
# Tool YAML:
|
|
100
|
+
execution:
|
|
101
|
+
type: http
|
|
102
|
+
method: POST
|
|
103
|
+
url: https://api.example.com/data
|
|
104
|
+
headers:
|
|
105
|
+
Authorization: 'Bearer {AUTH_TOKEN}'
|
|
106
|
+
body:
|
|
107
|
+
text: '{text}'
|
|
108
|
+
metadata: '{metadata}' # Objects/arrays automatically JSON-encoded
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Key features:**
|
|
112
|
+
- ✅ **Parameter embedding** — Objects and arrays automatically JSON-encoded in request body
|
|
113
|
+
- ✅ **Response validation** — Validates output against `output_schema` using Zod
|
|
114
|
+
- ✅ **Error normalization** — Converts Axios/HTTP errors to structured `MatimoError`
|
|
115
|
+
- ✅ **Structured error details** — Original error preserved via `error.cause` field
|
|
116
|
+
|
|
117
|
+
### CommandExecutor (Legacy Shell Execution)
|
|
118
|
+
Spawns shell processes for external commands:
|
|
119
|
+
```typescript
|
|
120
|
+
// Tool YAML:
|
|
121
|
+
execution:
|
|
122
|
+
type: command
|
|
123
|
+
command: node
|
|
124
|
+
args: ["script.js", "{param1}"]
|
|
125
|
+
|
|
126
|
+
// Spawns: node script.js value1
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Use when:**
|
|
130
|
+
- Executing external shell commands or legacy scripts
|
|
131
|
+
- Running tools from other packages that expect shell execution
|
|
132
|
+
- Most core Matimo tools now use function-based execution instead
|
|
133
|
+
|
|
134
|
+
## 🚨 Error Handling
|
|
135
|
+
|
|
136
|
+
All executors throw `MatimoError` (never generic `Error`) with structured context:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { MatimoError, ErrorCode } from '@matimo/core';
|
|
140
|
+
|
|
141
|
+
try {
|
|
142
|
+
await matimo.execute('my-tool', params);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
if (error instanceof MatimoError) {
|
|
145
|
+
console.error(`Error: ${error.message}`);
|
|
146
|
+
console.error(`Code: ${error.code}`);
|
|
147
|
+
console.error(`Details:`, error.details);
|
|
148
|
+
|
|
149
|
+
// Access original exception (if available)
|
|
150
|
+
if (error.cause) {
|
|
151
|
+
console.error(`Original error:`, error.cause);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Error codes:**
|
|
158
|
+
- `INVALID_SCHEMA` — Tool definition or parameters invalid
|
|
159
|
+
- `EXECUTION_FAILED` — Tool execution failed (network, timeout, etc.)
|
|
160
|
+
- `AUTH_FAILED` — Authentication/authorization error
|
|
161
|
+
- `TOOL_NOT_FOUND` — Tool not found in registry
|
|
162
|
+
|
|
163
|
+
**Error chaining:**
|
|
164
|
+
The optional `cause` field preserves the original error for debugging:
|
|
165
|
+
```typescript
|
|
166
|
+
throw new MatimoError('HTTP request failed', ErrorCode.EXECUTION_FAILED, {
|
|
167
|
+
toolName: 'slack_send',
|
|
168
|
+
statusCode: 500,
|
|
169
|
+
details: { originalError: axiosError }
|
|
170
|
+
});
|
|
171
|
+
// Access via: error.cause or error.details.originalError
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
## 🔐 Authentication & Security
|
|
175
|
+
|
|
176
|
+
Tools declare authentication requirements in YAML. `@matimo/core` supports:
|
|
177
|
+
|
|
178
|
+
- **API keys** (header/query injection)
|
|
179
|
+
- **Bearer/basic tokens** (automatic injection)
|
|
180
|
+
- **OAuth2** (provider configurations via OAuth2Handler)
|
|
181
|
+
|
|
182
|
+
Credentials are loaded from environment variables by convention:
|
|
183
|
+
```bash
|
|
184
|
+
export SLACK_BOT_TOKEN=xoxb-...
|
|
185
|
+
export GMAIL_ACCESS_TOKEN=ya29-...
|
|
186
|
+
export NOTION_API_KEY=ntn_...
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Security notes:**
|
|
190
|
+
- ✅ Secrets never logged (error messages exclude credential values)
|
|
191
|
+
- ✅ OAuth tokens refreshed automatically when expired
|
|
192
|
+
- ✅ HTTP Executor validates all authentication before making requests
|
|
193
|
+
- ✅ Missing credentials throw `MatimoError(AUTH_FAILED)` with helpful guidance
|
|
194
|
+
|
|
195
|
+
## ✅ Validation & Output Schema
|
|
196
|
+
|
|
197
|
+
All tool execution includes automatic validation:
|
|
198
|
+
|
|
199
|
+
**Input Validation:**
|
|
200
|
+
- Tool YAML definitions validated against Zod schema on load
|
|
201
|
+
- Parameters validated against tool's declared `parameters` schema
|
|
202
|
+
- Invalid parameters throw `MatimoError(INVALID_SCHEMA)`
|
|
203
|
+
|
|
204
|
+
**Output Validation:**
|
|
205
|
+
- HTTP executor validates response against tool's `output_schema`
|
|
206
|
+
- Function executor validates return value against `output_schema` (for HTTP tools)
|
|
207
|
+
- Invalid responses/returns throw `MatimoError(EXECUTION_FAILED)`
|
|
208
|
+
- Zod provides detailed validation error messages
|
|
209
|
+
|
|
210
|
+
**Example (core `execute` tool):**
|
|
211
|
+
```yaml
|
|
212
|
+
# Definition: packages/core/tools/execute/definition.yaml
|
|
213
|
+
execution:
|
|
214
|
+
type: function
|
|
215
|
+
code: './execute.ts'
|
|
216
|
+
|
|
217
|
+
output_schema:
|
|
218
|
+
type: object
|
|
219
|
+
properties:
|
|
220
|
+
success: { type: boolean }
|
|
221
|
+
exitCode: { type: number }
|
|
222
|
+
stdout: { type: string }
|
|
223
|
+
stderr: { type: string }
|
|
224
|
+
required: [success, exitCode, stdout, stderr]
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Invalid parameters or responses trigger validation errors with structured details.
|
|
228
|
+
|
|
229
|
+
## 🧪 Testing & Development
|
|
230
|
+
|
|
231
|
+
To run core package tests:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
pnpm --filter "@matimo/core" test
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
To build:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
pnpm --filter "@matimo/core" build
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## 📚 Contributing
|
|
244
|
+
|
|
245
|
+
See the project CONTRIBUTING guide and `docs/tool-development/ADDING_TOOLS.md` for adding provider packages and tools.
|
|
246
|
+
|
|
247
|
+
- Contributing: https://github.com/tallclub/matimo/blob/main/CONTRIBUTING.md
|
|
248
|
+
- Add tools: ../../docs/tool-development/ADDING_TOOLS.md
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
Part of the Matimo ecosystem — define tools once, use them everywhere.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Destructive keywords used by ApprovalHandler and execution tools to auto-detect operations requiring approval
|
|
2
|
+
# These are checked against SQL content, command parameters, and shell commands to determine if approval is needed
|
|
3
|
+
|
|
4
|
+
sql:
|
|
5
|
+
- CREATE
|
|
6
|
+
- DELETE
|
|
7
|
+
- DROP
|
|
8
|
+
- ALTER
|
|
9
|
+
- TRUNCATE
|
|
10
|
+
- UPDATE
|
|
11
|
+
- INSERT
|
|
12
|
+
- UPSERT
|
|
13
|
+
- REPLACE
|
|
14
|
+
- MERGE
|
|
15
|
+
- GRANT
|
|
16
|
+
- REVOKE
|
|
17
|
+
|
|
18
|
+
file:
|
|
19
|
+
- EDIT
|
|
20
|
+
- WRITE
|
|
21
|
+
- APPEND
|
|
22
|
+
- REMOVE
|
|
23
|
+
- RENAME
|
|
24
|
+
|
|
25
|
+
system:
|
|
26
|
+
- SHUTDOWN
|
|
27
|
+
- EXECUTE
|
|
28
|
+
- EXEC
|
|
29
|
+
- system
|
|
30
|
+
- cmd
|
|
31
|
+
- shell
|
|
32
|
+
- bash
|
|
33
|
+
- powershell
|
|
34
|
+
- "rm -rf"
|
|
35
|
+
- "del /f"
|
|
36
|
+
|
|
37
|
+
shell_commands:
|
|
38
|
+
# File deletion/removal
|
|
39
|
+
- rm
|
|
40
|
+
- rmdir
|
|
41
|
+
- del
|
|
42
|
+
- "del /f"
|
|
43
|
+
- "rd /s"
|
|
44
|
+
# File/directory creation (modifies filesystem)
|
|
45
|
+
- mkdir
|
|
46
|
+
- mkfile
|
|
47
|
+
- touch
|
|
48
|
+
# File operations (modify destination)
|
|
49
|
+
- cp
|
|
50
|
+
- mv
|
|
51
|
+
- copy
|
|
52
|
+
- move
|
|
53
|
+
# Version control modifications
|
|
54
|
+
- "git push"
|
|
55
|
+
- "git merge"
|
|
56
|
+
- "git commit"
|
|
57
|
+
- "git reset"
|
|
58
|
+
- "git rebase"
|
|
59
|
+
# Database CLIs
|
|
60
|
+
- isql
|
|
61
|
+
- sqlcmd
|
|
62
|
+
- psql
|
|
63
|
+
- mysql
|
|
64
|
+
# Disk/system modifications
|
|
65
|
+
- format
|
|
66
|
+
- fastboot
|
|
67
|
+
- "adb shell su"
|
|
68
|
+
- "adb shell rm"
|
|
69
|
+
- "adb shell mount"
|
|
70
|
+
- "adb shell reboot"
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Approval request for any tool operation
|
|
3
|
+
*/
|
|
4
|
+
export interface ApprovalRequest {
|
|
5
|
+
toolName: string;
|
|
6
|
+
description?: string;
|
|
7
|
+
params: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Generic approval callback - simple and scalable
|
|
11
|
+
* Returns true if approved, false if rejected or user declines
|
|
12
|
+
*/
|
|
13
|
+
export type ApprovalCallback = (request: ApprovalRequest) => Promise<boolean>;
|
|
14
|
+
/**
|
|
15
|
+
* Generic, simple approval handler for all tools
|
|
16
|
+
*
|
|
17
|
+
* Design: Single, scalable approval flow for any number of tools
|
|
18
|
+
* - Tools declare requires_approval in YAML OR contain destructive keywords
|
|
19
|
+
* - Check MATIMO_AUTO_APPROVE env var (approve all)
|
|
20
|
+
* - Check MATIMO_APPROVED_PATTERNS env var (pre-approved patterns)
|
|
21
|
+
* - If not pre-approved, invoke single generic callback
|
|
22
|
+
* - No per-provider validators or custom logic needed
|
|
23
|
+
*/
|
|
24
|
+
export declare class ApprovalHandler {
|
|
25
|
+
private autoApprove;
|
|
26
|
+
private approvedPatterns;
|
|
27
|
+
private approvalCallback;
|
|
28
|
+
private destructiveKeywords;
|
|
29
|
+
constructor();
|
|
30
|
+
/**
|
|
31
|
+
* Load destructive keywords from YAML configuration file
|
|
32
|
+
* Searches for destructive-keywords.yaml in:
|
|
33
|
+
* 1. packages/core/ (development/workspace)
|
|
34
|
+
* 2. node_modules/@matimo/core/ (installed package)
|
|
35
|
+
* 3. Relative to current working directory
|
|
36
|
+
*/
|
|
37
|
+
private loadDestructiveKeywords;
|
|
38
|
+
/**
|
|
39
|
+
* Set default destructive keywords
|
|
40
|
+
*/
|
|
41
|
+
private useDefaultKeywords;
|
|
42
|
+
/**
|
|
43
|
+
* Set approval callback for interactive/custom approval
|
|
44
|
+
*/
|
|
45
|
+
setApprovalCallback(callback: ApprovalCallback): void;
|
|
46
|
+
/**
|
|
47
|
+
* Check if a tool requires approval based on YAML definition or supplied content.
|
|
48
|
+
* @param requiresApproval In Yaml - From tool definition `requires_approval` field
|
|
49
|
+
* @param content - Optional content (SQL, shell command, etc.) to check for destructive keywords
|
|
50
|
+
*
|
|
51
|
+
* Notes:
|
|
52
|
+
* - We now accept any textual content so keyword detection also applies to command/shell and sql
|
|
53
|
+
* based tools (e.g. `params.command`).
|
|
54
|
+
*/
|
|
55
|
+
requiresApproval(requiresApprovalInYaml: boolean | undefined, content?: string): boolean;
|
|
56
|
+
/**
|
|
57
|
+
* Check if operation is pre-approved via env vars
|
|
58
|
+
*/
|
|
59
|
+
isPreApproved(toolName: string): boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Request approval for an operation
|
|
62
|
+
* Throws if not approved and no callback available
|
|
63
|
+
*/
|
|
64
|
+
requestApproval(request: ApprovalRequest): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Simple pattern matching (supports wildcards)
|
|
67
|
+
*/
|
|
68
|
+
private matchesPattern;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Get or create global approval handler
|
|
72
|
+
*/
|
|
73
|
+
export declare function getGlobalApprovalHandler(): ApprovalHandler;
|
|
74
|
+
//# sourceMappingURL=approval-handler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-handler.d.ts","sourceRoot":"","sources":["../../src/approval/approval-handler.ts"],"names":[],"mappings":"AAIA;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,EAAE,eAAe,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE9E;;;;;;;;;GASG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,WAAW,CAAkB;IACrC,OAAO,CAAC,gBAAgB,CAA0B;IAClD,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,mBAAmB,CAAgB;;IAsB3C;;;;;;OAMG;IACH,OAAO,CAAC,uBAAuB;IAqD/B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyB1B;;OAEG;IACH,mBAAmB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,IAAI;IAIrD;;;;;;;;OAQG;IACH,gBAAgB,CAAC,sBAAsB,EAAE,OAAO,GAAG,SAAS,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO;IAexF;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAgBxC;;;OAGG;IACG,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IA2B9D;;OAEG;IACH,OAAO,CAAC,cAAc;CAavB;AAKD;;GAEG;AACH,wBAAgB,wBAAwB,IAAI,eAAe,CAK1D"}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { MatimoError, ErrorCode } from '../errors/matimo-error';
|
|
4
|
+
/**
|
|
5
|
+
* Generic, simple approval handler for all tools
|
|
6
|
+
*
|
|
7
|
+
* Design: Single, scalable approval flow for any number of tools
|
|
8
|
+
* - Tools declare requires_approval in YAML OR contain destructive keywords
|
|
9
|
+
* - Check MATIMO_AUTO_APPROVE env var (approve all)
|
|
10
|
+
* - Check MATIMO_APPROVED_PATTERNS env var (pre-approved patterns)
|
|
11
|
+
* - If not pre-approved, invoke single generic callback
|
|
12
|
+
* - No per-provider validators or custom logic needed
|
|
13
|
+
*/
|
|
14
|
+
export class ApprovalHandler {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.autoApprove = false;
|
|
17
|
+
this.approvedPatterns = new Set();
|
|
18
|
+
this.approvalCallback = null;
|
|
19
|
+
this.destructiveKeywords = [];
|
|
20
|
+
// Load destructive keywords from YAML configuration
|
|
21
|
+
this.loadDestructiveKeywords();
|
|
22
|
+
// Load from environment variables
|
|
23
|
+
this.autoApprove = process.env.MATIMO_AUTO_APPROVE === 'true';
|
|
24
|
+
// Load pre-approved patterns (comma-separated)
|
|
25
|
+
// Example: "tool-name,pattern-*,prefix-*"
|
|
26
|
+
const approvedEnv = process.env.MATIMO_APPROVED_PATTERNS || '';
|
|
27
|
+
if (approvedEnv) {
|
|
28
|
+
approvedEnv.split(',').forEach((pattern) => {
|
|
29
|
+
const trimmed = pattern.trim();
|
|
30
|
+
if (trimmed) {
|
|
31
|
+
this.approvedPatterns.add(trimmed);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Load destructive keywords from YAML configuration file
|
|
38
|
+
* Searches for destructive-keywords.yaml in:
|
|
39
|
+
* 1. packages/core/ (development/workspace)
|
|
40
|
+
* 2. node_modules/@matimo/core/ (installed package)
|
|
41
|
+
* 3. Relative to current working directory
|
|
42
|
+
*/
|
|
43
|
+
loadDestructiveKeywords() {
|
|
44
|
+
try {
|
|
45
|
+
// Possible locations for destructive-keywords.yaml
|
|
46
|
+
const possiblePaths = [
|
|
47
|
+
path.join(process.cwd(), 'packages/core/destructive-keywords.yaml'), // workspace root
|
|
48
|
+
path.join(process.cwd(), 'node_modules/@matimo/core/destructive-keywords.yaml'), // installed
|
|
49
|
+
path.join(process.cwd(), 'destructive-keywords.yaml'), // current directory
|
|
50
|
+
];
|
|
51
|
+
let configContent = null;
|
|
52
|
+
for (const filePath of possiblePaths) {
|
|
53
|
+
try {
|
|
54
|
+
if (fs.existsSync(filePath)) {
|
|
55
|
+
configContent = fs.readFileSync(filePath, 'utf8');
|
|
56
|
+
break;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// Continue to next path
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
// If file not found, use fallback keywords defined below
|
|
64
|
+
if (!configContent) {
|
|
65
|
+
this.useDefaultKeywords();
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// Simple YAML parsing for flat structure
|
|
69
|
+
// Parse lines and extract keywords from each section
|
|
70
|
+
const lines = configContent.split('\n');
|
|
71
|
+
for (const line of lines) {
|
|
72
|
+
const trimmed = line.trim();
|
|
73
|
+
// Skip comments and empty lines and section headers
|
|
74
|
+
if (trimmed && !trimmed.startsWith('#') && !trimmed.endsWith(':')) {
|
|
75
|
+
// Extract keyword (remove leading dash and whitespace)
|
|
76
|
+
const keyword = trimmed.replace(/^-\s*/, '').trim();
|
|
77
|
+
if (keyword) {
|
|
78
|
+
this.destructiveKeywords.push(keyword);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// Fallback: If no keywords loaded, use defaults
|
|
83
|
+
if (this.destructiveKeywords.length === 0) {
|
|
84
|
+
this.useDefaultKeywords();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
// Fallback to hardcoded keywords if file parsing fails
|
|
89
|
+
this.useDefaultKeywords();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Set default destructive keywords
|
|
94
|
+
*/
|
|
95
|
+
useDefaultKeywords() {
|
|
96
|
+
this.destructiveKeywords = [
|
|
97
|
+
'CREATE',
|
|
98
|
+
'DELETE',
|
|
99
|
+
'DROP',
|
|
100
|
+
'ALTER',
|
|
101
|
+
'TRUNCATE',
|
|
102
|
+
'UPDATE',
|
|
103
|
+
'INSERT',
|
|
104
|
+
'UPSERT',
|
|
105
|
+
'REPLACE',
|
|
106
|
+
'MERGE',
|
|
107
|
+
'GRANT',
|
|
108
|
+
'REVOKE',
|
|
109
|
+
'EDIT',
|
|
110
|
+
'WRITE',
|
|
111
|
+
'APPEND',
|
|
112
|
+
'REMOVE',
|
|
113
|
+
'RENAME',
|
|
114
|
+
'SHUTDOWN',
|
|
115
|
+
'EXECUTE',
|
|
116
|
+
'EXEC',
|
|
117
|
+
];
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Set approval callback for interactive/custom approval
|
|
121
|
+
*/
|
|
122
|
+
setApprovalCallback(callback) {
|
|
123
|
+
this.approvalCallback = callback;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Check if a tool requires approval based on YAML definition or supplied content.
|
|
127
|
+
* @param requiresApproval In Yaml - From tool definition `requires_approval` field
|
|
128
|
+
* @param content - Optional content (SQL, shell command, etc.) to check for destructive keywords
|
|
129
|
+
*
|
|
130
|
+
* Notes:
|
|
131
|
+
* - We now accept any textual content so keyword detection also applies to command/shell and sql
|
|
132
|
+
* based tools (e.g. `params.command`).
|
|
133
|
+
*/
|
|
134
|
+
requiresApproval(requiresApprovalInYaml, content) {
|
|
135
|
+
// Explicit YAML definition takes precedence
|
|
136
|
+
if (requiresApprovalInYaml === true) {
|
|
137
|
+
return true;
|
|
138
|
+
}
|
|
139
|
+
// Check provided content (SQL, shell command, etc.) for destructive keywords
|
|
140
|
+
if (content) {
|
|
141
|
+
const upper = String(content).toUpperCase();
|
|
142
|
+
return this.destructiveKeywords.some((keyword) => upper.includes(keyword));
|
|
143
|
+
}
|
|
144
|
+
return false;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Check if operation is pre-approved via env vars
|
|
148
|
+
*/
|
|
149
|
+
isPreApproved(toolName) {
|
|
150
|
+
// Auto-approve everything
|
|
151
|
+
if (this.autoApprove) {
|
|
152
|
+
return true;
|
|
153
|
+
}
|
|
154
|
+
// Check against patterns
|
|
155
|
+
for (const pattern of this.approvedPatterns) {
|
|
156
|
+
if (this.matchesPattern(toolName, pattern)) {
|
|
157
|
+
return true;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Request approval for an operation
|
|
164
|
+
* Throws if not approved and no callback available
|
|
165
|
+
*/
|
|
166
|
+
async requestApproval(request) {
|
|
167
|
+
// If no callback set, fail safely
|
|
168
|
+
if (!this.approvalCallback) {
|
|
169
|
+
throw new MatimoError(`Destructive operation requires approval: ${request.toolName}`, ErrorCode.EXECUTION_FAILED, {
|
|
170
|
+
toolName: request.toolName,
|
|
171
|
+
hint: 'Set MATIMO_AUTO_APPROVE=true or MATIMO_APPROVED_PATTERNS or install approval callback',
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
// Call callback to get approval
|
|
175
|
+
const approved = await this.approvalCallback(request);
|
|
176
|
+
if (!approved) {
|
|
177
|
+
throw new MatimoError(`Operation rejected by approval handler: ${request.toolName}`, ErrorCode.EXECUTION_FAILED, {
|
|
178
|
+
toolName: request.toolName,
|
|
179
|
+
message: 'User or policy rejected the operation',
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Simple pattern matching (supports wildcards)
|
|
185
|
+
*/
|
|
186
|
+
matchesPattern(toolName, pattern) {
|
|
187
|
+
if (pattern === '*') {
|
|
188
|
+
return true;
|
|
189
|
+
}
|
|
190
|
+
// Convert glob pattern to regex:
|
|
191
|
+
// 1. Escape all regex metacharacters, including backslashes.
|
|
192
|
+
// 2. Turn escaped '*' back into a wildcard '.*'.
|
|
193
|
+
const escapedPattern = pattern.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
194
|
+
const regexPattern = escapedPattern.replace(/\\\*/g, '.*');
|
|
195
|
+
const regex = new RegExp(`^${regexPattern}$`, 'i');
|
|
196
|
+
return regex.test(toolName);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Global instance
|
|
200
|
+
let globalApprovalHandler = null;
|
|
201
|
+
/**
|
|
202
|
+
* Get or create global approval handler
|
|
203
|
+
*/
|
|
204
|
+
export function getGlobalApprovalHandler() {
|
|
205
|
+
if (!globalApprovalHandler) {
|
|
206
|
+
globalApprovalHandler = new ApprovalHandler();
|
|
207
|
+
}
|
|
208
|
+
return globalApprovalHandler;
|
|
209
|
+
}
|
|
210
|
+
//# sourceMappingURL=approval-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"approval-handler.js","sourceRoot":"","sources":["../../src/approval/approval-handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAiBhE;;;;;;;;;GASG;AACH,MAAM,OAAO,eAAe;IAM1B;QALQ,gBAAW,GAAY,KAAK,CAAC;QAC7B,qBAAgB,GAAgB,IAAI,GAAG,EAAE,CAAC;QAC1C,qBAAgB,GAA4B,IAAI,CAAC;QACjD,wBAAmB,GAAa,EAAE,CAAC;QAGzC,oDAAoD;QACpD,IAAI,CAAC,uBAAuB,EAAE,CAAC;QAE/B,kCAAkC;QAClC,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,KAAK,MAAM,CAAC;QAE9D,+CAA+C;QAC/C,0CAA0C;QAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,EAAE,CAAC;QAC/D,IAAI,WAAW,EAAE,CAAC;YAChB,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;gBACzC,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;gBAC/B,IAAI,OAAO,EAAE,CAAC;oBACZ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACrC,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACK,uBAAuB;QAC7B,IAAI,CAAC;YACH,mDAAmD;YACnD,MAAM,aAAa,GAAG;gBACpB,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,yCAAyC,CAAC,EAAE,iBAAiB;gBACtF,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,qDAAqD,CAAC,EAAE,YAAY;gBAC7F,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,2BAA2B,CAAC,EAAE,oBAAoB;aAC5E,CAAC;YAEF,IAAI,aAAa,GAAkB,IAAI,CAAC;YAExC,KAAK,MAAM,QAAQ,IAAI,aAAa,EAAE,CAAC;gBACrC,IAAI,CAAC;oBACH,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;wBAC5B,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;wBAClD,MAAM;oBACR,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,wBAAwB;gBAC1B,CAAC;YACH,CAAC;YAED,yDAAyD;YACzD,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,IAAI,CAAC,kBAAkB,EAAE,CAAC;gBAC1B,OAAO;YACT,CAAC;YAED,yCAAyC;YACzC,qDAAqD;YACrD,MAAM,KAAK,GAAG,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACxC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;gBAC5B,oDAAoD;gBACpD,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAClE,uDAAuD;oBACvD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;oBACpD,IAAI,OAAO,EAAE,CAAC;wBACZ,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBACzC,CAAC;gBACH,CAAC;YACH,CAAC;YAED,gDAAgD;YAChD,IAAI,IAAI,CAAC,mBAAmB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC1C,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC5B,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,uDAAuD;YACvD,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAED;;OAEG;IACK,kBAAkB;QACxB,IAAI,CAAC,mBAAmB,GAAG;YACzB,QAAQ;YACR,QAAQ;YACR,MAAM;YACN,OAAO;YACP,UAAU;YACV,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,SAAS;YACT,OAAO;YACP,OAAO;YACP,QAAQ;YACR,MAAM;YACN,OAAO;YACP,QAAQ;YACR,QAAQ;YACR,QAAQ;YACR,UAAU;YACV,SAAS;YACT,MAAM;SACP,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,mBAAmB,CAAC,QAA0B;QAC5C,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC;IACnC,CAAC;IAED;;;;;;;;OAQG;IACH,gBAAgB,CAAC,sBAA2C,EAAE,OAAgB;QAC5E,4CAA4C;QAC5C,IAAI,sBAAsB,KAAK,IAAI,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,6EAA6E;QAC7E,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;YAC5C,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QAC7E,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,QAAgB;QAC5B,0BAA0B;QAC1B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,yBAAyB;QACzB,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC5C,IAAI,IAAI,CAAC,cAAc,CAAC,QAAQ,EAAE,OAAO,CAAC,EAAE,CAAC;gBAC3C,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,eAAe,CAAC,OAAwB;QAC5C,kCAAkC;QAClC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC3B,MAAM,IAAI,WAAW,CACnB,4CAA4C,OAAO,CAAC,QAAQ,EAAE,EAC9D,SAAS,CAAC,gBAAgB,EAC1B;gBACE,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,IAAI,EAAE,uFAAuF;aAC9F,CACF,CAAC;QACJ,CAAC;QAED,gCAAgC;QAChC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QACtD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,WAAW,CACnB,2CAA2C,OAAO,CAAC,QAAQ,EAAE,EAC7D,SAAS,CAAC,gBAAgB,EAC1B;gBACE,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,OAAO,EAAE,uCAAuC;aACjD,CACF,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACK,cAAc,CAAC,QAAgB,EAAE,OAAe;QACtD,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;YACpB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,iCAAiC;QACjC,6DAA6D;QAC7D,iDAAiD;QACjD,MAAM,cAAc,GAAG,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QACtE,MAAM,YAAY,GAAG,cAAc,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC3D,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,GAAG,EAAE,GAAG,CAAC,CAAC;QACnD,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,kBAAkB;AAClB,IAAI,qBAAqB,GAA2B,IAAI,CAAC;AAEzD;;GAEG;AACH,MAAM,UAAU,wBAAwB;IACtC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,qBAAqB,GAAG,IAAI,eAAe,EAAE,CAAC;IAChD,CAAC;IACD,OAAO,qBAAqB,CAAC;AAC/B,CAAC"}
|