sqlew 3.2.2 → 3.2.3
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 +35 -0
- package/README.md +46 -1
- package/dist/index.js +23 -1005
- package/dist/index.js.map +1 -1
- package/dist/tools/config.d.ts +10 -0
- package/dist/tools/config.d.ts.map +1 -1
- package/dist/tools/config.js +105 -0
- package/dist/tools/config.js.map +1 -1
- package/dist/tools/constraints.d.ts +10 -0
- package/dist/tools/constraints.d.ts.map +1 -1
- package/dist/tools/constraints.js +167 -0
- package/dist/tools/constraints.js.map +1 -1
- package/dist/tools/context.d.ts +8 -0
- package/dist/tools/context.d.ts.map +1 -1
- package/dist/tools/context.js +332 -103
- package/dist/tools/context.js.map +1 -1
- package/dist/tools/files.d.ts +8 -0
- package/dist/tools/files.d.ts.map +1 -1
- package/dist/tools/files.js +125 -0
- package/dist/tools/files.js.map +1 -1
- package/dist/tools/messaging.d.ts +8 -0
- package/dist/tools/messaging.d.ts.map +1 -1
- package/dist/tools/messaging.js +134 -0
- package/dist/tools/messaging.js.map +1 -1
- package/dist/tools/tasks.d.ts +9 -0
- package/dist/tools/tasks.d.ts.map +1 -1
- package/dist/tools/tasks.js +354 -0
- package/dist/tools/tasks.js.map +1 -1
- package/dist/tools/utils.d.ts +10 -0
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tools/utils.js +135 -0
- package/dist/tools/utils.js.map +1 -1
- package/docs/HELP_PREVIEW_COMPARISON.md +259 -0
- package/docs/TOOL_REFERENCE.md +158 -1
- package/package.json +2 -2
package/dist/tools/context.js
CHANGED
|
@@ -44,31 +44,31 @@ function setDecisionInternal(params, db) {
|
|
|
44
44
|
// Insert or update decision based on value type
|
|
45
45
|
if (isNumeric) {
|
|
46
46
|
// Numeric decision
|
|
47
|
-
const stmt = db.prepare(`
|
|
48
|
-
INSERT INTO t_decisions_numeric (key_id, value, agent_id, layer_id, version, status, ts)
|
|
49
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
50
|
-
ON CONFLICT(key_id) DO UPDATE SET
|
|
51
|
-
value = excluded.value,
|
|
52
|
-
agent_id = excluded.agent_id,
|
|
53
|
-
layer_id = excluded.layer_id,
|
|
54
|
-
version = excluded.version,
|
|
55
|
-
status = excluded.status,
|
|
56
|
-
ts = excluded.ts
|
|
47
|
+
const stmt = db.prepare(`
|
|
48
|
+
INSERT INTO t_decisions_numeric (key_id, value, agent_id, layer_id, version, status, ts)
|
|
49
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
50
|
+
ON CONFLICT(key_id) DO UPDATE SET
|
|
51
|
+
value = excluded.value,
|
|
52
|
+
agent_id = excluded.agent_id,
|
|
53
|
+
layer_id = excluded.layer_id,
|
|
54
|
+
version = excluded.version,
|
|
55
|
+
status = excluded.status,
|
|
56
|
+
ts = excluded.ts
|
|
57
57
|
`);
|
|
58
58
|
stmt.run(keyId, value, agentId, layerId, version, status, ts);
|
|
59
59
|
}
|
|
60
60
|
else {
|
|
61
61
|
// String decision
|
|
62
|
-
const stmt = db.prepare(`
|
|
63
|
-
INSERT INTO t_decisions (key_id, value, agent_id, layer_id, version, status, ts)
|
|
64
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
65
|
-
ON CONFLICT(key_id) DO UPDATE SET
|
|
66
|
-
value = excluded.value,
|
|
67
|
-
agent_id = excluded.agent_id,
|
|
68
|
-
layer_id = excluded.layer_id,
|
|
69
|
-
version = excluded.version,
|
|
70
|
-
status = excluded.status,
|
|
71
|
-
ts = excluded.ts
|
|
62
|
+
const stmt = db.prepare(`
|
|
63
|
+
INSERT INTO t_decisions (key_id, value, agent_id, layer_id, version, status, ts)
|
|
64
|
+
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
65
|
+
ON CONFLICT(key_id) DO UPDATE SET
|
|
66
|
+
value = excluded.value,
|
|
67
|
+
agent_id = excluded.agent_id,
|
|
68
|
+
layer_id = excluded.layer_id,
|
|
69
|
+
version = excluded.version,
|
|
70
|
+
status = excluded.status,
|
|
71
|
+
ts = excluded.ts
|
|
72
72
|
`);
|
|
73
73
|
stmt.run(keyId, String(value), agentId, layerId, version, status, ts);
|
|
74
74
|
}
|
|
@@ -347,16 +347,16 @@ export function getVersions(params) {
|
|
|
347
347
|
}
|
|
348
348
|
const keyId = keyResult.id;
|
|
349
349
|
// Query t_decision_history with agent join
|
|
350
|
-
const stmt = db.prepare(`
|
|
351
|
-
SELECT
|
|
352
|
-
dh.version,
|
|
353
|
-
dh.value,
|
|
354
|
-
a.name as agent_name,
|
|
355
|
-
datetime(dh.ts, 'unixepoch') as timestamp
|
|
356
|
-
FROM t_decision_history dh
|
|
357
|
-
LEFT JOIN m_agents a ON dh.agent_id = a.id
|
|
358
|
-
WHERE dh.key_id = ?
|
|
359
|
-
ORDER BY dh.ts DESC
|
|
350
|
+
const stmt = db.prepare(`
|
|
351
|
+
SELECT
|
|
352
|
+
dh.version,
|
|
353
|
+
dh.value,
|
|
354
|
+
a.name as agent_name,
|
|
355
|
+
datetime(dh.ts, 'unixepoch') as timestamp
|
|
356
|
+
FROM t_decision_history dh
|
|
357
|
+
LEFT JOIN m_agents a ON dh.agent_id = a.id
|
|
358
|
+
WHERE dh.key_id = ?
|
|
359
|
+
ORDER BY dh.ts DESC
|
|
360
360
|
`);
|
|
361
361
|
const rows = stmt.all(keyId);
|
|
362
362
|
// Transform to response format
|
|
@@ -407,58 +407,58 @@ export function searchByLayer(params) {
|
|
|
407
407
|
const queryParams = [params.layer, statusValue];
|
|
408
408
|
if (includeTagsValue) {
|
|
409
409
|
// Use v_tagged_decisions view for full metadata
|
|
410
|
-
query = `
|
|
411
|
-
SELECT * FROM v_tagged_decisions
|
|
412
|
-
WHERE layer = ? AND status = ?
|
|
413
|
-
ORDER BY updated DESC
|
|
410
|
+
query = `
|
|
411
|
+
SELECT * FROM v_tagged_decisions
|
|
412
|
+
WHERE layer = ? AND status = ?
|
|
413
|
+
ORDER BY updated DESC
|
|
414
414
|
`;
|
|
415
415
|
}
|
|
416
416
|
else {
|
|
417
417
|
// Use base t_decisions table with minimal joins
|
|
418
|
-
query = `
|
|
419
|
-
SELECT
|
|
420
|
-
ck.key,
|
|
421
|
-
d.value,
|
|
422
|
-
d.version,
|
|
423
|
-
CASE d.status
|
|
424
|
-
WHEN 1 THEN 'active'
|
|
425
|
-
WHEN 2 THEN 'deprecated'
|
|
426
|
-
WHEN 3 THEN 'draft'
|
|
427
|
-
END as status,
|
|
428
|
-
l.name as layer,
|
|
429
|
-
NULL as tags,
|
|
430
|
-
NULL as scopes,
|
|
431
|
-
a.name as decided_by,
|
|
432
|
-
datetime(d.ts, 'unixepoch') as updated
|
|
433
|
-
FROM t_decisions d
|
|
434
|
-
INNER JOIN m_context_keys ck ON d.key_id = ck.id
|
|
435
|
-
LEFT JOIN m_layers l ON d.layer_id = l.id
|
|
436
|
-
LEFT JOIN m_agents a ON d.agent_id = a.id
|
|
437
|
-
WHERE l.name = ? AND d.status = ?
|
|
438
|
-
|
|
439
|
-
UNION ALL
|
|
440
|
-
|
|
441
|
-
SELECT
|
|
442
|
-
ck.key,
|
|
443
|
-
CAST(dn.value AS TEXT) as value,
|
|
444
|
-
dn.version,
|
|
445
|
-
CASE dn.status
|
|
446
|
-
WHEN 1 THEN 'active'
|
|
447
|
-
WHEN 2 THEN 'deprecated'
|
|
448
|
-
WHEN 3 THEN 'draft'
|
|
449
|
-
END as status,
|
|
450
|
-
l.name as layer,
|
|
451
|
-
NULL as tags,
|
|
452
|
-
NULL as scopes,
|
|
453
|
-
a.name as decided_by,
|
|
454
|
-
datetime(dn.ts, 'unixepoch') as updated
|
|
455
|
-
FROM t_decisions_numeric dn
|
|
456
|
-
INNER JOIN m_context_keys ck ON dn.key_id = ck.id
|
|
457
|
-
LEFT JOIN m_layers l ON dn.layer_id = l.id
|
|
458
|
-
LEFT JOIN m_agents a ON dn.agent_id = a.id
|
|
459
|
-
WHERE l.name = ? AND dn.status = ?
|
|
460
|
-
|
|
461
|
-
ORDER BY updated DESC
|
|
418
|
+
query = `
|
|
419
|
+
SELECT
|
|
420
|
+
ck.key,
|
|
421
|
+
d.value,
|
|
422
|
+
d.version,
|
|
423
|
+
CASE d.status
|
|
424
|
+
WHEN 1 THEN 'active'
|
|
425
|
+
WHEN 2 THEN 'deprecated'
|
|
426
|
+
WHEN 3 THEN 'draft'
|
|
427
|
+
END as status,
|
|
428
|
+
l.name as layer,
|
|
429
|
+
NULL as tags,
|
|
430
|
+
NULL as scopes,
|
|
431
|
+
a.name as decided_by,
|
|
432
|
+
datetime(d.ts, 'unixepoch') as updated
|
|
433
|
+
FROM t_decisions d
|
|
434
|
+
INNER JOIN m_context_keys ck ON d.key_id = ck.id
|
|
435
|
+
LEFT JOIN m_layers l ON d.layer_id = l.id
|
|
436
|
+
LEFT JOIN m_agents a ON d.agent_id = a.id
|
|
437
|
+
WHERE l.name = ? AND d.status = ?
|
|
438
|
+
|
|
439
|
+
UNION ALL
|
|
440
|
+
|
|
441
|
+
SELECT
|
|
442
|
+
ck.key,
|
|
443
|
+
CAST(dn.value AS TEXT) as value,
|
|
444
|
+
dn.version,
|
|
445
|
+
CASE dn.status
|
|
446
|
+
WHEN 1 THEN 'active'
|
|
447
|
+
WHEN 2 THEN 'deprecated'
|
|
448
|
+
WHEN 3 THEN 'draft'
|
|
449
|
+
END as status,
|
|
450
|
+
l.name as layer,
|
|
451
|
+
NULL as tags,
|
|
452
|
+
NULL as scopes,
|
|
453
|
+
a.name as decided_by,
|
|
454
|
+
datetime(dn.ts, 'unixepoch') as updated
|
|
455
|
+
FROM t_decisions_numeric dn
|
|
456
|
+
INNER JOIN m_context_keys ck ON dn.key_id = ck.id
|
|
457
|
+
LEFT JOIN m_layers l ON dn.layer_id = l.id
|
|
458
|
+
LEFT JOIN m_agents a ON dn.agent_id = a.id
|
|
459
|
+
WHERE l.name = ? AND dn.status = ?
|
|
460
|
+
|
|
461
|
+
ORDER BY updated DESC
|
|
462
462
|
`;
|
|
463
463
|
// Add params for the numeric table part of UNION
|
|
464
464
|
queryParams.push(params.layer, statusValue);
|
|
@@ -815,12 +815,12 @@ export function hasUpdates(params) {
|
|
|
815
815
|
}
|
|
816
816
|
const sinceTs = Math.floor(sinceDate.getTime() / 1000);
|
|
817
817
|
// Count decisions updated since timestamp (both string and numeric tables)
|
|
818
|
-
const decisionCountStmt = db.prepare(`
|
|
819
|
-
SELECT COUNT(*) as count FROM (
|
|
820
|
-
SELECT ts FROM t_decisions WHERE ts > ?
|
|
821
|
-
UNION ALL
|
|
822
|
-
SELECT ts FROM t_decisions_numeric WHERE ts > ?
|
|
823
|
-
)
|
|
818
|
+
const decisionCountStmt = db.prepare(`
|
|
819
|
+
SELECT COUNT(*) as count FROM (
|
|
820
|
+
SELECT ts FROM t_decisions WHERE ts > ?
|
|
821
|
+
UNION ALL
|
|
822
|
+
SELECT ts FROM t_decisions_numeric WHERE ts > ?
|
|
823
|
+
)
|
|
824
824
|
`);
|
|
825
825
|
const decisionResult = decisionCountStmt.get(sinceTs, sinceTs);
|
|
826
826
|
const decisionsCount = decisionResult.count;
|
|
@@ -830,16 +830,16 @@ export function hasUpdates(params) {
|
|
|
830
830
|
let messagesCount = 0;
|
|
831
831
|
if (agentResult) {
|
|
832
832
|
const agentId = agentResult.id;
|
|
833
|
-
const messageCountStmt = db.prepare(`
|
|
834
|
-
SELECT COUNT(*) as count FROM t_agent_messages
|
|
835
|
-
WHERE ts > ? AND (to_agent_id = ? OR to_agent_id IS NULL)
|
|
833
|
+
const messageCountStmt = db.prepare(`
|
|
834
|
+
SELECT COUNT(*) as count FROM t_agent_messages
|
|
835
|
+
WHERE ts > ? AND (to_agent_id = ? OR to_agent_id IS NULL)
|
|
836
836
|
`);
|
|
837
837
|
const messageResult = messageCountStmt.get(sinceTs, agentId);
|
|
838
838
|
messagesCount = messageResult.count;
|
|
839
839
|
}
|
|
840
840
|
// Count file changes since timestamp
|
|
841
|
-
const fileCountStmt = db.prepare(`
|
|
842
|
-
SELECT COUNT(*) as count FROM t_file_changes WHERE ts > ?
|
|
841
|
+
const fileCountStmt = db.prepare(`
|
|
842
|
+
SELECT COUNT(*) as count FROM t_file_changes WHERE ts > ?
|
|
843
843
|
`);
|
|
844
844
|
const fileResult = fileCountStmt.get(sinceTs);
|
|
845
845
|
const filesCount = fileResult.count;
|
|
@@ -974,9 +974,9 @@ export function createTemplate(params) {
|
|
|
974
974
|
const defaultsJson = JSON.stringify(params.defaults);
|
|
975
975
|
const requiredFieldsJson = params.required_fields ? JSON.stringify(params.required_fields) : null;
|
|
976
976
|
// Insert template
|
|
977
|
-
const stmt = db.prepare(`
|
|
978
|
-
INSERT INTO t_decision_templates (name, defaults, required_fields, created_by)
|
|
979
|
-
VALUES (?, ?, ?, ?)
|
|
977
|
+
const stmt = db.prepare(`
|
|
978
|
+
INSERT INTO t_decision_templates (name, defaults, required_fields, created_by)
|
|
979
|
+
VALUES (?, ?, ?, ?)
|
|
980
980
|
`);
|
|
981
981
|
const info = stmt.run(params.name, defaultsJson, requiredFieldsJson, createdById);
|
|
982
982
|
return {
|
|
@@ -1002,17 +1002,17 @@ export function createTemplate(params) {
|
|
|
1002
1002
|
export function listTemplates(params = {}) {
|
|
1003
1003
|
const db = getDatabase();
|
|
1004
1004
|
try {
|
|
1005
|
-
const stmt = db.prepare(`
|
|
1006
|
-
SELECT
|
|
1007
|
-
t.id,
|
|
1008
|
-
t.name,
|
|
1009
|
-
t.defaults,
|
|
1010
|
-
t.required_fields,
|
|
1011
|
-
a.name as created_by,
|
|
1012
|
-
datetime(t.ts, 'unixepoch') as created_at
|
|
1013
|
-
FROM t_decision_templates t
|
|
1014
|
-
LEFT JOIN m_agents a ON t.created_by = a.id
|
|
1015
|
-
ORDER BY t.name ASC
|
|
1005
|
+
const stmt = db.prepare(`
|
|
1006
|
+
SELECT
|
|
1007
|
+
t.id,
|
|
1008
|
+
t.name,
|
|
1009
|
+
t.defaults,
|
|
1010
|
+
t.required_fields,
|
|
1011
|
+
a.name as created_by,
|
|
1012
|
+
datetime(t.ts, 'unixepoch') as created_at
|
|
1013
|
+
FROM t_decision_templates t
|
|
1014
|
+
LEFT JOIN m_agents a ON t.created_by = a.id
|
|
1015
|
+
ORDER BY t.name ASC
|
|
1016
1016
|
`);
|
|
1017
1017
|
const rows = stmt.all();
|
|
1018
1018
|
// Parse JSON fields
|
|
@@ -1176,4 +1176,233 @@ export function listDecisionContextsAction(params) {
|
|
|
1176
1176
|
throw new Error(`Failed to list decision contexts: ${message}`);
|
|
1177
1177
|
}
|
|
1178
1178
|
}
|
|
1179
|
+
/**
|
|
1180
|
+
* Help action for decision tool
|
|
1181
|
+
*/
|
|
1182
|
+
export function decisionHelp() {
|
|
1183
|
+
return {
|
|
1184
|
+
tool: 'decision',
|
|
1185
|
+
description: 'Manage decisions with metadata (tags, layers, versions, scopes)',
|
|
1186
|
+
note: '💡 TIP: Use action: "example" to see comprehensive usage scenarios and real-world examples for all decision actions.',
|
|
1187
|
+
purpose: {
|
|
1188
|
+
title: '⚠️ CRITICAL: Store WHY and REASON, Not WHAT',
|
|
1189
|
+
principle: 'Decisions table is for ARCHITECTURAL CONTEXT and REASONING, NOT implementation logs or task completion status',
|
|
1190
|
+
what_to_store: {
|
|
1191
|
+
correct: [
|
|
1192
|
+
'WHY a design choice was made (e.g., "Chose JWT over sessions because stateless auth scales better for our microservice architecture")',
|
|
1193
|
+
'REASONING behind architecture decisions (e.g., "Moved oscillator_type to MonophonicSynthConfig to separate synthesis methods - FM operators use different config")',
|
|
1194
|
+
'PROBLEM ANALYSIS and solution rationale (e.g., "Nested transaction bug: setDecision wraps in transaction, batch also wraps → solution: extract internal helper without transaction wrapper")',
|
|
1195
|
+
'DESIGN TRADE-OFFS and alternatives considered (e.g., "Query builder limited to simple filters, kept domain-specific logic inline for maintainability")',
|
|
1196
|
+
'CONSTRAINTS and requirements reasoning (e.g., "API response must be <100ms because mobile clients timeout at 200ms")',
|
|
1197
|
+
'BREAKING CHANGES with migration rationale (e.g., "Removed /v1/users endpoint - clients must use /v2/users with pagination for scalability")'
|
|
1198
|
+
],
|
|
1199
|
+
incorrect: [
|
|
1200
|
+
'❌ Task completion logs (e.g., "Task 5 completed", "Refactoring done", "Tests passing") → Use tasks tool instead',
|
|
1201
|
+
'❌ Implementation status (e.g., "Added validators.ts", "Fixed bug in batch_create", "Updated README") → These are WHAT, not WHY',
|
|
1202
|
+
'❌ Test results (e.g., "All tests passing", "Integration tests complete", "v3.0.2 testing verified") → Temporary status, not architectural context',
|
|
1203
|
+
'❌ Git commit summaries (e.g., "Released v3.0.2", "Created git commit 2bf55a0") → Belongs in git history',
|
|
1204
|
+
'❌ Documentation updates (e.g., "README reorganized", "Help actions enhanced") → Implementation logs, not decisions',
|
|
1205
|
+
'❌ Build status (e.g., "Build succeeded", "TypeScript compiled with zero errors") → Temporary status'
|
|
1206
|
+
]
|
|
1207
|
+
},
|
|
1208
|
+
analogy: {
|
|
1209
|
+
git_history: 'WHAT changed (files, lines, commits)',
|
|
1210
|
+
code_comments: 'HOW it works (implementation details, algorithms)',
|
|
1211
|
+
sqlew_decisions: 'WHY it was changed (reasoning, trade-offs, context)',
|
|
1212
|
+
sqlew_tasks: 'WHAT needs to be done (work items, status, completion)'
|
|
1213
|
+
},
|
|
1214
|
+
examples: [
|
|
1215
|
+
{
|
|
1216
|
+
key: 'api/auth/jwt-choice',
|
|
1217
|
+
value: 'Chose JWT over session-based auth because: (1) Stateless design scales horizontally, (2) Mobile clients can cache tokens, (3) Microservice architecture requires distributed auth. Trade-off: Revocation requires token blacklist, but acceptable for 15-min token lifetime.',
|
|
1218
|
+
explanation: 'Explains WHY JWT was chosen, considers trade-offs, provides architectural context'
|
|
1219
|
+
},
|
|
1220
|
+
{
|
|
1221
|
+
key: 'database/postgresql-choice',
|
|
1222
|
+
value: 'Selected PostgreSQL over MongoDB because: (1) Complex relational queries required for reporting, (2) ACID compliance critical for financial data, (3) Team has strong SQL expertise. Trade-off: Less flexible schema, but data integrity more important than schema flexibility for our use case.',
|
|
1223
|
+
explanation: 'Documents database choice with reasoning, alternatives considered, and trade-offs'
|
|
1224
|
+
},
|
|
1225
|
+
{
|
|
1226
|
+
key: 'security/encryption-at-rest',
|
|
1227
|
+
value: 'Implementing AES-256 encryption for all PII in database because: (1) GDPR compliance requires encryption at rest, (2) Recent security audit identified unencrypted sensitive data, (3) Performance impact <5ms per query acceptable. Alternative considered: Database-level encryption rejected due to backup/restore complexity.',
|
|
1228
|
+
explanation: 'Explains security decision with compliance reasoning and performance considerations'
|
|
1229
|
+
}
|
|
1230
|
+
],
|
|
1231
|
+
cleanup_rule: 'Delete decisions that start with "COMPLETED:", contain task status, test results, or implementation logs. Keep only architectural reasoning and design rationale.'
|
|
1232
|
+
},
|
|
1233
|
+
actions: {
|
|
1234
|
+
set: 'Set/update a decision. Params: key (required), value (required), agent, layer, version, status, tags, scopes',
|
|
1235
|
+
get: 'Get specific decision by key. Params: key (required), include_context (optional, boolean, default: false). When include_context=true, returns decision with attached context (rationale, alternatives, tradeoffs). Backward compatible - omitting flag returns standard decision format.',
|
|
1236
|
+
list: 'List/filter decisions. Params: status, layer, tags, scope, tag_match',
|
|
1237
|
+
search_tags: 'Search decisions by tags. Params: tags (required), match_mode, status, layer',
|
|
1238
|
+
search_layer: 'Search decisions by layer. Params: layer (required), status, include_tags',
|
|
1239
|
+
versions: 'Get version history for a decision. Params: key (required)',
|
|
1240
|
+
quick_set: 'Quick set with smart defaults (FR-002). Params: key (required), value (required), agent, layer, version, status, tags, scopes. Auto-infers layer from key prefix (api/*→presentation, db/*→data, service/*→business, config/*→infrastructure), tags from key hierarchy, scope from parent path. Defaults: status=active, version=1.0.0. All inferred fields can be overridden.',
|
|
1241
|
+
search_advanced: 'Advanced query with complex filtering (FR-004). Params: layers (OR), tags_all (AND), tags_any (OR), exclude_tags, scopes (wildcards), updated_after/before (ISO or relative like "7d"), decided_by, statuses, search_text, sort_by (updated/key/version), sort_order (asc/desc), limit (default:20, max:1000), offset (default:0). Returns decisions with total_count for pagination. All filters use parameterized queries (SQL injection protection).',
|
|
1242
|
+
set_batch: 'Batch set decisions (FR-005). Params: decisions (required, array of SetDecisionParams, max: 50), atomic (optional, boolean, default: true). Returns: {success, inserted, failed, results}. ATOMIC MODE BEHAVIOR (atomic: true): All decisions succeed or all fail as a single transaction. If ANY decision fails, entire batch is rolled back and error is thrown. Use for critical operations requiring consistency. NON-ATOMIC MODE (atomic: false): Each decision is processed independently. If some fail, others still succeed. Returns partial results with per-item success/error status. Use for best-effort batch operations or when individual failures are acceptable. RECOMMENDATION FOR AI AGENTS: Use atomic:false by default to avoid transaction failures from validation errors or malformed data. Only use atomic:true when all-or-nothing guarantee is required. 52% token reduction vs individual calls.',
|
|
1243
|
+
has_updates: 'Check for updates since timestamp (FR-003 Phase A - Lightweight Polling). Params: agent_name (required), since_timestamp (required, ISO 8601 format like "2025-10-14T08:00:00Z"). Returns: {has_updates: boolean, counts: {decisions: N, messages: N, files: N}}. Token cost: ~5-10 tokens per check. Uses COUNT queries on t_decisions, t_agent_messages, t_file_changes with timestamp filtering. Enables efficient polling without full data retrieval.',
|
|
1244
|
+
set_from_template: 'Set decision using template (FR-006). Params: template (required, template name), key (required), value (required), agent, layer (override), version, status (override), tags (override), scopes, plus any template-required fields. Applies template defaults (layer, status, tags) while allowing overrides. Validates required fields if specified by template. Returns: {success, key, key_id, version, template_used, applied_defaults, message}. Built-in templates: breaking_change, security_vulnerability, performance_optimization, deprecation, architecture_decision.',
|
|
1245
|
+
create_template: 'Create new decision template (FR-006). Params: name (required, unique), defaults (required, object with layer/status/tags/priority), required_fields (optional, array of field names), created_by (optional, agent name). Returns: {success, template_id, template_name, message}. Example defaults: {"layer":"business","status":"active","tags":["breaking"]}. Validates layer/status values.',
|
|
1246
|
+
list_templates: 'List all decision templates (FR-006). No params required. Returns: {templates: [{id, name, defaults, required_fields, created_by, created_at}], count}. Shows both built-in and custom templates.',
|
|
1247
|
+
hard_delete: 'Permanently delete a decision (hard delete). Params: key (required). WARNING: IRREVERSIBLE - removes all records including version history, tags, scopes. Use cases: manual cleanup after decision-to-task migration, remove test/debug decisions, purge sensitive data. Unlike soft delete (status=deprecated), this completely removes from database. Idempotent - safe to call even if already deleted. Returns: {success, key, message}.',
|
|
1248
|
+
add_decision_context: 'Add rich context to a decision (v3.2.2). Params: key (required), rationale (required), alternatives_considered (optional, JSON array), tradeoffs (optional, JSON object with pros/cons), decided_by (optional), related_task_id (optional), related_constraint_id (optional). Use to document WHY decisions were made, what alternatives were considered, and trade-offs. Multiple contexts can be attached to the same decision over time. Returns: {success, context_id, decision_key, message}.',
|
|
1249
|
+
list_decision_contexts: 'List decision contexts with filters (v3.2.2). Params: decision_key (optional), related_task_id (optional), related_constraint_id (optional), decided_by (optional), limit (default: 50), offset (default: 0). Returns: {success, contexts: [{id, decision_key, rationale, alternatives_considered, tradeoffs, decided_by, decision_date, related_task_id, related_constraint_id}], count}. JSON fields (alternatives, tradeoffs) are automatically parsed.'
|
|
1250
|
+
},
|
|
1251
|
+
examples: {
|
|
1252
|
+
set: '{ action: "set", key: "auth_method", value: "jwt", tags: ["security"] }',
|
|
1253
|
+
get: '{ action: "get", key: "auth_method" }',
|
|
1254
|
+
list: '{ action: "list", status: "active", layer: "infrastructure" }',
|
|
1255
|
+
search_tags: '{ action: "search_tags", tags: ["security", "api"] }',
|
|
1256
|
+
quick_set: '{ action: "quick_set", key: "api/instruments/oscillator-refactor", value: "Moved oscillator_type to MonophonicSynthConfig" }',
|
|
1257
|
+
search_advanced: '{ action: "search_advanced", layers: ["business", "data"], tags_all: ["breaking", "v0.3.3"], tags_any: ["api", "synthesis"], exclude_tags: ["deprecated"], scopes: ["api/instruments/*"], updated_after: "2025-10-01", statuses: ["active", "draft"], search_text: "oscillator", sort_by: "updated", sort_order: "desc", limit: 20, offset: 0 }',
|
|
1258
|
+
set_batch: '{ action: "set_batch", decisions: [{"key": "feat-1", "value": "...", "layer": "business"}, {"key": "feat-2", "value": "...", "layer": "data"}], atomic: true }',
|
|
1259
|
+
has_updates: '{ action: "has_updates", agent_name: "my-agent", since_timestamp: "2025-10-14T08:00:00Z" }',
|
|
1260
|
+
set_from_template: '{ action: "set_from_template", template: "breaking_change", key: "oscillator-type-moved", value: "oscillator_type moved to MonophonicSynthConfig" }',
|
|
1261
|
+
create_template: '{ action: "create_template", name: "bug_fix", defaults: {"layer":"business","tags":["bug","fix"],"status":"active"}, created_by: "my-agent" }',
|
|
1262
|
+
list_templates: '{ action: "list_templates" }',
|
|
1263
|
+
hard_delete: '{ action: "hard_delete", key: "task_old_authentication_refactor" }'
|
|
1264
|
+
},
|
|
1265
|
+
documentation: {
|
|
1266
|
+
tool_selection: 'docs/TOOL_SELECTION.md - Decision tree, tool comparison, when to use each tool (236 lines, ~12k tokens)',
|
|
1267
|
+
tool_reference: 'docs/TOOL_REFERENCE.md - Parameter requirements, batch operations, templates (471 lines, ~24k tokens)',
|
|
1268
|
+
workflows: 'docs/WORKFLOWS.md - Multi-step workflow examples, multi-agent coordination (602 lines, ~30k tokens)',
|
|
1269
|
+
best_practices: 'docs/BEST_PRACTICES.md - Common errors, best practices, troubleshooting (345 lines, ~17k tokens)',
|
|
1270
|
+
shared_concepts: 'docs/SHARED_CONCEPTS.md - Layer definitions, enum values (status/layer/priority), atomic mode (339 lines, ~17k tokens)'
|
|
1271
|
+
}
|
|
1272
|
+
};
|
|
1273
|
+
}
|
|
1274
|
+
/**
|
|
1275
|
+
* Example action for decision tool
|
|
1276
|
+
*/
|
|
1277
|
+
export function decisionExample() {
|
|
1278
|
+
return {
|
|
1279
|
+
tool: 'decision',
|
|
1280
|
+
description: 'Comprehensive decision tool examples without needing WebFetch access',
|
|
1281
|
+
scenarios: {
|
|
1282
|
+
basic_usage: {
|
|
1283
|
+
title: 'Basic Decision Management',
|
|
1284
|
+
examples: [
|
|
1285
|
+
{
|
|
1286
|
+
scenario: 'Record API design decision',
|
|
1287
|
+
request: '{ action: "set", key: "api_auth_method", value: "JWT with refresh tokens", layer: "business", tags: ["api", "security", "authentication"] }',
|
|
1288
|
+
explanation: 'Documents the choice of authentication method for the API'
|
|
1289
|
+
},
|
|
1290
|
+
{
|
|
1291
|
+
scenario: 'Retrieve a decision',
|
|
1292
|
+
request: '{ action: "get", key: "api_auth_method" }',
|
|
1293
|
+
response_structure: '{ key, value, layer, status, version, tags, scopes, decided_by, updated_at }'
|
|
1294
|
+
},
|
|
1295
|
+
{
|
|
1296
|
+
scenario: 'List all active decisions',
|
|
1297
|
+
request: '{ action: "list", status: "active", limit: 20 }',
|
|
1298
|
+
explanation: 'Returns active decisions with metadata for browsing'
|
|
1299
|
+
}
|
|
1300
|
+
]
|
|
1301
|
+
},
|
|
1302
|
+
advanced_filtering: {
|
|
1303
|
+
title: 'Advanced Search and Filtering',
|
|
1304
|
+
examples: [
|
|
1305
|
+
{
|
|
1306
|
+
scenario: 'Find all security-related decisions in business layer',
|
|
1307
|
+
request: '{ action: "search_advanced", layers: ["business"], tags_any: ["security", "authentication"], status: ["active"], sort_by: "updated", sort_order: "desc" }',
|
|
1308
|
+
explanation: 'Combines layer filtering, tag matching, and sorting'
|
|
1309
|
+
},
|
|
1310
|
+
{
|
|
1311
|
+
scenario: 'Search within API scope with multiple tags',
|
|
1312
|
+
request: '{ action: "search_advanced", scopes: ["api/*"], tags_all: ["breaking", "v2.0"], updated_after: "2025-01-01" }',
|
|
1313
|
+
explanation: 'Uses scope wildcards and timestamp filtering for recent breaking changes'
|
|
1314
|
+
}
|
|
1315
|
+
]
|
|
1316
|
+
},
|
|
1317
|
+
versioning_workflow: {
|
|
1318
|
+
title: 'Version Management',
|
|
1319
|
+
steps: [
|
|
1320
|
+
{
|
|
1321
|
+
step: 1,
|
|
1322
|
+
action: 'Create initial decision',
|
|
1323
|
+
request: '{ action: "set", key: "database_choice", value: "PostgreSQL", layer: "data", version: "1.0.0", tags: ["database"] }'
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
step: 2,
|
|
1327
|
+
action: 'Update decision (creates new version)',
|
|
1328
|
+
request: '{ action: "set", key: "database_choice", value: "PostgreSQL with read replicas", layer: "data", version: "1.1.0", tags: ["database", "scaling"] }'
|
|
1329
|
+
},
|
|
1330
|
+
{
|
|
1331
|
+
step: 3,
|
|
1332
|
+
action: 'View version history',
|
|
1333
|
+
request: '{ action: "versions", key: "database_choice" }',
|
|
1334
|
+
result: 'Returns all versions with timestamps and changes'
|
|
1335
|
+
}
|
|
1336
|
+
]
|
|
1337
|
+
},
|
|
1338
|
+
batch_operations: {
|
|
1339
|
+
title: 'Batch Decision Management',
|
|
1340
|
+
examples: [
|
|
1341
|
+
{
|
|
1342
|
+
scenario: 'Record multiple related decisions atomically',
|
|
1343
|
+
request: '{ action: "set_batch", decisions: [{"key": "cache_layer", "value": "Redis", "layer": "infrastructure"}, {"key": "cache_ttl", "value": "3600", "layer": "infrastructure"}], atomic: true }',
|
|
1344
|
+
explanation: 'All decisions succeed or all fail together (atomic mode)'
|
|
1345
|
+
},
|
|
1346
|
+
{
|
|
1347
|
+
scenario: 'Best-effort batch insert',
|
|
1348
|
+
request: '{ action: "set_batch", decisions: [{...}, {...}, {...}], atomic: false }',
|
|
1349
|
+
explanation: 'Each decision processed independently - partial success allowed'
|
|
1350
|
+
}
|
|
1351
|
+
]
|
|
1352
|
+
},
|
|
1353
|
+
templates: {
|
|
1354
|
+
title: 'Using Decision Templates',
|
|
1355
|
+
examples: [
|
|
1356
|
+
{
|
|
1357
|
+
scenario: 'Use built-in breaking_change template',
|
|
1358
|
+
request: '{ action: "set_from_template", template: "breaking_change", key: "api_remove_legacy_endpoint", value: "Removed /v1/users endpoint - migrate to /v2/users" }',
|
|
1359
|
+
explanation: 'Automatically applies layer=business, tags=["breaking"], status=active'
|
|
1360
|
+
},
|
|
1361
|
+
{
|
|
1362
|
+
scenario: 'Create custom template',
|
|
1363
|
+
request: '{ action: "create_template", name: "feature_flag", defaults: {"layer": "presentation", "tags": ["feature-flag"], "status": "draft"}, created_by: "backend-team" }',
|
|
1364
|
+
explanation: 'Define reusable templates for common decision patterns'
|
|
1365
|
+
}
|
|
1366
|
+
]
|
|
1367
|
+
},
|
|
1368
|
+
quick_set_inference: {
|
|
1369
|
+
title: 'Quick Set with Smart Defaults',
|
|
1370
|
+
examples: [
|
|
1371
|
+
{
|
|
1372
|
+
scenario: 'Auto-infer layer from key prefix',
|
|
1373
|
+
request: '{ action: "quick_set", key: "api/instruments/oscillator-refactor", value: "Moved oscillator_type to MonophonicSynthConfig" }',
|
|
1374
|
+
inferred: 'layer=presentation (from api/*), tags=["instruments", "oscillator-refactor"], scope=api/instruments'
|
|
1375
|
+
},
|
|
1376
|
+
{
|
|
1377
|
+
scenario: 'Database decision with auto-inference',
|
|
1378
|
+
request: '{ action: "quick_set", key: "db/users/add-email-index", value: "Added index on email column" }',
|
|
1379
|
+
inferred: 'layer=data (from db/*), tags=["users", "add-email-index"]'
|
|
1380
|
+
}
|
|
1381
|
+
]
|
|
1382
|
+
}
|
|
1383
|
+
},
|
|
1384
|
+
best_practices: {
|
|
1385
|
+
key_naming: [
|
|
1386
|
+
'Use hierarchical keys: "api/users/authentication"',
|
|
1387
|
+
'Prefix with layer hint: api/* → presentation, db/* → data, service/* → business',
|
|
1388
|
+
'Use descriptive names that explain the decision context'
|
|
1389
|
+
],
|
|
1390
|
+
tagging: [
|
|
1391
|
+
'Tag with relevant categories: security, performance, breaking, etc.',
|
|
1392
|
+
'Include version tags for release-specific decisions',
|
|
1393
|
+
'Use consistent tag naming conventions across team'
|
|
1394
|
+
],
|
|
1395
|
+
versioning: [
|
|
1396
|
+
'Use semantic versioning: 1.0.0, 1.1.0, 2.0.0',
|
|
1397
|
+
'Increment major version for breaking changes',
|
|
1398
|
+
'Document rationale in decision value text'
|
|
1399
|
+
],
|
|
1400
|
+
cleanup: [
|
|
1401
|
+
'Mark deprecated decisions with status="deprecated"',
|
|
1402
|
+
'Use hard_delete only for sensitive data or migration cleanup',
|
|
1403
|
+
'Link related decisions using scopes'
|
|
1404
|
+
]
|
|
1405
|
+
}
|
|
1406
|
+
};
|
|
1407
|
+
}
|
|
1179
1408
|
//# sourceMappingURL=context.js.map
|