sqlew 1.1.2 → 2.1.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/CHANGELOG.md +259 -0
- package/MIGRATION_v2.md +538 -0
- package/README.md +444 -79
- package/assets/schema.sql +122 -36
- package/dist/cli.d.ts +7 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +312 -0
- package/dist/cli.js.map +1 -0
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +18 -0
- package/dist/database.js.map +1 -1
- package/dist/index.js +373 -707
- package/dist/index.js.map +1 -1
- package/dist/migrations/add-v2.1.0-features.d.ts +29 -0
- package/dist/migrations/add-v2.1.0-features.d.ts.map +1 -0
- package/dist/migrations/add-v2.1.0-features.js +198 -0
- package/dist/migrations/add-v2.1.0-features.js.map +1 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +5 -0
- package/dist/schema.js.map +1 -1
- package/dist/tools/context.d.ts +91 -1
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +614 -0
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/files.d.ts +10 -1
- package/dist/tools/files.d.ts.map +1 -1
- package/dist/tools/files.js +98 -1
- package/dist/tools/files.js.map +1 -1
- package/dist/tools/messaging.d.ts +10 -1
- package/dist/tools/messaging.d.ts.map +1 -1
- package/dist/tools/messaging.js +107 -1
- package/dist/tools/messaging.js.map +1 -1
- package/dist/tools/utils.d.ts +9 -1
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tools/utils.js +115 -0
- package/dist/tools/utils.js.map +1 -1
- package/dist/types.d.ts +196 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/cleanup.d.ts +12 -1
- package/dist/utils/cleanup.d.ts.map +1 -1
- package/dist/utils/cleanup.js +20 -3
- package/dist/utils/cleanup.js.map +1 -1
- package/package.json +6 -3
package/assets/schema.sql
CHANGED
|
@@ -1,63 +1,63 @@
|
|
|
1
1
|
-- MCP Shared Context Server - Database Schema
|
|
2
|
-
-- Version:
|
|
2
|
+
-- Version: 2.1.0 (with activity log, smart defaults, batch ops, templates, CLI, subscriptions)
|
|
3
3
|
|
|
4
4
|
-- ============================================================================
|
|
5
|
-
--
|
|
5
|
+
-- Master Tables (Normalization)
|
|
6
6
|
-- ============================================================================
|
|
7
7
|
|
|
8
|
-
--
|
|
8
|
+
-- Agent Management
|
|
9
9
|
CREATE TABLE IF NOT EXISTS m_agents (
|
|
10
10
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
11
11
|
name TEXT UNIQUE NOT NULL
|
|
12
12
|
);
|
|
13
13
|
|
|
14
|
-
--
|
|
14
|
+
-- File Path Management
|
|
15
15
|
CREATE TABLE IF NOT EXISTS m_files (
|
|
16
16
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
17
17
|
path TEXT UNIQUE NOT NULL
|
|
18
18
|
);
|
|
19
19
|
|
|
20
|
-
--
|
|
20
|
+
-- Context Key Management
|
|
21
21
|
CREATE TABLE IF NOT EXISTS m_context_keys (
|
|
22
22
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
23
23
|
key TEXT UNIQUE NOT NULL
|
|
24
24
|
);
|
|
25
25
|
|
|
26
|
-
--
|
|
26
|
+
-- Constraint Category Management
|
|
27
27
|
CREATE TABLE IF NOT EXISTS m_constraint_categories (
|
|
28
28
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
29
29
|
name TEXT UNIQUE NOT NULL
|
|
30
30
|
);
|
|
31
31
|
|
|
32
|
-
--
|
|
32
|
+
-- Layer Management
|
|
33
33
|
CREATE TABLE IF NOT EXISTS m_layers (
|
|
34
34
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
35
35
|
name TEXT UNIQUE NOT NULL
|
|
36
36
|
);
|
|
37
37
|
|
|
38
|
-
--
|
|
38
|
+
-- Tag Management
|
|
39
39
|
CREATE TABLE IF NOT EXISTS m_tags (
|
|
40
40
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
41
41
|
name TEXT UNIQUE NOT NULL
|
|
42
42
|
);
|
|
43
43
|
|
|
44
|
-
--
|
|
44
|
+
-- Scope Management (Modules/Components)
|
|
45
45
|
CREATE TABLE IF NOT EXISTS m_scopes (
|
|
46
46
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
47
47
|
name TEXT UNIQUE NOT NULL
|
|
48
48
|
);
|
|
49
49
|
|
|
50
|
-
--
|
|
50
|
+
-- Configuration Management (Server Settings)
|
|
51
51
|
CREATE TABLE IF NOT EXISTS m_config (
|
|
52
52
|
key TEXT PRIMARY KEY,
|
|
53
53
|
value TEXT NOT NULL
|
|
54
54
|
);
|
|
55
55
|
|
|
56
56
|
-- ============================================================================
|
|
57
|
-
--
|
|
57
|
+
-- Transaction Tables
|
|
58
58
|
-- ============================================================================
|
|
59
59
|
|
|
60
|
-
--
|
|
60
|
+
-- Decisions (String Values)
|
|
61
61
|
CREATE TABLE IF NOT EXISTS t_decisions (
|
|
62
62
|
key_id INTEGER PRIMARY KEY REFERENCES m_context_keys(id),
|
|
63
63
|
value TEXT NOT NULL,
|
|
@@ -68,7 +68,7 @@ CREATE TABLE IF NOT EXISTS t_decisions (
|
|
|
68
68
|
ts INTEGER DEFAULT (unixepoch())
|
|
69
69
|
);
|
|
70
70
|
|
|
71
|
-
--
|
|
71
|
+
-- Decisions (Numeric Values)
|
|
72
72
|
CREATE TABLE IF NOT EXISTS t_decisions_numeric (
|
|
73
73
|
key_id INTEGER PRIMARY KEY REFERENCES m_context_keys(id),
|
|
74
74
|
value REAL NOT NULL,
|
|
@@ -79,7 +79,7 @@ CREATE TABLE IF NOT EXISTS t_decisions_numeric (
|
|
|
79
79
|
ts INTEGER DEFAULT (unixepoch())
|
|
80
80
|
);
|
|
81
81
|
|
|
82
|
-
--
|
|
82
|
+
-- Decision Version History
|
|
83
83
|
CREATE TABLE IF NOT EXISTS t_decision_history (
|
|
84
84
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
85
85
|
key_id INTEGER REFERENCES m_context_keys(id),
|
|
@@ -89,33 +89,33 @@ CREATE TABLE IF NOT EXISTS t_decision_history (
|
|
|
89
89
|
ts INTEGER NOT NULL
|
|
90
90
|
);
|
|
91
91
|
|
|
92
|
-
--
|
|
92
|
+
-- Decision Tagging (Many-to-Many)
|
|
93
93
|
CREATE TABLE IF NOT EXISTS t_decision_tags (
|
|
94
94
|
decision_key_id INTEGER REFERENCES m_context_keys(id),
|
|
95
95
|
tag_id INTEGER REFERENCES m_tags(id),
|
|
96
96
|
PRIMARY KEY (decision_key_id, tag_id)
|
|
97
97
|
);
|
|
98
98
|
|
|
99
|
-
--
|
|
99
|
+
-- Decision Scopes (Many-to-Many)
|
|
100
100
|
CREATE TABLE IF NOT EXISTS t_decision_scopes (
|
|
101
101
|
decision_key_id INTEGER REFERENCES m_context_keys(id),
|
|
102
102
|
scope_id INTEGER REFERENCES m_scopes(id),
|
|
103
103
|
PRIMARY KEY (decision_key_id, scope_id)
|
|
104
104
|
);
|
|
105
105
|
|
|
106
|
-
--
|
|
106
|
+
-- Inter-Agent Messages
|
|
107
107
|
CREATE TABLE IF NOT EXISTS t_agent_messages (
|
|
108
108
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
109
109
|
from_agent_id INTEGER NOT NULL REFERENCES m_agents(id),
|
|
110
110
|
to_agent_id INTEGER REFERENCES m_agents(id), -- NULL = broadcast
|
|
111
111
|
msg_type INTEGER NOT NULL, -- 1=decision, 2=warning, 3=request, 4=info
|
|
112
112
|
priority INTEGER DEFAULT 2, -- 1=low, 2=medium, 3=high, 4=critical
|
|
113
|
-
payload TEXT, -- JSON
|
|
113
|
+
payload TEXT, -- JSON string (only when needed)
|
|
114
114
|
ts INTEGER DEFAULT (unixepoch()),
|
|
115
115
|
read INTEGER DEFAULT 0
|
|
116
116
|
);
|
|
117
117
|
|
|
118
|
-
--
|
|
118
|
+
-- File Change History
|
|
119
119
|
CREATE TABLE IF NOT EXISTS t_file_changes (
|
|
120
120
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
121
121
|
file_id INTEGER NOT NULL REFERENCES m_files(id),
|
|
@@ -126,7 +126,7 @@ CREATE TABLE IF NOT EXISTS t_file_changes (
|
|
|
126
126
|
ts INTEGER DEFAULT (unixepoch())
|
|
127
127
|
);
|
|
128
128
|
|
|
129
|
-
--
|
|
129
|
+
-- Constraints/Requirements
|
|
130
130
|
CREATE TABLE IF NOT EXISTS t_constraints (
|
|
131
131
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
132
132
|
category_id INTEGER NOT NULL REFERENCES m_constraint_categories(id),
|
|
@@ -138,15 +138,36 @@ CREATE TABLE IF NOT EXISTS t_constraints (
|
|
|
138
138
|
ts INTEGER DEFAULT (unixepoch())
|
|
139
139
|
);
|
|
140
140
|
|
|
141
|
-
--
|
|
141
|
+
-- Constraint Tagging (Many-to-Many)
|
|
142
142
|
CREATE TABLE IF NOT EXISTS t_constraint_tags (
|
|
143
143
|
constraint_id INTEGER REFERENCES t_constraints(id),
|
|
144
144
|
tag_id INTEGER REFERENCES m_tags(id),
|
|
145
145
|
PRIMARY KEY (constraint_id, tag_id)
|
|
146
146
|
);
|
|
147
147
|
|
|
148
|
+
-- Activity Log (v2.1.0 - FR-001)
|
|
149
|
+
CREATE TABLE IF NOT EXISTS t_activity_log (
|
|
150
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
151
|
+
ts INTEGER DEFAULT (unixepoch()),
|
|
152
|
+
agent_id INTEGER NOT NULL REFERENCES m_agents(id),
|
|
153
|
+
action_type TEXT NOT NULL, -- 'decision_set', 'decision_update', 'message_send', 'file_record'
|
|
154
|
+
target TEXT NOT NULL, -- key name, message id, file path, etc.
|
|
155
|
+
layer_id INTEGER REFERENCES m_layers(id),
|
|
156
|
+
details TEXT -- JSON string with additional details
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
-- Decision Templates (v2.1.0 - FR-006)
|
|
160
|
+
CREATE TABLE IF NOT EXISTS t_decision_templates (
|
|
161
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
162
|
+
name TEXT UNIQUE NOT NULL,
|
|
163
|
+
defaults TEXT NOT NULL, -- JSON: {layer, status, tags, priority}
|
|
164
|
+
required_fields TEXT, -- JSON array: ["cve_id", "severity"]
|
|
165
|
+
created_by INTEGER REFERENCES m_agents(id),
|
|
166
|
+
ts INTEGER DEFAULT (unixepoch())
|
|
167
|
+
);
|
|
168
|
+
|
|
148
169
|
-- ============================================================================
|
|
149
|
-
--
|
|
170
|
+
-- Indexes
|
|
150
171
|
-- ============================================================================
|
|
151
172
|
|
|
152
173
|
CREATE INDEX IF NOT EXISTS idx_decisions_ts ON t_decisions(ts DESC);
|
|
@@ -162,12 +183,15 @@ CREATE INDEX IF NOT EXISTS idx_constraints_active ON t_constraints(active, categ
|
|
|
162
183
|
CREATE INDEX IF NOT EXISTS idx_constraints_priority ON t_constraints(priority DESC);
|
|
163
184
|
CREATE INDEX IF NOT EXISTS idx_decision_tags_tag ON t_decision_tags(tag_id);
|
|
164
185
|
CREATE INDEX IF NOT EXISTS idx_decision_scopes_scope ON t_decision_scopes(scope_id);
|
|
186
|
+
CREATE INDEX IF NOT EXISTS idx_activity_log_ts ON t_activity_log(ts DESC);
|
|
187
|
+
CREATE INDEX IF NOT EXISTS idx_activity_log_agent ON t_activity_log(agent_id);
|
|
188
|
+
CREATE INDEX IF NOT EXISTS idx_activity_log_action ON t_activity_log(action_type);
|
|
165
189
|
|
|
166
190
|
-- ============================================================================
|
|
167
|
-
--
|
|
191
|
+
-- Views (Token Efficiency)
|
|
168
192
|
-- ============================================================================
|
|
169
193
|
|
|
170
|
-
--
|
|
194
|
+
-- Tagged Decisions (Most Efficient View)
|
|
171
195
|
CREATE VIEW IF NOT EXISTS v_tagged_decisions AS
|
|
172
196
|
SELECT
|
|
173
197
|
k.key,
|
|
@@ -188,7 +212,7 @@ JOIN m_context_keys k ON d.key_id = k.id
|
|
|
188
212
|
LEFT JOIN m_layers l ON d.layer_id = l.id
|
|
189
213
|
LEFT JOIN m_agents a ON d.agent_id = a.id;
|
|
190
214
|
|
|
191
|
-
--
|
|
215
|
+
-- Active Context (Last Hour, Active Only)
|
|
192
216
|
CREATE VIEW IF NOT EXISTS v_active_context AS
|
|
193
217
|
SELECT
|
|
194
218
|
k.key,
|
|
@@ -204,7 +228,7 @@ LEFT JOIN m_agents a ON d.agent_id = a.id
|
|
|
204
228
|
WHERE d.status = 1 AND d.ts > unixepoch() - 3600
|
|
205
229
|
ORDER BY d.ts DESC;
|
|
206
230
|
|
|
207
|
-
--
|
|
231
|
+
-- Layer Summary
|
|
208
232
|
CREATE VIEW IF NOT EXISTS v_layer_summary AS
|
|
209
233
|
SELECT
|
|
210
234
|
l.name as layer,
|
|
@@ -217,7 +241,7 @@ LEFT JOIN t_file_changes fc ON l.id = fc.layer_id AND fc.ts > unixepoch() - 3600
|
|
|
217
241
|
LEFT JOIN t_constraints c ON l.id = c.layer_id AND c.active = 1
|
|
218
242
|
GROUP BY l.id;
|
|
219
243
|
|
|
220
|
-
--
|
|
244
|
+
-- Unread Messages by Priority
|
|
221
245
|
CREATE VIEW IF NOT EXISTS v_unread_messages_by_priority AS
|
|
222
246
|
SELECT
|
|
223
247
|
a.name as agent,
|
|
@@ -229,7 +253,7 @@ WHERE m.read = 0
|
|
|
229
253
|
GROUP BY m.to_agent_id, m.priority
|
|
230
254
|
ORDER BY m.priority DESC;
|
|
231
255
|
|
|
232
|
-
--
|
|
256
|
+
-- Recent File Changes (With Layer)
|
|
233
257
|
CREATE VIEW IF NOT EXISTS v_recent_file_changes AS
|
|
234
258
|
SELECT
|
|
235
259
|
f.path,
|
|
@@ -245,7 +269,7 @@ LEFT JOIN m_layers l ON fc.layer_id = l.id
|
|
|
245
269
|
WHERE fc.ts > unixepoch() - 3600
|
|
246
270
|
ORDER BY fc.ts DESC;
|
|
247
271
|
|
|
248
|
-
--
|
|
272
|
+
-- Tagged Constraints
|
|
249
273
|
CREATE VIEW IF NOT EXISTS v_tagged_constraints AS
|
|
250
274
|
SELECT
|
|
251
275
|
c.id,
|
|
@@ -266,10 +290,10 @@ WHERE c.active = 1
|
|
|
266
290
|
ORDER BY c.priority DESC, cc.name, c.ts DESC;
|
|
267
291
|
|
|
268
292
|
-- ============================================================================
|
|
269
|
-
--
|
|
293
|
+
-- Triggers (Automatic Processing)
|
|
270
294
|
-- ============================================================================
|
|
271
295
|
|
|
272
|
-
--
|
|
296
|
+
-- Automatic Version History Recording
|
|
273
297
|
CREATE TRIGGER IF NOT EXISTS trg_record_decision_history
|
|
274
298
|
AFTER UPDATE ON t_decisions
|
|
275
299
|
WHEN OLD.value != NEW.value OR OLD.version != NEW.version
|
|
@@ -278,11 +302,65 @@ BEGIN
|
|
|
278
302
|
VALUES (OLD.key_id, OLD.version, OLD.value, OLD.agent_id, OLD.ts);
|
|
279
303
|
END;
|
|
280
304
|
|
|
305
|
+
-- Activity Log Recording Triggers (v2.1.0 - FR-001)
|
|
306
|
+
-- Decision Addition Log
|
|
307
|
+
CREATE TRIGGER IF NOT EXISTS trg_log_decision_set
|
|
308
|
+
AFTER INSERT ON t_decisions
|
|
309
|
+
BEGIN
|
|
310
|
+
INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
|
|
311
|
+
SELECT
|
|
312
|
+
COALESCE(NEW.agent_id, (SELECT id FROM m_agents WHERE name = 'system' LIMIT 1)),
|
|
313
|
+
'decision_set',
|
|
314
|
+
(SELECT key FROM m_context_keys WHERE id = NEW.key_id),
|
|
315
|
+
NEW.layer_id,
|
|
316
|
+
json_object('value', NEW.value, 'version', NEW.version, 'status', NEW.status);
|
|
317
|
+
END;
|
|
318
|
+
|
|
319
|
+
-- Decision Update Log
|
|
320
|
+
CREATE TRIGGER IF NOT EXISTS trg_log_decision_update
|
|
321
|
+
AFTER UPDATE ON t_decisions
|
|
322
|
+
WHEN OLD.value != NEW.value OR OLD.version != NEW.version OR OLD.status != NEW.status
|
|
323
|
+
BEGIN
|
|
324
|
+
INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
|
|
325
|
+
SELECT
|
|
326
|
+
COALESCE(NEW.agent_id, (SELECT id FROM m_agents WHERE name = 'system' LIMIT 1)),
|
|
327
|
+
'decision_update',
|
|
328
|
+
(SELECT key FROM m_context_keys WHERE id = NEW.key_id),
|
|
329
|
+
NEW.layer_id,
|
|
330
|
+
json_object('old_value', OLD.value, 'new_value', NEW.value, 'old_version', OLD.version, 'new_version', NEW.version, 'old_status', OLD.status, 'new_status', NEW.status);
|
|
331
|
+
END;
|
|
332
|
+
|
|
333
|
+
-- Message Send Log
|
|
334
|
+
CREATE TRIGGER IF NOT EXISTS trg_log_message_send
|
|
335
|
+
AFTER INSERT ON t_agent_messages
|
|
336
|
+
BEGIN
|
|
337
|
+
INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
|
|
338
|
+
SELECT
|
|
339
|
+
NEW.from_agent_id,
|
|
340
|
+
'message_send',
|
|
341
|
+
'msg_id:' || NEW.id,
|
|
342
|
+
NULL,
|
|
343
|
+
json_object('to_agent_id', NEW.to_agent_id, 'msg_type', NEW.msg_type, 'priority', NEW.priority);
|
|
344
|
+
END;
|
|
345
|
+
|
|
346
|
+
-- File Change Log
|
|
347
|
+
CREATE TRIGGER IF NOT EXISTS trg_log_file_record
|
|
348
|
+
AFTER INSERT ON t_file_changes
|
|
349
|
+
BEGIN
|
|
350
|
+
INSERT INTO t_activity_log (agent_id, action_type, target, layer_id, details)
|
|
351
|
+
SELECT
|
|
352
|
+
NEW.agent_id,
|
|
353
|
+
'file_record',
|
|
354
|
+
(SELECT path FROM m_files WHERE id = NEW.file_id),
|
|
355
|
+
NEW.layer_id,
|
|
356
|
+
json_object('change_type', NEW.change_type, 'description', NEW.description);
|
|
357
|
+
END;
|
|
358
|
+
|
|
281
359
|
-- ============================================================================
|
|
282
|
-
--
|
|
360
|
+
-- Initial Data
|
|
283
361
|
-- ============================================================================
|
|
284
362
|
|
|
285
|
-
--
|
|
363
|
+
-- Standard Layers
|
|
286
364
|
INSERT OR IGNORE INTO m_layers (name) VALUES
|
|
287
365
|
('presentation'),
|
|
288
366
|
('business'),
|
|
@@ -290,13 +368,13 @@ INSERT OR IGNORE INTO m_layers (name) VALUES
|
|
|
290
368
|
('infrastructure'),
|
|
291
369
|
('cross-cutting');
|
|
292
370
|
|
|
293
|
-
--
|
|
371
|
+
-- Standard Categories
|
|
294
372
|
INSERT OR IGNORE INTO m_constraint_categories (name) VALUES
|
|
295
373
|
('performance'),
|
|
296
374
|
('architecture'),
|
|
297
375
|
('security');
|
|
298
376
|
|
|
299
|
-
--
|
|
377
|
+
-- Common Tags
|
|
300
378
|
INSERT OR IGNORE INTO m_tags (name) VALUES
|
|
301
379
|
('authentication'),
|
|
302
380
|
('authorization'),
|
|
@@ -309,8 +387,16 @@ INSERT OR IGNORE INTO m_tags (name) VALUES
|
|
|
309
387
|
('validation'),
|
|
310
388
|
('error-handling');
|
|
311
389
|
|
|
312
|
-
--
|
|
390
|
+
-- Default Settings (Auto-deletion Configuration)
|
|
313
391
|
INSERT OR IGNORE INTO m_config (key, value) VALUES
|
|
314
392
|
('autodelete_ignore_weekend', '0'),
|
|
315
393
|
('autodelete_message_hours', '24'),
|
|
316
394
|
('autodelete_file_history_days', '7');
|
|
395
|
+
|
|
396
|
+
-- Built-in Templates (Built-in Decision Templates - FR-006)
|
|
397
|
+
INSERT OR IGNORE INTO t_decision_templates (name, defaults, required_fields, created_by, ts) VALUES
|
|
398
|
+
('breaking_change', '{"layer":"business","status":"active","tags":["breaking"]}', NULL, NULL, unixepoch()),
|
|
399
|
+
('security_vulnerability', '{"layer":"infrastructure","status":"active","tags":["security","vulnerability"]}', '["cve_id","severity"]', NULL, unixepoch()),
|
|
400
|
+
('performance_optimization', '{"layer":"business","status":"active","tags":["performance","optimization"]}', NULL, NULL, unixepoch()),
|
|
401
|
+
('deprecation', '{"layer":"business","status":"active","tags":["deprecation"]}', NULL, NULL, unixepoch()),
|
|
402
|
+
('architecture_decision', '{"layer":"infrastructure","status":"active","tags":["architecture","adr"]}', NULL, NULL, unixepoch());
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;GAGG"}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* CLI for sqlew - Standalone query commands for mcp-sqlew
|
|
4
|
+
* Provides quick terminal access to decisions, messages, files, and activity logs
|
|
5
|
+
*/
|
|
6
|
+
import { initializeDatabase } from './database.js';
|
|
7
|
+
import { searchAdvanced } from './tools/context.js';
|
|
8
|
+
import { getMessages } from './tools/messaging.js';
|
|
9
|
+
import { getFileChanges } from './tools/files.js';
|
|
10
|
+
import { getActivityLog } from './tools/utils.js';
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Helper Functions
|
|
13
|
+
// ============================================================================
|
|
14
|
+
/**
|
|
15
|
+
* Parse command-line arguments into structured object
|
|
16
|
+
*/
|
|
17
|
+
function parseArgs(args) {
|
|
18
|
+
const parsed = {};
|
|
19
|
+
for (let i = 0; i < args.length; i++) {
|
|
20
|
+
const arg = args[i];
|
|
21
|
+
if (arg.startsWith('--')) {
|
|
22
|
+
const key = arg.slice(2);
|
|
23
|
+
const value = args[i + 1];
|
|
24
|
+
if (key === 'unread') {
|
|
25
|
+
parsed.unread = true;
|
|
26
|
+
}
|
|
27
|
+
else if (key === 'help') {
|
|
28
|
+
parsed.help = true;
|
|
29
|
+
}
|
|
30
|
+
else if (value && !value.startsWith('--')) {
|
|
31
|
+
// Handle different key types
|
|
32
|
+
if (key === 'limit') {
|
|
33
|
+
parsed[key] = parseInt(value, 10);
|
|
34
|
+
}
|
|
35
|
+
else if (key === 'db-path') {
|
|
36
|
+
parsed['db-path'] = value;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
parsed[key] = value;
|
|
40
|
+
}
|
|
41
|
+
i++; // Skip the value in next iteration
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
else if (!parsed.command) {
|
|
45
|
+
parsed.command = arg;
|
|
46
|
+
}
|
|
47
|
+
else if (!parsed.subcommand) {
|
|
48
|
+
parsed.subcommand = arg;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return parsed;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Format output as JSON
|
|
55
|
+
*/
|
|
56
|
+
function formatJSON(data) {
|
|
57
|
+
console.log(JSON.stringify(data, null, 2));
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Format output as ASCII table
|
|
61
|
+
*/
|
|
62
|
+
function formatTable(data, headers) {
|
|
63
|
+
if (data.length === 0) {
|
|
64
|
+
console.log('No results found.');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
// Calculate column widths
|
|
68
|
+
const widths = headers.map(h => h.length);
|
|
69
|
+
data.forEach(row => {
|
|
70
|
+
headers.forEach((header, i) => {
|
|
71
|
+
const value = String(row[header] || '');
|
|
72
|
+
widths[i] = Math.max(widths[i], Math.min(value.length, 50));
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
// Print header
|
|
76
|
+
const headerRow = headers.map((h, i) => h.padEnd(widths[i])).join(' | ');
|
|
77
|
+
console.log(headerRow);
|
|
78
|
+
console.log(headers.map((_, i) => '-'.repeat(widths[i])).join('-+-'));
|
|
79
|
+
// Print rows
|
|
80
|
+
data.forEach(row => {
|
|
81
|
+
const rowStr = headers.map((header, i) => {
|
|
82
|
+
let value = String(row[header] || '');
|
|
83
|
+
if (value.length > 50) {
|
|
84
|
+
value = value.slice(0, 47) + '...';
|
|
85
|
+
}
|
|
86
|
+
return value.padEnd(widths[i]);
|
|
87
|
+
}).join(' | ');
|
|
88
|
+
console.log(rowStr);
|
|
89
|
+
});
|
|
90
|
+
console.log(`\nTotal: ${data.length} result(s)`);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Show help message
|
|
94
|
+
*/
|
|
95
|
+
function showHelp() {
|
|
96
|
+
console.log(`
|
|
97
|
+
sqlew CLI - Query tool for mcp-sqlew v2.1.0
|
|
98
|
+
|
|
99
|
+
USAGE:
|
|
100
|
+
sqlew query <subcommand> [options]
|
|
101
|
+
|
|
102
|
+
SUBCOMMANDS:
|
|
103
|
+
decisions Query decisions with filtering
|
|
104
|
+
messages Query agent messages
|
|
105
|
+
files Query file changes
|
|
106
|
+
activity Query activity log
|
|
107
|
+
|
|
108
|
+
OPTIONS:
|
|
109
|
+
--layer <layer> Filter by layer (presentation, business, data, infrastructure, cross-cutting)
|
|
110
|
+
--tags <tags> Filter by tags (comma-separated)
|
|
111
|
+
--since <time> Time filter (e.g., "5m", "1h", "2d", or ISO timestamp)
|
|
112
|
+
--unread Show only unread messages (messages only)
|
|
113
|
+
--priority <priority> Filter by priority (low, medium, high, critical)
|
|
114
|
+
--agent <agent> Filter by agent name
|
|
115
|
+
--actions <actions> Filter by action types (comma-separated, activity only)
|
|
116
|
+
--limit <number> Limit number of results
|
|
117
|
+
--output <format> Output format: json or table (default: json)
|
|
118
|
+
--db-path <path> Database file path (default: .sqlew/sqlew.db)
|
|
119
|
+
--help Show this help message
|
|
120
|
+
|
|
121
|
+
EXAMPLES:
|
|
122
|
+
# Query active decisions with breaking changes
|
|
123
|
+
sqlew query decisions --layer=business --tags=breaking --output=table
|
|
124
|
+
|
|
125
|
+
# Query unread high-priority messages
|
|
126
|
+
sqlew query messages --unread --priority=high --output=json
|
|
127
|
+
|
|
128
|
+
# Query recent file changes in last hour
|
|
129
|
+
sqlew query files --since=1h --output=table
|
|
130
|
+
|
|
131
|
+
# Query recent activity from all agents
|
|
132
|
+
sqlew query activity --since=5m --agent=* --output=json
|
|
133
|
+
|
|
134
|
+
# Query activity with specific actions
|
|
135
|
+
sqlew query activity --actions=decision_set,message_send --limit=20
|
|
136
|
+
`);
|
|
137
|
+
}
|
|
138
|
+
// ============================================================================
|
|
139
|
+
// Query Commands
|
|
140
|
+
// ============================================================================
|
|
141
|
+
/**
|
|
142
|
+
* Query decisions command
|
|
143
|
+
*/
|
|
144
|
+
function queryDecisions(args) {
|
|
145
|
+
const outputFormat = args.output || 'json';
|
|
146
|
+
// Build query params
|
|
147
|
+
const params = {};
|
|
148
|
+
if (args.layer) {
|
|
149
|
+
params.layers = [args.layer];
|
|
150
|
+
}
|
|
151
|
+
if (args.tags) {
|
|
152
|
+
params.tags_any = args.tags.split(',').map(t => t.trim());
|
|
153
|
+
}
|
|
154
|
+
if (args.since) {
|
|
155
|
+
params.updated_after = args.since;
|
|
156
|
+
}
|
|
157
|
+
if (args.limit) {
|
|
158
|
+
params.limit = args.limit;
|
|
159
|
+
}
|
|
160
|
+
// Execute query
|
|
161
|
+
const result = searchAdvanced(params);
|
|
162
|
+
// Output results
|
|
163
|
+
if (outputFormat === 'json') {
|
|
164
|
+
formatJSON(result);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
formatTable(result.decisions, ['key', 'value', 'version', 'status', 'layer', 'tags', 'updated']);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Query messages command
|
|
172
|
+
*/
|
|
173
|
+
function queryMessages(args) {
|
|
174
|
+
const outputFormat = args.output || 'json';
|
|
175
|
+
// Agent name is required for messages
|
|
176
|
+
const agentName = args.agent || 'cli';
|
|
177
|
+
// Build query params
|
|
178
|
+
const params = {
|
|
179
|
+
agent_name: agentName,
|
|
180
|
+
};
|
|
181
|
+
if (args.unread) {
|
|
182
|
+
params.unread_only = true;
|
|
183
|
+
}
|
|
184
|
+
if (args.priority) {
|
|
185
|
+
params.priority_filter = args.priority;
|
|
186
|
+
}
|
|
187
|
+
if (args.limit) {
|
|
188
|
+
params.limit = args.limit;
|
|
189
|
+
}
|
|
190
|
+
// Execute query
|
|
191
|
+
const result = getMessages(params);
|
|
192
|
+
// Output results
|
|
193
|
+
if (outputFormat === 'json') {
|
|
194
|
+
formatJSON(result);
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
formatTable(result.messages, ['id', 'from_agent', 'msg_type', 'priority', 'timestamp', 'read']);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Query files command
|
|
202
|
+
*/
|
|
203
|
+
function queryFiles(args) {
|
|
204
|
+
const outputFormat = args.output || 'json';
|
|
205
|
+
// Build query params
|
|
206
|
+
const params = {};
|
|
207
|
+
if (args.since) {
|
|
208
|
+
params.since = args.since;
|
|
209
|
+
}
|
|
210
|
+
if (args.layer) {
|
|
211
|
+
params.layer = args.layer;
|
|
212
|
+
}
|
|
213
|
+
if (args.agent) {
|
|
214
|
+
params.agent_name = args.agent;
|
|
215
|
+
}
|
|
216
|
+
if (args.limit) {
|
|
217
|
+
params.limit = args.limit;
|
|
218
|
+
}
|
|
219
|
+
// Execute query
|
|
220
|
+
const result = getFileChanges(params);
|
|
221
|
+
// Output results
|
|
222
|
+
if (outputFormat === 'json') {
|
|
223
|
+
formatJSON(result);
|
|
224
|
+
}
|
|
225
|
+
else {
|
|
226
|
+
formatTable(result.changes, ['path', 'changed_by', 'change_type', 'layer', 'changed_at']);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Query activity command
|
|
231
|
+
*/
|
|
232
|
+
function queryActivity(args) {
|
|
233
|
+
const outputFormat = args.output || 'json';
|
|
234
|
+
// Build query params
|
|
235
|
+
const params = {};
|
|
236
|
+
if (args.since) {
|
|
237
|
+
params.since = args.since;
|
|
238
|
+
}
|
|
239
|
+
if (args.agent) {
|
|
240
|
+
// Support wildcard for all agents
|
|
241
|
+
if (args.agent === '*') {
|
|
242
|
+
params.agent_names = ['*'];
|
|
243
|
+
}
|
|
244
|
+
else {
|
|
245
|
+
params.agent_names = args.agent.split(',').map(a => a.trim());
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (args.actions) {
|
|
249
|
+
params.actions = args.actions.split(',').map(a => a.trim());
|
|
250
|
+
}
|
|
251
|
+
if (args.limit) {
|
|
252
|
+
params.limit = args.limit;
|
|
253
|
+
}
|
|
254
|
+
// Execute query
|
|
255
|
+
const result = getActivityLog(params);
|
|
256
|
+
// Output results
|
|
257
|
+
if (outputFormat === 'json') {
|
|
258
|
+
formatJSON(result);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
formatTable(result.activities, ['id', 'timestamp', 'agent', 'action', 'target', 'layer']);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// ============================================================================
|
|
265
|
+
// Main Entry Point
|
|
266
|
+
// ============================================================================
|
|
267
|
+
function main() {
|
|
268
|
+
const args = parseArgs(process.argv.slice(2));
|
|
269
|
+
// Show help if requested or no command
|
|
270
|
+
if (args.help || !args.command) {
|
|
271
|
+
showHelp();
|
|
272
|
+
process.exit(0);
|
|
273
|
+
}
|
|
274
|
+
try {
|
|
275
|
+
// Initialize database
|
|
276
|
+
const dbPath = args['db-path'];
|
|
277
|
+
initializeDatabase(dbPath);
|
|
278
|
+
// Route to appropriate command
|
|
279
|
+
if (args.command === 'query') {
|
|
280
|
+
switch (args.subcommand) {
|
|
281
|
+
case 'decisions':
|
|
282
|
+
queryDecisions(args);
|
|
283
|
+
break;
|
|
284
|
+
case 'messages':
|
|
285
|
+
queryMessages(args);
|
|
286
|
+
break;
|
|
287
|
+
case 'files':
|
|
288
|
+
queryFiles(args);
|
|
289
|
+
break;
|
|
290
|
+
case 'activity':
|
|
291
|
+
queryActivity(args);
|
|
292
|
+
break;
|
|
293
|
+
default:
|
|
294
|
+
console.error(`Unknown subcommand: ${args.subcommand}`);
|
|
295
|
+
console.error('Run "sqlew --help" for usage information.');
|
|
296
|
+
process.exit(1);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
console.error(`Unknown command: ${args.command}`);
|
|
301
|
+
console.error('Run "sqlew --help" for usage information.');
|
|
302
|
+
process.exit(1);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
catch (error) {
|
|
306
|
+
console.error('Error:', error instanceof Error ? error.message : String(error));
|
|
307
|
+
process.exit(1);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
// Run main function
|
|
311
|
+
main();
|
|
312
|
+
//# sourceMappingURL=cli.js.map
|