@achieveai/hitl-mcp-server 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 +20 -0
- package/README.md +306 -0
- package/config/claude-desktop.json +11 -0
- package/config/cursor-mcp.json +18 -0
- package/config/vscode-mcp.json +17 -0
- package/dist/__tests__/dialog-manager.test.d.ts +2 -0
- package/dist/__tests__/dialog-manager.test.d.ts.map +1 -0
- package/dist/__tests__/dialog-manager.test.js +140 -0
- package/dist/__tests__/dialog-manager.test.js.map +1 -0
- package/dist/dialog-manager.d.ts +36 -0
- package/dist/dialog-manager.d.ts.map +1 -0
- package/dist/dialog-manager.js +477 -0
- package/dist/dialog-manager.js.map +1 -0
- package/dist/dialog-manager.test.d.ts +2 -0
- package/dist/dialog-manager.test.d.ts.map +1 -0
- package/dist/dialog-manager.test.js +156 -0
- package/dist/dialog-manager.test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +195 -0
- package/dist/index.js.map +1 -0
- package/dist/test-client.d.ts +3 -0
- package/dist/test-client.d.ts.map +1 -0
- package/dist/test-client.js +111 -0
- package/dist/test-client.js.map +1 -0
- package/example-usage.md +223 -0
- package/mcp.json +152 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
GNU GENERAL PUBLIC LICENSE
|
|
2
|
+
Version 3, 29 June 2007
|
|
3
|
+
|
|
4
|
+
Copyright (C) 2025 Human-in-the-Loop MCP Server Contributors
|
|
5
|
+
|
|
6
|
+
This program is free software: you can redistribute it and/or modify
|
|
7
|
+
it under the terms of the GNU General Public License as published by
|
|
8
|
+
the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
(at your option) any later version.
|
|
10
|
+
|
|
11
|
+
This program is distributed in the hope that it will be useful,
|
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
GNU General Public License for more details.
|
|
15
|
+
|
|
16
|
+
You should have received a copy of the GNU General Public License
|
|
17
|
+
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
18
|
+
|
|
19
|
+
For the full text of the GNU General Public License Version 3,
|
|
20
|
+
please visit: https://www.gnu.org/licenses/gpl-3.0.txt
|
package/README.md
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
# Human In The Loop MCP Server
|
|
2
|
+
|
|
3
|
+
A Model Context Protocol (MCP) server that enables LLM agents to request human input through interactive dialog boxes. This tool provides a seamless way for AI agents to ask for clarification, make decisions with human guidance, and handle ambiguous situations.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **Interactive Dialog UI**: Opens a browser-based dialog for user interaction
|
|
8
|
+
- **Multiple Choice Questions**: Support for both single and multiple selection
|
|
9
|
+
- **Custom Input**: "Other" field for free-text responses
|
|
10
|
+
- **Cross-Platform**: Works on Windows, macOS, and Linux
|
|
11
|
+
- **Timeout Support**: Configurable timeouts for time-sensitive decisions
|
|
12
|
+
- **STDIO Transport**: Easy integration with Claude Desktop and other MCP clients
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
### Prerequisites
|
|
17
|
+
|
|
18
|
+
- Node.js 18+ and npm
|
|
19
|
+
- A browser (for displaying dialogs)
|
|
20
|
+
|
|
21
|
+
### From Source
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Clone the repository
|
|
25
|
+
git clone <repository-url>
|
|
26
|
+
cd hitl-mcp-server
|
|
27
|
+
|
|
28
|
+
# Install dependencies
|
|
29
|
+
npm install
|
|
30
|
+
|
|
31
|
+
# Build the TypeScript code
|
|
32
|
+
npm run build
|
|
33
|
+
|
|
34
|
+
# Test the installation
|
|
35
|
+
npm run dev
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Global Installation
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# Build first
|
|
42
|
+
npm run build
|
|
43
|
+
|
|
44
|
+
# Install globally
|
|
45
|
+
npm install -g .
|
|
46
|
+
|
|
47
|
+
# Now you can run it from anywhere
|
|
48
|
+
hitl-mcp-server
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Configuration
|
|
52
|
+
|
|
53
|
+
Pre-configured examples are available in the `config/` directory for different MCP clients.
|
|
54
|
+
|
|
55
|
+
### Claude Desktop Configuration
|
|
56
|
+
|
|
57
|
+
Add the server to your Claude Desktop config file:
|
|
58
|
+
|
|
59
|
+
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
60
|
+
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
61
|
+
**Linux**: `~/.config/claude/claude_desktop_config.json`
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"mcpServers": {
|
|
66
|
+
"human-in-the-loop": {
|
|
67
|
+
"command": "node",
|
|
68
|
+
"args": ["D:\\Source\\repos\\Hitl_MCP\\hitl-mcp-server\\dist\\index.js"],
|
|
69
|
+
"env": {
|
|
70
|
+
"NODE_ENV": "production"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### VS Code Configuration
|
|
78
|
+
|
|
79
|
+
Create `.vscode/mcp.json` in your workspace:
|
|
80
|
+
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"mcpServers": {
|
|
84
|
+
"human-in-the-loop": {
|
|
85
|
+
"command": "npx",
|
|
86
|
+
"args": ["-y", "@hitl/mcp-server"],
|
|
87
|
+
"env": {
|
|
88
|
+
"NODE_ENV": "production"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Cursor IDE Configuration
|
|
96
|
+
|
|
97
|
+
Add to your Cursor settings:
|
|
98
|
+
|
|
99
|
+
```json
|
|
100
|
+
{
|
|
101
|
+
"mcpServers": {
|
|
102
|
+
"human-in-the-loop": {
|
|
103
|
+
"name": "Human In The Loop",
|
|
104
|
+
"command": "node",
|
|
105
|
+
"args": ["./dist/index.js"],
|
|
106
|
+
"cwd": "D:\\Source\\repos\\Hitl_MCP\\hitl-mcp-server",
|
|
107
|
+
"transport": "stdio",
|
|
108
|
+
"autoStart": false
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### NPM Global Installation
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
# Install globally from npm (when published)
|
|
118
|
+
npm install -g @hitl/mcp-server
|
|
119
|
+
|
|
120
|
+
# Then use in any config:
|
|
121
|
+
{
|
|
122
|
+
"mcpServers": {
|
|
123
|
+
"human-in-the-loop": {
|
|
124
|
+
"command": "hitl-mcp-server"
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Usage
|
|
131
|
+
|
|
132
|
+
Once configured, the AI agent can use the `ask_human` tool to request input:
|
|
133
|
+
|
|
134
|
+
### Example: Single Choice
|
|
135
|
+
|
|
136
|
+
```javascript
|
|
137
|
+
{
|
|
138
|
+
"question": "Which database should I use for this project?",
|
|
139
|
+
"options": [
|
|
140
|
+
{
|
|
141
|
+
"label": "PostgreSQL",
|
|
142
|
+
"value": "postgres",
|
|
143
|
+
"description": "Robust relational database with advanced features"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"label": "MongoDB",
|
|
147
|
+
"value": "mongo",
|
|
148
|
+
"description": "Flexible document database for unstructured data"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"label": "SQLite",
|
|
152
|
+
"value": "sqlite",
|
|
153
|
+
"description": "Lightweight embedded database"
|
|
154
|
+
}
|
|
155
|
+
],
|
|
156
|
+
"allowMultiple": false,
|
|
157
|
+
"allowOther": true,
|
|
158
|
+
"context": "This is for a medium-scale web application with complex queries"
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Example: Multiple Choice
|
|
163
|
+
|
|
164
|
+
```javascript
|
|
165
|
+
{
|
|
166
|
+
"question": "Which files should I include in the commit?",
|
|
167
|
+
"options": [
|
|
168
|
+
{
|
|
169
|
+
"label": "src/index.ts",
|
|
170
|
+
"value": "index"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"label": "src/utils.ts",
|
|
174
|
+
"value": "utils"
|
|
175
|
+
},
|
|
176
|
+
{
|
|
177
|
+
"label": "README.md",
|
|
178
|
+
"value": "readme"
|
|
179
|
+
}
|
|
180
|
+
],
|
|
181
|
+
"allowMultiple": true,
|
|
182
|
+
"allowOther": false,
|
|
183
|
+
"context": "Several files have been modified"
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Example: With Timeout
|
|
188
|
+
|
|
189
|
+
```javascript
|
|
190
|
+
{
|
|
191
|
+
"question": "Should I proceed with the deployment?",
|
|
192
|
+
"options": [
|
|
193
|
+
{
|
|
194
|
+
"label": "Yes, deploy now",
|
|
195
|
+
"value": "yes"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"label": "No, cancel",
|
|
199
|
+
"value": "no"
|
|
200
|
+
}
|
|
201
|
+
],
|
|
202
|
+
"allowMultiple": false,
|
|
203
|
+
"allowOther": false,
|
|
204
|
+
"timeout": 30000 // 30 seconds
|
|
205
|
+
}
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Response Format
|
|
209
|
+
|
|
210
|
+
The tool returns a JSON response:
|
|
211
|
+
|
|
212
|
+
```javascript
|
|
213
|
+
{
|
|
214
|
+
"success": true,
|
|
215
|
+
"timestamp": 1703001234567,
|
|
216
|
+
"response": "selected_value", // or array for multiple selection
|
|
217
|
+
"responseType": "selection" // or "custom" for other text, "none" if skipped
|
|
218
|
+
}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## Testing
|
|
222
|
+
|
|
223
|
+
### Run Unit Tests
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
npm test
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Test Dialog Manager
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
npm run build
|
|
233
|
+
node dist/test-client.js
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
This will open test dialogs to verify the UI is working correctly.
|
|
237
|
+
|
|
238
|
+
### Manual Testing with MCP Inspector
|
|
239
|
+
|
|
240
|
+
You can use the MCP Inspector tool to test the server:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
npx @modelcontextprotocol/inspector node dist/index.js
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
## Development
|
|
247
|
+
|
|
248
|
+
### Project Structure
|
|
249
|
+
|
|
250
|
+
```
|
|
251
|
+
hitl-mcp-server/
|
|
252
|
+
├── src/
|
|
253
|
+
│ ├── index.ts # Main MCP server implementation
|
|
254
|
+
│ ├── dialog-manager.ts # Dialog UI and HTTP server
|
|
255
|
+
│ └── test-client.ts # Test client for dialog manager
|
|
256
|
+
├── dist/ # Compiled JavaScript (after build)
|
|
257
|
+
├── package.json
|
|
258
|
+
├── tsconfig.json
|
|
259
|
+
└── README.md
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
### Available Scripts
|
|
263
|
+
|
|
264
|
+
- `npm run build` - Compile TypeScript to JavaScript
|
|
265
|
+
- `npm run dev` - Run in development mode with auto-reload
|
|
266
|
+
- `npm test` - Run unit tests
|
|
267
|
+
- `npm run typecheck` - Check TypeScript types without building
|
|
268
|
+
|
|
269
|
+
## Why Use This Tool?
|
|
270
|
+
|
|
271
|
+
LLM agents often encounter situations requiring human judgment:
|
|
272
|
+
|
|
273
|
+
1. **Ambiguous Requirements**: When instructions are unclear or contradictory
|
|
274
|
+
2. **Critical Decisions**: Before performing irreversible actions
|
|
275
|
+
3. **Multiple Valid Approaches**: When several solutions are equally valid
|
|
276
|
+
4. **Missing Context**: When additional information is needed
|
|
277
|
+
5. **Subjective Choices**: Design decisions, naming conventions, etc.
|
|
278
|
+
|
|
279
|
+
This tool ensures AI agents can gracefully handle these situations by requesting human input rather than making assumptions or failing silently.
|
|
280
|
+
|
|
281
|
+
## Troubleshooting
|
|
282
|
+
|
|
283
|
+
### Dialog doesn't open
|
|
284
|
+
|
|
285
|
+
- Check if port 3000-5000 range is available
|
|
286
|
+
- Ensure your default browser is properly configured
|
|
287
|
+
- Check the server logs for error messages
|
|
288
|
+
|
|
289
|
+
### Timeout errors
|
|
290
|
+
|
|
291
|
+
- Increase the timeout value in your request
|
|
292
|
+
- Ensure the dialog window has focus
|
|
293
|
+
|
|
294
|
+
### Server won't start
|
|
295
|
+
|
|
296
|
+
- Check if another instance is already running
|
|
297
|
+
- Verify Node.js version is 18 or higher
|
|
298
|
+
- Run `npm install` to ensure all dependencies are installed
|
|
299
|
+
|
|
300
|
+
## License
|
|
301
|
+
|
|
302
|
+
MIT
|
|
303
|
+
|
|
304
|
+
## Contributing
|
|
305
|
+
|
|
306
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"human-in-the-loop": {
|
|
4
|
+
"name": "Human In The Loop",
|
|
5
|
+
"description": "Interactive dialog system for getting human feedback",
|
|
6
|
+
"command": "node",
|
|
7
|
+
"args": ["./dist/index.js"],
|
|
8
|
+
"cwd": "D:\\Source\\repos\\Hitl_MCP\\hitl-mcp-server",
|
|
9
|
+
"env": {
|
|
10
|
+
"NODE_ENV": "production"
|
|
11
|
+
},
|
|
12
|
+
"transport": "stdio",
|
|
13
|
+
"autoStart": false,
|
|
14
|
+
"restartOnFailure": true,
|
|
15
|
+
"maxRestarts": 3
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog-manager.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/dialog-manager.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { DialogManager } from '../dialog-manager.js';
|
|
2
|
+
import { describe, it, expect, beforeEach, afterEach } from '@jest/globals';
|
|
3
|
+
describe('DialogManager', () => {
|
|
4
|
+
let manager;
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
manager = new DialogManager();
|
|
7
|
+
});
|
|
8
|
+
afterEach(async () => {
|
|
9
|
+
await manager.close();
|
|
10
|
+
});
|
|
11
|
+
describe('initialization', () => {
|
|
12
|
+
it('should initialize the server on a random port', async () => {
|
|
13
|
+
const port = await manager.initialize();
|
|
14
|
+
expect(port).toBeGreaterThan(0);
|
|
15
|
+
expect(port).toBeLessThanOrEqual(65535);
|
|
16
|
+
});
|
|
17
|
+
it('should not reinitialize if already initialized', async () => {
|
|
18
|
+
const port1 = await manager.initialize();
|
|
19
|
+
const port2 = await manager.initialize();
|
|
20
|
+
expect(port1).toBe(port2);
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
describe('HTML generation', () => {
|
|
24
|
+
it('should escape HTML in user input', () => {
|
|
25
|
+
const manager = new DialogManager();
|
|
26
|
+
const html = manager.generateDialogHTML({
|
|
27
|
+
id: 'test',
|
|
28
|
+
question: '<script>alert("XSS")</script>',
|
|
29
|
+
options: [
|
|
30
|
+
{
|
|
31
|
+
label: '<b>Bold</b>',
|
|
32
|
+
value: 'test',
|
|
33
|
+
description: '"Quotes" & \'apostrophes\''
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
allowMultiple: false,
|
|
37
|
+
allowOther: true
|
|
38
|
+
});
|
|
39
|
+
expect(html).not.toContain('<script>alert("XSS")</script>');
|
|
40
|
+
expect(html).toContain('<script>alert("XSS")</script>');
|
|
41
|
+
expect(html).not.toContain('<b>Bold</b>');
|
|
42
|
+
expect(html).toContain('<b>Bold</b>');
|
|
43
|
+
});
|
|
44
|
+
it('should include context when provided', () => {
|
|
45
|
+
const manager = new DialogManager();
|
|
46
|
+
const html = manager.generateDialogHTML({
|
|
47
|
+
id: 'test',
|
|
48
|
+
question: 'Test question',
|
|
49
|
+
options: [{ label: 'Option 1', value: 'opt1' }],
|
|
50
|
+
allowMultiple: false,
|
|
51
|
+
allowOther: false,
|
|
52
|
+
context: 'Important context information'
|
|
53
|
+
});
|
|
54
|
+
expect(html).toContain('Important context information');
|
|
55
|
+
expect(html).toContain('Context:');
|
|
56
|
+
});
|
|
57
|
+
it('should not include context section when not provided', () => {
|
|
58
|
+
const manager = new DialogManager();
|
|
59
|
+
const html = manager.generateDialogHTML({
|
|
60
|
+
id: 'test',
|
|
61
|
+
question: 'Test question',
|
|
62
|
+
options: [{ label: 'Option 1', value: 'opt1' }],
|
|
63
|
+
allowMultiple: false,
|
|
64
|
+
allowOther: false
|
|
65
|
+
});
|
|
66
|
+
expect(html).not.toContain('Context:');
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
describe('dialog options', () => {
|
|
70
|
+
it('should render radio buttons for single choice', () => {
|
|
71
|
+
const manager = new DialogManager();
|
|
72
|
+
const html = manager.generateDialogHTML({
|
|
73
|
+
id: 'test',
|
|
74
|
+
question: 'Choose one',
|
|
75
|
+
options: [
|
|
76
|
+
{ label: 'A', value: 'a' },
|
|
77
|
+
{ label: 'B', value: 'b' }
|
|
78
|
+
],
|
|
79
|
+
allowMultiple: false,
|
|
80
|
+
allowOther: false
|
|
81
|
+
});
|
|
82
|
+
expect(html).toContain('type="radio"');
|
|
83
|
+
expect(html).not.toContain('type="checkbox"');
|
|
84
|
+
});
|
|
85
|
+
it('should render checkboxes for multiple choice', () => {
|
|
86
|
+
const manager = new DialogManager();
|
|
87
|
+
const html = manager.generateDialogHTML({
|
|
88
|
+
id: 'test',
|
|
89
|
+
question: 'Choose many',
|
|
90
|
+
options: [
|
|
91
|
+
{ label: 'A', value: 'a' },
|
|
92
|
+
{ label: 'B', value: 'b' }
|
|
93
|
+
],
|
|
94
|
+
allowMultiple: true,
|
|
95
|
+
allowOther: false
|
|
96
|
+
});
|
|
97
|
+
expect(html).toContain('type="checkbox"');
|
|
98
|
+
expect(html).not.toContain('type="radio"');
|
|
99
|
+
});
|
|
100
|
+
it('should include other field when allowed', () => {
|
|
101
|
+
const manager = new DialogManager();
|
|
102
|
+
const html = manager.generateDialogHTML({
|
|
103
|
+
id: 'test',
|
|
104
|
+
question: 'Choose',
|
|
105
|
+
options: [{ label: 'A', value: 'a' }],
|
|
106
|
+
allowMultiple: false,
|
|
107
|
+
allowOther: true
|
|
108
|
+
});
|
|
109
|
+
expect(html).toContain('other-input');
|
|
110
|
+
expect(html).toContain('Other (please specify)');
|
|
111
|
+
});
|
|
112
|
+
it('should not include other field when not allowed', () => {
|
|
113
|
+
const manager = new DialogManager();
|
|
114
|
+
const html = manager.generateDialogHTML({
|
|
115
|
+
id: 'test',
|
|
116
|
+
question: 'Choose',
|
|
117
|
+
options: [{ label: 'A', value: 'a' }],
|
|
118
|
+
allowMultiple: false,
|
|
119
|
+
allowOther: false
|
|
120
|
+
});
|
|
121
|
+
expect(html).not.toContain('other-input');
|
|
122
|
+
expect(html).not.toContain('Other (please specify)');
|
|
123
|
+
});
|
|
124
|
+
});
|
|
125
|
+
describe('timeout handling', () => {
|
|
126
|
+
it('should reject with timeout error after specified duration', async () => {
|
|
127
|
+
await manager.initialize();
|
|
128
|
+
const dialogPromise = manager.showDialog({
|
|
129
|
+
id: 'timeout-test',
|
|
130
|
+
question: 'This will timeout',
|
|
131
|
+
options: [{ label: 'Option', value: 'opt' }],
|
|
132
|
+
allowMultiple: false,
|
|
133
|
+
allowOther: false,
|
|
134
|
+
timeout: 100
|
|
135
|
+
});
|
|
136
|
+
await expect(dialogPromise).rejects.toThrow('Dialog timeout');
|
|
137
|
+
}, 10000);
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
//# sourceMappingURL=dialog-manager.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog-manager.test.js","sourceRoot":"","sources":["../../src/__tests__/dialog-manager.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
export interface DialogOption {
|
|
3
|
+
label: string;
|
|
4
|
+
value: string;
|
|
5
|
+
description?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface DialogRequest {
|
|
8
|
+
id: string;
|
|
9
|
+
question: string;
|
|
10
|
+
options: DialogOption[];
|
|
11
|
+
allowMultiple: boolean;
|
|
12
|
+
allowOther: boolean;
|
|
13
|
+
context?: string;
|
|
14
|
+
timeout?: number;
|
|
15
|
+
}
|
|
16
|
+
export interface DialogResponse {
|
|
17
|
+
id: string;
|
|
18
|
+
selectedValues: string[];
|
|
19
|
+
otherText?: string;
|
|
20
|
+
timestamp: number;
|
|
21
|
+
}
|
|
22
|
+
export declare class DialogManager extends EventEmitter {
|
|
23
|
+
private app;
|
|
24
|
+
private port;
|
|
25
|
+
private pendingDialogs;
|
|
26
|
+
private server;
|
|
27
|
+
private isInitialized;
|
|
28
|
+
constructor(port?: number);
|
|
29
|
+
private setupRoutes;
|
|
30
|
+
private generateDialogHTML;
|
|
31
|
+
private escapeHtml;
|
|
32
|
+
initialize(): Promise<number>;
|
|
33
|
+
showDialog(request: DialogRequest): Promise<DialogResponse>;
|
|
34
|
+
close(): Promise<void>;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=dialog-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dialog-manager.d.ts","sourceRoot":"","sources":["../src/dialog-manager.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAEtC,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,aAAc,SAAQ,YAAY;IAC7C,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,cAAc,CAKnB;IACH,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,aAAa,CAAkB;gBAE3B,IAAI,GAAE,MAAU;IAQ5B,OAAO,CAAC,WAAW;IAgDnB,OAAO,CAAC,kBAAkB;IAqW1B,OAAO,CAAC,UAAU;IAWZ,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC;IAoB7B,UAAU,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;IAkC3D,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAU7B"}
|