sqlew 3.6.3 → 3.6.6
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/CHANGELOG.md +89 -0
- package/LICENSE +52 -52
- package/README.md +45 -3
- package/assets/config.example.toml +41 -0
- package/assets/sample-agents/README.md +38 -0
- package/assets/sample-agents/sqlew-architect.md +247 -0
- package/assets/sample-agents/sqlew-researcher.md +189 -0
- package/assets/sample-agents/sqlew-scrum-master.md +236 -0
- package/dist/config/loader.d.ts.map +1 -1
- package/dist/config/loader.js +13 -0
- package/dist/config/loader.js.map +1 -1
- package/dist/config/minimal-generator.d.ts +25 -0
- package/dist/config/minimal-generator.d.ts.map +1 -0
- package/dist/config/minimal-generator.js +103 -0
- package/dist/config/minimal-generator.js.map +1 -0
- package/dist/config/types.d.ts +13 -0
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js +5 -0
- package/dist/config/types.js.map +1 -1
- package/dist/database.d.ts +6 -9
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +30 -106
- package/dist/database.js.map +1 -1
- package/dist/index.js +36 -72
- package/dist/index.js.map +1 -1
- package/dist/init-agents.d.ts +7 -0
- package/dist/init-agents.d.ts.map +1 -0
- package/dist/init-agents.js +207 -0
- package/dist/init-agents.js.map +1 -0
- package/dist/migrations/knex/bootstrap/20251025020452_create_master_tables.d.ts.map +1 -1
- package/dist/migrations/knex/bootstrap/20251025020452_create_master_tables.js +49 -34
- package/dist/migrations/knex/bootstrap/20251025020452_create_master_tables.js.map +1 -1
- package/dist/migrations/knex/bootstrap/20251025021152_create_transaction_tables.d.ts.map +1 -1
- package/dist/migrations/knex/bootstrap/20251025021152_create_transaction_tables.js +211 -175
- package/dist/migrations/knex/bootstrap/20251025021152_create_transaction_tables.js.map +1 -1
- package/dist/migrations/knex/enhancements/20251028000000_simplify_agent_system.d.ts +23 -0
- package/dist/migrations/knex/enhancements/20251028000000_simplify_agent_system.d.ts.map +1 -0
- package/dist/migrations/knex/enhancements/20251028000000_simplify_agent_system.js +44 -0
- package/dist/migrations/knex/enhancements/20251028000000_simplify_agent_system.js.map +1 -0
- package/dist/sync-agents.d.ts +13 -0
- package/dist/sync-agents.d.ts.map +1 -0
- package/dist/sync-agents.js +112 -0
- package/dist/sync-agents.js.map +1 -0
- package/dist/tests/all-features.test.js +0 -71
- package/dist/tests/all-features.test.js.map +1 -1
- package/dist/tests/parameter-validation.test.d.ts +8 -0
- package/dist/tests/parameter-validation.test.d.ts.map +1 -0
- package/dist/tests/parameter-validation.test.js +461 -0
- package/dist/tests/parameter-validation.test.js.map +1 -0
- package/dist/tools/constraints.d.ts.map +1 -1
- package/dist/tools/constraints.js +7 -8
- package/dist/tools/constraints.js.map +1 -1
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +68 -39
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/files.d.ts.map +1 -1
- package/dist/tools/files.js +9 -7
- package/dist/tools/files.js.map +1 -1
- package/dist/tools/help-queries.d.ts.map +1 -1
- package/dist/tools/help-queries.js +20 -14
- package/dist/tools/help-queries.js.map +1 -1
- package/dist/tools/messaging.d.ts +4 -0
- package/dist/tools/messaging.d.ts.map +1 -1
- package/dist/tools/messaging.js +38 -0
- package/dist/tools/messaging.js.map +1 -1
- package/dist/tools/tasks.d.ts.map +1 -1
- package/dist/tools/tasks.js +13 -0
- package/dist/tools/tasks.js.map +1 -1
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tools/utils.js +15 -12
- package/dist/tools/utils.js.map +1 -1
- package/dist/types.d.ts +93 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/action-specs.d.ts +46 -0
- package/dist/utils/action-specs.d.ts.map +1 -0
- package/dist/utils/action-specs.js +527 -0
- package/dist/utils/action-specs.js.map +1 -0
- package/dist/utils/error-handler.d.ts.map +1 -1
- package/dist/utils/error-handler.js +41 -24
- package/dist/utils/error-handler.js.map +1 -1
- package/dist/utils/parameter-validator.d.ts +53 -0
- package/dist/utils/parameter-validator.d.ts.map +1 -0
- package/dist/utils/parameter-validator.js +286 -0
- package/dist/utils/parameter-validator.js.map +1 -0
- package/dist/watcher/file-watcher.d.ts +11 -5
- package/dist/watcher/file-watcher.d.ts.map +1 -1
- package/dist/watcher/file-watcher.js +43 -10
- package/dist/watcher/file-watcher.js.map +1 -1
- package/docs/BEST_PRACTICES.md +69 -0
- package/docs/CONFIGURATION.md +35 -19
- package/docs/SPECIALIZED_AGENTS.md +576 -0
- package/docs/TOOL_REFERENCE.md +178 -0
- package/package.json +86 -85
- package/dist/tests/agent-reuse.test.d.ts +0 -6
- package/dist/tests/agent-reuse.test.d.ts.map +0 -1
- package/dist/tests/agent-reuse.test.js +0 -242
- package/dist/tests/agent-reuse.test.js.map +0 -1
- package/dist/tools/config.d.ts +0 -50
- package/dist/tools/config.d.ts.map +0 -1
- package/dist/tools/config.js +0 -170
- package/dist/tools/config.js.map +0 -1
package/docs/TOOL_REFERENCE.md
CHANGED
|
@@ -23,6 +23,63 @@
|
|
|
23
23
|
|
|
24
24
|
---
|
|
25
25
|
|
|
26
|
+
## Parameter Validation
|
|
27
|
+
|
|
28
|
+
**NEW in dev branch**: sqlew now provides comprehensive parameter validation with helpful error messages.
|
|
29
|
+
|
|
30
|
+
### Validation Features
|
|
31
|
+
|
|
32
|
+
1. **Required vs Optional Detection** - Clear indication of which parameters must be provided
|
|
33
|
+
2. **Typo Suggestions** - Levenshtein distance-based suggestions for mistyped parameter names
|
|
34
|
+
3. **Structured Error Messages** - JSON format with examples showing correct usage
|
|
35
|
+
4. **Visual Markers** - Help responses show 🔴 REQUIRED and ⚪ OPTIONAL parameter markers
|
|
36
|
+
|
|
37
|
+
### Example Error Message
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"error": "Missing required parameter for action 'set': value",
|
|
42
|
+
"action": "set",
|
|
43
|
+
"missing_params": ["value"],
|
|
44
|
+
"required_params": ["key", "value"],
|
|
45
|
+
"optional_params": ["agent", "layer", "tags", "status", "version", "scopes"],
|
|
46
|
+
"you_provided": ["key", "layer"],
|
|
47
|
+
"example": {
|
|
48
|
+
"action": "set",
|
|
49
|
+
"key": "database/postgresql-choice",
|
|
50
|
+
"value": "Selected PostgreSQL over MongoDB",
|
|
51
|
+
"layer": "data",
|
|
52
|
+
"tags": ["database", "architecture"]
|
|
53
|
+
},
|
|
54
|
+
"hint": "Use 'quick_set' for simpler usage with auto-inferred metadata"
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Typo Detection Example
|
|
59
|
+
|
|
60
|
+
```json
|
|
61
|
+
{
|
|
62
|
+
"error": "Unknown parameter for action 'set': tgas",
|
|
63
|
+
"action": "set",
|
|
64
|
+
"invalid_params": ["tgas"],
|
|
65
|
+
"did_you_mean": {
|
|
66
|
+
"tgas": "tags"
|
|
67
|
+
},
|
|
68
|
+
"valid_params": ["action", "key", "value", "agent", "layer", "tags", "status", "version", "scopes"],
|
|
69
|
+
"hint": "Parameter names are case-sensitive"
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Common Validation Errors
|
|
74
|
+
|
|
75
|
+
| Error Type | Cause | Solution |
|
|
76
|
+
|------------|-------|----------|
|
|
77
|
+
| Missing required parameter | Omitted required field | Check error message for required_params list |
|
|
78
|
+
| Unknown parameter | Typo or invalid field | Check did_you_mean suggestions |
|
|
79
|
+
| Wrong parameter for action | Using parameter from different action | Verify action name and consult example |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
26
83
|
## Quick Start
|
|
27
84
|
|
|
28
85
|
### Basic Decision Workflow
|
|
@@ -80,6 +137,123 @@
|
|
|
80
137
|
|
|
81
138
|
---
|
|
82
139
|
|
|
140
|
+
## Parameter Validation (v3.7.0)
|
|
141
|
+
|
|
142
|
+
sqlew provides structured error messages with examples and typo suggestions to help you fix parameter errors quickly.
|
|
143
|
+
|
|
144
|
+
### Structured Error Format
|
|
145
|
+
|
|
146
|
+
When required parameters are missing or incorrect, sqlew returns a detailed JSON error response:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{
|
|
150
|
+
"error": "Missing required parameters for 'set': key",
|
|
151
|
+
"action": "set",
|
|
152
|
+
"missing_params": ["key"],
|
|
153
|
+
"required_params": ["key", "value"],
|
|
154
|
+
"optional_params": ["agent", "layer", "tags", "status", "version", "scopes"],
|
|
155
|
+
"you_provided": ["action", "context_key", "value"],
|
|
156
|
+
"did_you_mean": {
|
|
157
|
+
"context_key": "key"
|
|
158
|
+
},
|
|
159
|
+
"example": {
|
|
160
|
+
"action": "set",
|
|
161
|
+
"key": "database/pre-existence-requirement",
|
|
162
|
+
"value": "Database must pre-exist before connection...",
|
|
163
|
+
"layer": "infrastructure",
|
|
164
|
+
"tags": ["database", "security"]
|
|
165
|
+
},
|
|
166
|
+
"hint": "💡 TIP: Use 'quick_set' action for simpler usage with smart defaults"
|
|
167
|
+
}
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Error Response Fields
|
|
171
|
+
|
|
172
|
+
| Field | Description |
|
|
173
|
+
|-------|-------------|
|
|
174
|
+
| **error** | Human-readable error message |
|
|
175
|
+
| **action** | The action that was attempted |
|
|
176
|
+
| **missing_params** | List of missing required parameters |
|
|
177
|
+
| **required_params** | All required parameters for this action |
|
|
178
|
+
| **optional_params** | All optional parameters for this action |
|
|
179
|
+
| **you_provided** | Parameters you actually provided |
|
|
180
|
+
| **did_you_mean** | Typo suggestions (parameter name → correct name) |
|
|
181
|
+
| **example** | Working example showing correct usage |
|
|
182
|
+
| **hint** | Optional helpful tip for this action |
|
|
183
|
+
|
|
184
|
+
### Example Error Scenarios
|
|
185
|
+
|
|
186
|
+
#### Scenario 1: Wrong Parameter Name
|
|
187
|
+
|
|
188
|
+
```javascript
|
|
189
|
+
// ❌ Wrong
|
|
190
|
+
{ action: "set", context_key: "db/feature", value: "..." }
|
|
191
|
+
|
|
192
|
+
// Error Response:
|
|
193
|
+
{
|
|
194
|
+
"error": "Missing required parameter 'key' for action 'set'",
|
|
195
|
+
"did_you_mean": { "context_key": "key" },
|
|
196
|
+
"example": { action: "set", key: "db/feature", value: "..." }
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
#### Scenario 2: Missing Required Parameter
|
|
201
|
+
|
|
202
|
+
```javascript
|
|
203
|
+
// ❌ Wrong
|
|
204
|
+
{ action: "add", category: "architecture", constraint_text: "..." }
|
|
205
|
+
|
|
206
|
+
// Error Response:
|
|
207
|
+
{
|
|
208
|
+
"error": "Missing required parameter 'priority' for action 'add'",
|
|
209
|
+
"required_params": ["category", "constraint_text", "priority"],
|
|
210
|
+
"optional_params": ["layer", "tags", "created_by"],
|
|
211
|
+
"example": {
|
|
212
|
+
action: "add",
|
|
213
|
+
category: "architecture",
|
|
214
|
+
constraint_text: "...",
|
|
215
|
+
priority: "critical"
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
#### Scenario 3: Typo Detection
|
|
221
|
+
|
|
222
|
+
```javascript
|
|
223
|
+
// ❌ Wrong
|
|
224
|
+
{ action: "add", cat: "architecture", constraint_text: "...", priority: "high" }
|
|
225
|
+
|
|
226
|
+
// Error Response:
|
|
227
|
+
{
|
|
228
|
+
"error": "Missing required parameter 'category' for action 'add'",
|
|
229
|
+
"did_you_mean": { "cat": "category" },
|
|
230
|
+
"example": { ... }
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Typo Detection
|
|
235
|
+
|
|
236
|
+
sqlew uses Levenshtein distance (≤2 edits) to detect common typos:
|
|
237
|
+
|
|
238
|
+
| Common Typo | Suggestion |
|
|
239
|
+
|-------------|------------|
|
|
240
|
+
| context_key | key |
|
|
241
|
+
| constraint | constraint_text |
|
|
242
|
+
| cat | category |
|
|
243
|
+
| prio | priority |
|
|
244
|
+
| msg | message |
|
|
245
|
+
| desc | description |
|
|
246
|
+
|
|
247
|
+
### Best Practices
|
|
248
|
+
|
|
249
|
+
1. **Read the error response** - It includes everything you need to fix the issue
|
|
250
|
+
2. **Check `did_you_mean`** - Often catches simple typos
|
|
251
|
+
3. **Copy the example** - Use it as a template for your call
|
|
252
|
+
4. **Verify required params** - Make sure you provide all items in `required_params`
|
|
253
|
+
5. **Use hints** - Look for simpler alternatives (e.g., `quick_set` vs `set`)
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
83
257
|
## Parameter Requirements by Tool
|
|
84
258
|
|
|
85
259
|
### `decision` Tool
|
|
@@ -140,6 +314,10 @@
|
|
|
140
314
|
|
|
141
315
|
### `config` Tool
|
|
142
316
|
|
|
317
|
+
> ⚠️ **DEPRECATED in v3.7.0** - This tool will be removed in a future version.
|
|
318
|
+
> Use `.sqlew/config.toml` file instead for configuration.
|
|
319
|
+
> See [CONFIGURATION.md](CONFIGURATION.md) for migration guide.
|
|
320
|
+
|
|
143
321
|
| Action | Required | Optional |
|
|
144
322
|
|--------|----------|----------|
|
|
145
323
|
| **get** | action | - |
|
package/package.json
CHANGED
|
@@ -1,85 +1,86 @@
|
|
|
1
|
-
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
"
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
"
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
"
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "sqlew",
|
|
3
|
+
"version": "3.6.6",
|
|
4
|
+
"description": "MCP server for efficient context sharing between Claude Code sub-agents (60-70% token reduction), Kanban Task Watcher, Decision or Constraint Context, and streamlined documentation",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"sqlew": "dist/index.js",
|
|
9
|
+
"sqlew-cli": "dist/cli.js",
|
|
10
|
+
"sqlew-init-agents": "dist/init-agents.js"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist/",
|
|
14
|
+
"assets/",
|
|
15
|
+
"docs/",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE",
|
|
18
|
+
"CHANGELOG.md",
|
|
19
|
+
"MIGRATION_v2.md",
|
|
20
|
+
"ARCHITECTURE.md"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc",
|
|
24
|
+
"start": "node dist/index.js",
|
|
25
|
+
"cli": "node dist/cli.js",
|
|
26
|
+
"inspector": "npx @modelcontextprotocol/inspector node dist/index.js",
|
|
27
|
+
"dev": "tsc --watch",
|
|
28
|
+
"clean": "rm -rf dist",
|
|
29
|
+
"rebuild": "npm run clean && npm run build",
|
|
30
|
+
"test": "npm run build && node --test dist/tests/tasks.dependencies.test.js",
|
|
31
|
+
"test:all-features": "npm run build && node dist/tests/all-features.test.js",
|
|
32
|
+
"test:migrations": "npm run build && node dist/tests/migrations/test-v3.2-migration.js",
|
|
33
|
+
"test:migrations:all": "npm run build && node dist/tests/migrations/test-all-versions-real.js",
|
|
34
|
+
"prepare": "husky",
|
|
35
|
+
"prepublishOnly": "npm run rebuild",
|
|
36
|
+
"knex": "tsx node_modules/.bin/knex --knexfile src/knexfile.ts",
|
|
37
|
+
"migrate:make": "npm run knex migrate:make",
|
|
38
|
+
"migrate:latest": "npm run knex migrate:latest",
|
|
39
|
+
"migrate:rollback": "npm run knex migrate:rollback",
|
|
40
|
+
"migrate:rollback:all": "npm run knex migrate:rollback --all",
|
|
41
|
+
"migrate:status": "npm run knex migrate:status",
|
|
42
|
+
"seed:make": "npm run knex seed:make",
|
|
43
|
+
"seed:run": "npm run knex seed:run"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18.0.0"
|
|
47
|
+
},
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/sin5ddd/mcp-sqlew.git"
|
|
51
|
+
},
|
|
52
|
+
"bugs": {
|
|
53
|
+
"url": "https://github.com/sin5ddd/mcp-sqlew/issues"
|
|
54
|
+
},
|
|
55
|
+
"homepage": "https://github.com/sin5ddd/mcp-sqlew#readme",
|
|
56
|
+
"keywords": [
|
|
57
|
+
"mcp",
|
|
58
|
+
"mcp-server",
|
|
59
|
+
"model-context-protocol",
|
|
60
|
+
"context-sharing",
|
|
61
|
+
"claude-code",
|
|
62
|
+
"sub-agents",
|
|
63
|
+
"sqlite",
|
|
64
|
+
"token-efficiency",
|
|
65
|
+
"shared-context"
|
|
66
|
+
],
|
|
67
|
+
"author": "sin5ddd",
|
|
68
|
+
"license": "AGPL-3.0",
|
|
69
|
+
"dependencies": {
|
|
70
|
+
"@modelcontextprotocol/sdk": "latest",
|
|
71
|
+
"better-sqlite3": "^11.0.0",
|
|
72
|
+
"chokidar": "^4.0.3",
|
|
73
|
+
"ignore": "^7.0.5",
|
|
74
|
+
"knex": "^3.1.0",
|
|
75
|
+
"smol-toml": "^1.4.2",
|
|
76
|
+
"sqlite3": "^5.1.7"
|
|
77
|
+
},
|
|
78
|
+
"devDependencies": {
|
|
79
|
+
"@types/better-sqlite3": "^7.6.0",
|
|
80
|
+
"@types/knex": "^0.15.2",
|
|
81
|
+
"@types/node": "^20.0.0",
|
|
82
|
+
"husky": "^9.1.7",
|
|
83
|
+
"tsx": "^4.20.6",
|
|
84
|
+
"typescript": "^5.0.0"
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent-reuse.test.d.ts","sourceRoot":"","sources":["../../src/tests/agent-reuse.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test suite for agent reuse system
|
|
3
|
-
* Tests generic agent slot reuse and user-specified agent preservation
|
|
4
|
-
*/
|
|
5
|
-
import { describe, it, beforeEach, afterEach } from 'node:test';
|
|
6
|
-
import assert from 'node:assert';
|
|
7
|
-
import { initializeDatabase, getOrCreateAgent, releaseAgent, updateAgentActivity, closeDatabase } from '../database.js';
|
|
8
|
-
import { releaseInactiveAgents } from '../utils/retention.js';
|
|
9
|
-
import { clearOldData } from '../tools/utils.js';
|
|
10
|
-
describe('Agent Reuse System', () => {
|
|
11
|
-
let adapter;
|
|
12
|
-
beforeEach(async () => {
|
|
13
|
-
adapter = await initializeDatabase({
|
|
14
|
-
databaseType: 'sqlite',
|
|
15
|
-
connection: { filename: ':memory:' }
|
|
16
|
-
});
|
|
17
|
-
});
|
|
18
|
-
afterEach(async () => {
|
|
19
|
-
await closeDatabase();
|
|
20
|
-
});
|
|
21
|
-
describe('User-specified agents', () => {
|
|
22
|
-
it('should create user-specified agents as non-reusable', async () => {
|
|
23
|
-
const agentId = await getOrCreateAgent(adapter, 'rust-expert');
|
|
24
|
-
const agent = await adapter.getKnex()('m_agents')
|
|
25
|
-
.where({ id: agentId })
|
|
26
|
-
.first();
|
|
27
|
-
assert.strictEqual(agent.name, 'rust-expert');
|
|
28
|
-
assert.strictEqual(agent.is_reusable, 0); // SQLite stores false as 0
|
|
29
|
-
assert.strictEqual(agent.in_use, 1); // SQLite stores true as 1
|
|
30
|
-
assert.ok(agent.last_active_ts > 0);
|
|
31
|
-
});
|
|
32
|
-
it('should preserve user-specified agent names', async () => {
|
|
33
|
-
const agentId1 = await getOrCreateAgent(adapter, 'typescript-expert');
|
|
34
|
-
const agentId2 = await getOrCreateAgent(adapter, 'typescript-expert');
|
|
35
|
-
assert.strictEqual(agentId1, agentId2);
|
|
36
|
-
const count = await adapter.getKnex()('m_agents')
|
|
37
|
-
.where({ name: 'typescript-expert' })
|
|
38
|
-
.count('* as count')
|
|
39
|
-
.first();
|
|
40
|
-
assert.strictEqual(count?.count, 1);
|
|
41
|
-
});
|
|
42
|
-
it('should update activity timestamp on reuse', async () => {
|
|
43
|
-
const agentId1 = await getOrCreateAgent(adapter, 'scrum-master');
|
|
44
|
-
const agent1 = await adapter.getKnex()('m_agents')
|
|
45
|
-
.where({ id: agentId1 })
|
|
46
|
-
.first();
|
|
47
|
-
// Wait a moment
|
|
48
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
49
|
-
const agentId2 = await getOrCreateAgent(adapter, 'scrum-master');
|
|
50
|
-
const agent2 = await adapter.getKnex()('m_agents')
|
|
51
|
-
.where({ id: agentId2 })
|
|
52
|
-
.first();
|
|
53
|
-
assert.strictEqual(agentId1, agentId2);
|
|
54
|
-
assert.ok(agent2.last_active_ts >= agent1.last_active_ts);
|
|
55
|
-
});
|
|
56
|
-
});
|
|
57
|
-
describe('Generic agents', () => {
|
|
58
|
-
it('should create first generic agent as generic-1', async () => {
|
|
59
|
-
const agentId = await getOrCreateAgent(adapter, '');
|
|
60
|
-
const agent = await adapter.getKnex()('m_agents')
|
|
61
|
-
.where({ id: agentId })
|
|
62
|
-
.first();
|
|
63
|
-
assert.strictEqual(agent.name, 'generic-1');
|
|
64
|
-
assert.strictEqual(agent.is_reusable, 1);
|
|
65
|
-
assert.strictEqual(agent.in_use, 1);
|
|
66
|
-
});
|
|
67
|
-
it('should create multiple generic agents sequentially', async () => {
|
|
68
|
-
const agentId1 = await getOrCreateAgent(adapter, '');
|
|
69
|
-
const agentId2 = await getOrCreateAgent(adapter, '');
|
|
70
|
-
const agentId3 = await getOrCreateAgent(adapter, '');
|
|
71
|
-
const agents = await adapter.getKnex()('m_agents')
|
|
72
|
-
.whereIn('id', [agentId1, agentId2, agentId3])
|
|
73
|
-
.orderBy('id');
|
|
74
|
-
assert.strictEqual(agents[0].name, 'generic-1');
|
|
75
|
-
assert.strictEqual(agents[1].name, 'generic-2');
|
|
76
|
-
assert.strictEqual(agents[2].name, 'generic-3');
|
|
77
|
-
agents.forEach(agent => {
|
|
78
|
-
assert.strictEqual(agent.is_reusable, 1);
|
|
79
|
-
assert.strictEqual(agent.in_use, 1);
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
it('should reuse released generic agent slots', async () => {
|
|
83
|
-
const agentId1 = await getOrCreateAgent(adapter, '');
|
|
84
|
-
const agentId2 = await getOrCreateAgent(adapter, '');
|
|
85
|
-
// Release the first agent
|
|
86
|
-
await releaseAgent(adapter, agentId1);
|
|
87
|
-
// Next generic agent request should reuse slot 1
|
|
88
|
-
const agentId3 = await getOrCreateAgent(adapter, '');
|
|
89
|
-
assert.strictEqual(agentId3, agentId1);
|
|
90
|
-
const agent = await adapter.getKnex()('m_agents')
|
|
91
|
-
.where({ id: agentId3 })
|
|
92
|
-
.first();
|
|
93
|
-
assert.strictEqual(agent.name, 'generic-1');
|
|
94
|
-
assert.strictEqual(agent.in_use, 1);
|
|
95
|
-
});
|
|
96
|
-
it('should recognize generic-N pattern as reusable', async () => {
|
|
97
|
-
const agentId = await getOrCreateAgent(adapter, 'generic-5');
|
|
98
|
-
const agent = await adapter.getKnex()('m_agents')
|
|
99
|
-
.where({ id: agentId })
|
|
100
|
-
.first();
|
|
101
|
-
assert.strictEqual(agent.name, 'generic-5');
|
|
102
|
-
assert.strictEqual(agent.is_reusable, 1);
|
|
103
|
-
});
|
|
104
|
-
it('should recognize agent-N pattern as reusable', async () => {
|
|
105
|
-
const agentId = await getOrCreateAgent(adapter, 'agent-123');
|
|
106
|
-
const agent = await adapter.getKnex()('m_agents')
|
|
107
|
-
.where({ id: agentId })
|
|
108
|
-
.first();
|
|
109
|
-
assert.strictEqual(agent.name, 'agent-123');
|
|
110
|
-
assert.strictEqual(agent.is_reusable, 1);
|
|
111
|
-
});
|
|
112
|
-
it('should recognize subagent-N pattern as reusable', async () => {
|
|
113
|
-
const agentId = await getOrCreateAgent(adapter, 'subagent-42');
|
|
114
|
-
const agent = await adapter.getKnex()('m_agents')
|
|
115
|
-
.where({ id: agentId })
|
|
116
|
-
.first();
|
|
117
|
-
assert.strictEqual(agent.name, 'subagent-42');
|
|
118
|
-
assert.strictEqual(agent.is_reusable, 1);
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
describe('Agent release and cleanup', () => {
|
|
122
|
-
it('should mark generic agent as not in use', async () => {
|
|
123
|
-
const agentId = await getOrCreateAgent(adapter, '');
|
|
124
|
-
await releaseAgent(adapter, agentId);
|
|
125
|
-
const agent = await adapter.getKnex()('m_agents')
|
|
126
|
-
.where({ id: agentId })
|
|
127
|
-
.first();
|
|
128
|
-
assert.strictEqual(agent.in_use, 0);
|
|
129
|
-
});
|
|
130
|
-
it('should not release user-specified agents', async () => {
|
|
131
|
-
const agentId = await getOrCreateAgent(adapter, 'important-agent');
|
|
132
|
-
await releaseAgent(adapter, agentId);
|
|
133
|
-
const agent = await adapter.getKnex()('m_agents')
|
|
134
|
-
.where({ id: agentId })
|
|
135
|
-
.first();
|
|
136
|
-
// User-specified agents (is_reusable=false) should not be released
|
|
137
|
-
assert.strictEqual(agent.in_use, 1);
|
|
138
|
-
});
|
|
139
|
-
it('should release inactive agents after timeout', async () => {
|
|
140
|
-
const agentId1 = await getOrCreateAgent(adapter, '');
|
|
141
|
-
const agentId2 = await getOrCreateAgent(adapter, '');
|
|
142
|
-
// Set agent1 as inactive (old timestamp)
|
|
143
|
-
const oldTimestamp = Math.floor(Date.now() / 1000) - (25 * 3600); // 25 hours ago
|
|
144
|
-
await adapter.getKnex()('m_agents')
|
|
145
|
-
.where({ id: agentId1 })
|
|
146
|
-
.update({ last_active_ts: oldTimestamp });
|
|
147
|
-
// Release inactive agents (24 hour threshold)
|
|
148
|
-
const releasedCount = await releaseInactiveAgents(adapter, 24);
|
|
149
|
-
assert.strictEqual(releasedCount, 1);
|
|
150
|
-
const agent1 = await adapter.getKnex()('m_agents')
|
|
151
|
-
.where({ id: agentId1 })
|
|
152
|
-
.first();
|
|
153
|
-
const agent2 = await adapter.getKnex()('m_agents')
|
|
154
|
-
.where({ id: agentId2 })
|
|
155
|
-
.first();
|
|
156
|
-
assert.strictEqual(agent1.in_use, 0);
|
|
157
|
-
assert.strictEqual(agent2.in_use, 1);
|
|
158
|
-
});
|
|
159
|
-
it('should update agent activity timestamp', async () => {
|
|
160
|
-
const agentId = await getOrCreateAgent(adapter, 'test-agent');
|
|
161
|
-
const initialAgent = await adapter.getKnex()('m_agents')
|
|
162
|
-
.where({ id: agentId })
|
|
163
|
-
.first();
|
|
164
|
-
await new Promise(resolve => setTimeout(resolve, 100));
|
|
165
|
-
await updateAgentActivity(adapter, agentId);
|
|
166
|
-
const updatedAgent = await adapter.getKnex()('m_agents')
|
|
167
|
-
.where({ id: agentId })
|
|
168
|
-
.first();
|
|
169
|
-
assert.ok(updatedAgent.last_active_ts > initialAgent.last_active_ts);
|
|
170
|
-
});
|
|
171
|
-
});
|
|
172
|
-
describe('Integration with cleanup', () => {
|
|
173
|
-
it('should include agent release in clearOldData', async () => {
|
|
174
|
-
// Create some generic agents
|
|
175
|
-
const agentId1 = await getOrCreateAgent(adapter, '');
|
|
176
|
-
const agentId2 = await getOrCreateAgent(adapter, '');
|
|
177
|
-
const agentId3 = await getOrCreateAgent(adapter, '');
|
|
178
|
-
// Set agent1 and agent2 as old
|
|
179
|
-
const oldTimestamp = Math.floor(Date.now() / 1000) - (25 * 3600);
|
|
180
|
-
await adapter.getKnex()('m_agents')
|
|
181
|
-
.whereIn('id', [agentId1, agentId2])
|
|
182
|
-
.update({ last_active_ts: oldTimestamp });
|
|
183
|
-
// Run cleanup
|
|
184
|
-
const result = await clearOldData(undefined, adapter);
|
|
185
|
-
assert.strictEqual(result.agents_released, 2);
|
|
186
|
-
assert.strictEqual(result.success, true);
|
|
187
|
-
const agents = await adapter.getKnex()('m_agents')
|
|
188
|
-
.whereIn('id', [agentId1, agentId2, agentId3]);
|
|
189
|
-
assert.strictEqual(agents[0].in_use, false);
|
|
190
|
-
assert.strictEqual(agents[1].in_use, false);
|
|
191
|
-
assert.strictEqual(agents[2].in_use, true);
|
|
192
|
-
});
|
|
193
|
-
});
|
|
194
|
-
describe('Edge cases', () => {
|
|
195
|
-
it('should handle mixed user and generic agents', async () => {
|
|
196
|
-
const userAgent = await getOrCreateAgent(adapter, 'custom-agent');
|
|
197
|
-
const genericAgent1 = await getOrCreateAgent(adapter, '');
|
|
198
|
-
const genericAgent2 = await getOrCreateAgent(adapter, 'agent-5');
|
|
199
|
-
const agents = await adapter.getKnex()('m_agents')
|
|
200
|
-
.orderBy('id');
|
|
201
|
-
assert.strictEqual(agents.length, 3);
|
|
202
|
-
assert.strictEqual(agents[0].is_reusable, 0); // custom-agent
|
|
203
|
-
assert.strictEqual(agents[1].is_reusable, 1); // generic-1
|
|
204
|
-
assert.strictEqual(agents[2].is_reusable, 1); // agent-5
|
|
205
|
-
});
|
|
206
|
-
it('should handle concurrent agent creation', async () => {
|
|
207
|
-
// Create multiple agents concurrently
|
|
208
|
-
const promises = [
|
|
209
|
-
getOrCreateAgent(adapter, ''),
|
|
210
|
-
getOrCreateAgent(adapter, ''),
|
|
211
|
-
getOrCreateAgent(adapter, ''),
|
|
212
|
-
];
|
|
213
|
-
const agentIds = await Promise.all(promises);
|
|
214
|
-
// All should be created (no slot reuse since all concurrent)
|
|
215
|
-
assert.strictEqual(agentIds.length, 3);
|
|
216
|
-
assert.strictEqual(new Set(agentIds).size, 3); // All unique
|
|
217
|
-
const agents = await adapter.getKnex()('m_agents')
|
|
218
|
-
.whereIn('id', agentIds)
|
|
219
|
-
.orderBy('name');
|
|
220
|
-
assert.strictEqual(agents[0].name, 'generic-1');
|
|
221
|
-
assert.strictEqual(agents[1].name, 'generic-2');
|
|
222
|
-
assert.strictEqual(agents[2].name, 'generic-3');
|
|
223
|
-
});
|
|
224
|
-
it('should handle empty string as generic', async () => {
|
|
225
|
-
const agentId = await getOrCreateAgent(adapter, '');
|
|
226
|
-
const agent = await adapter.getKnex()('m_agents')
|
|
227
|
-
.where({ id: agentId })
|
|
228
|
-
.first();
|
|
229
|
-
assert.strictEqual(agent.is_reusable, 1);
|
|
230
|
-
assert.strictEqual(agent.name, 'generic-1');
|
|
231
|
-
});
|
|
232
|
-
it('should preserve system agent as non-reusable', async () => {
|
|
233
|
-
const agentId = await getOrCreateAgent(adapter, 'system');
|
|
234
|
-
const agent = await adapter.getKnex()('m_agents')
|
|
235
|
-
.where({ id: agentId })
|
|
236
|
-
.first();
|
|
237
|
-
assert.strictEqual(agent.name, 'system');
|
|
238
|
-
assert.strictEqual(agent.is_reusable, 0);
|
|
239
|
-
});
|
|
240
|
-
});
|
|
241
|
-
});
|
|
242
|
-
//# sourceMappingURL=agent-reuse.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent-reuse.test.js","sourceRoot":"","sources":["../../src/tests/agent-reuse.test.ts"],"names":[],"mappings":"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"}
|