@massu/core 0.1.1 → 0.1.2
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/README.md +2 -2
- package/dist/hooks/cost-tracker.js +23 -35
- package/dist/hooks/post-edit-context.js +2 -2
- package/dist/hooks/post-tool-use.js +43 -58
- package/dist/hooks/pre-compact.js +23 -38
- package/dist/hooks/pre-delete-check.js +18 -31
- package/dist/hooks/quality-event.js +23 -35
- package/dist/hooks/session-end.js +62 -78
- package/dist/hooks/session-start.js +33 -42
- package/dist/hooks/user-prompt.js +23 -38
- package/package.json +8 -14
- package/src/adr-generator.ts +9 -2
- package/src/analytics.ts +9 -3
- package/src/audit-trail.ts +10 -3
- package/src/cloud-sync.ts +14 -18
- package/src/commands/init.ts +1 -5
- package/src/cost-tracker.ts +11 -6
- package/src/dependency-scorer.ts +9 -2
- package/src/docs-tools.ts +13 -10
- package/src/hooks/post-edit-context.ts +3 -3
- package/src/hooks/session-end.ts +3 -3
- package/src/hooks/session-start.ts +2 -2
- package/src/memory-db.ts +1351 -23
- package/src/memory-tools.ts +14 -15
- package/src/observability-tools.ts +13 -2
- package/src/prompt-analyzer.ts +9 -2
- package/src/regression-detector.ts +9 -3
- package/src/security-scorer.ts +9 -2
- package/src/sentinel-db.ts +43 -88
- package/src/sentinel-tools.ts +8 -11
- package/src/server.ts +1 -2
- package/src/team-knowledge.ts +9 -2
- package/src/tools.ts +771 -35
- package/src/validate-features-runner.ts +0 -1
- package/src/validation-engine.ts +9 -2
- package/dist/cli.js +0 -7890
- package/dist/server.js +0 -7008
- package/src/__tests__/adr-generator.test.ts +0 -260
- package/src/__tests__/analytics.test.ts +0 -282
- package/src/__tests__/audit-trail.test.ts +0 -382
- package/src/__tests__/backfill-sessions.test.ts +0 -690
- package/src/__tests__/cli.test.ts +0 -290
- package/src/__tests__/cloud-sync.test.ts +0 -261
- package/src/__tests__/config-sections.test.ts +0 -359
- package/src/__tests__/config.test.ts +0 -732
- package/src/__tests__/cost-tracker.test.ts +0 -348
- package/src/__tests__/db.test.ts +0 -177
- package/src/__tests__/dependency-scorer.test.ts +0 -325
- package/src/__tests__/docs-integration.test.ts +0 -178
- package/src/__tests__/docs-tools.test.ts +0 -199
- package/src/__tests__/domains.test.ts +0 -236
- package/src/__tests__/hooks.test.ts +0 -221
- package/src/__tests__/import-resolver.test.ts +0 -95
- package/src/__tests__/integration/path-traversal.test.ts +0 -134
- package/src/__tests__/integration/pricing-consistency.test.ts +0 -88
- package/src/__tests__/integration/tool-registration.test.ts +0 -146
- package/src/__tests__/memory-db.test.ts +0 -404
- package/src/__tests__/memory-enhancements.test.ts +0 -316
- package/src/__tests__/memory-tools.test.ts +0 -199
- package/src/__tests__/middleware-tree.test.ts +0 -177
- package/src/__tests__/observability-tools.test.ts +0 -595
- package/src/__tests__/observability.test.ts +0 -437
- package/src/__tests__/observation-extractor.test.ts +0 -167
- package/src/__tests__/page-deps.test.ts +0 -60
- package/src/__tests__/prompt-analyzer.test.ts +0 -298
- package/src/__tests__/regression-detector.test.ts +0 -295
- package/src/__tests__/rules.test.ts +0 -87
- package/src/__tests__/schema-mapper.test.ts +0 -29
- package/src/__tests__/security-scorer.test.ts +0 -238
- package/src/__tests__/security-utils.test.ts +0 -175
- package/src/__tests__/sentinel-db.test.ts +0 -491
- package/src/__tests__/sentinel-scanner.test.ts +0 -750
- package/src/__tests__/sentinel-tools.test.ts +0 -324
- package/src/__tests__/sentinel-types.test.ts +0 -750
- package/src/__tests__/server.test.ts +0 -452
- package/src/__tests__/session-archiver.test.ts +0 -524
- package/src/__tests__/session-state-generator.test.ts +0 -900
- package/src/__tests__/team-knowledge.test.ts +0 -327
- package/src/__tests__/tools.test.ts +0 -340
- package/src/__tests__/transcript-parser.test.ts +0 -195
- package/src/__tests__/trpc-index.test.ts +0 -25
- package/src/__tests__/validate-features-runner.test.ts +0 -517
- package/src/__tests__/validation-engine.test.ts +0 -300
- package/src/core-tools.ts +0 -685
- package/src/memory-queries.ts +0 -804
- package/src/memory-schema.ts +0 -546
- package/src/tool-helpers.ts +0 -41
package/src/memory-schema.ts
DELETED
|
@@ -1,546 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2026 Massu. All rights reserved.
|
|
2
|
-
// Licensed under BSL 1.1 - see LICENSE file for details.
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Memory database schema DDL.
|
|
6
|
-
* Extracted from memory-db.ts (P3-001 remediation) to keep
|
|
7
|
-
* memory-db.ts focused on connection factory + re-exports.
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import type Database from 'better-sqlite3';
|
|
11
|
-
|
|
12
|
-
export function initMemorySchema(db: Database.Database): void {
|
|
13
|
-
db.exec(`
|
|
14
|
-
-- Sessions table (linked to Claude Code session IDs)
|
|
15
|
-
CREATE TABLE IF NOT EXISTS sessions (
|
|
16
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
17
|
-
session_id TEXT UNIQUE NOT NULL,
|
|
18
|
-
project TEXT NOT NULL DEFAULT 'unknown',
|
|
19
|
-
git_branch TEXT,
|
|
20
|
-
started_at TEXT NOT NULL,
|
|
21
|
-
started_at_epoch INTEGER NOT NULL,
|
|
22
|
-
ended_at TEXT,
|
|
23
|
-
ended_at_epoch INTEGER,
|
|
24
|
-
status TEXT CHECK(status IN ('active', 'completed', 'abandoned')) NOT NULL DEFAULT 'active',
|
|
25
|
-
plan_file TEXT,
|
|
26
|
-
plan_phase TEXT,
|
|
27
|
-
task_id TEXT
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_session_id ON sessions(session_id);
|
|
31
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_started ON sessions(started_at_epoch DESC);
|
|
32
|
-
CREATE INDEX IF NOT EXISTS idx_sessions_task_id ON sessions(task_id);
|
|
33
|
-
|
|
34
|
-
-- Observations table (structured knowledge from tool usage)
|
|
35
|
-
CREATE TABLE IF NOT EXISTS observations (
|
|
36
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
37
|
-
session_id TEXT NOT NULL,
|
|
38
|
-
type TEXT NOT NULL CHECK(type IN (
|
|
39
|
-
'decision', 'bugfix', 'feature', 'refactor', 'discovery',
|
|
40
|
-
'cr_violation', 'vr_check', 'pattern_compliance', 'failed_attempt',
|
|
41
|
-
'file_change', 'incident_near_miss'
|
|
42
|
-
)),
|
|
43
|
-
title TEXT NOT NULL,
|
|
44
|
-
detail TEXT,
|
|
45
|
-
files_involved TEXT DEFAULT '[]',
|
|
46
|
-
plan_item TEXT,
|
|
47
|
-
cr_rule TEXT,
|
|
48
|
-
vr_type TEXT,
|
|
49
|
-
evidence TEXT,
|
|
50
|
-
importance INTEGER NOT NULL DEFAULT 3 CHECK(importance BETWEEN 1 AND 5),
|
|
51
|
-
recurrence_count INTEGER NOT NULL DEFAULT 1,
|
|
52
|
-
original_tokens INTEGER DEFAULT 0,
|
|
53
|
-
created_at TEXT NOT NULL,
|
|
54
|
-
created_at_epoch INTEGER NOT NULL,
|
|
55
|
-
FOREIGN KEY(session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
56
|
-
);
|
|
57
|
-
|
|
58
|
-
CREATE INDEX IF NOT EXISTS idx_observations_session ON observations(session_id);
|
|
59
|
-
CREATE INDEX IF NOT EXISTS idx_observations_type ON observations(type);
|
|
60
|
-
CREATE INDEX IF NOT EXISTS idx_observations_created ON observations(created_at_epoch DESC);
|
|
61
|
-
CREATE INDEX IF NOT EXISTS idx_observations_plan_item ON observations(plan_item);
|
|
62
|
-
CREATE INDEX IF NOT EXISTS idx_observations_cr_rule ON observations(cr_rule);
|
|
63
|
-
CREATE INDEX IF NOT EXISTS idx_observations_importance ON observations(importance DESC);
|
|
64
|
-
`);
|
|
65
|
-
|
|
66
|
-
// FTS5 tables - create separately to handle "already exists" gracefully
|
|
67
|
-
try {
|
|
68
|
-
db.exec(`
|
|
69
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS observations_fts USING fts5(
|
|
70
|
-
title, detail, evidence,
|
|
71
|
-
content='observations',
|
|
72
|
-
content_rowid='id'
|
|
73
|
-
);
|
|
74
|
-
`);
|
|
75
|
-
} catch (e) {
|
|
76
|
-
process.stderr.write(`FTS5 setup warning: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// FTS5 sync triggers
|
|
80
|
-
db.exec(`
|
|
81
|
-
CREATE TRIGGER IF NOT EXISTS observations_ai AFTER INSERT ON observations BEGIN
|
|
82
|
-
INSERT INTO observations_fts(rowid, title, detail, evidence)
|
|
83
|
-
VALUES (new.id, new.title, new.detail, new.evidence);
|
|
84
|
-
END;
|
|
85
|
-
|
|
86
|
-
CREATE TRIGGER IF NOT EXISTS observations_ad AFTER DELETE ON observations BEGIN
|
|
87
|
-
INSERT INTO observations_fts(observations_fts, rowid, title, detail, evidence)
|
|
88
|
-
VALUES ('delete', old.id, old.title, old.detail, old.evidence);
|
|
89
|
-
END;
|
|
90
|
-
|
|
91
|
-
CREATE TRIGGER IF NOT EXISTS observations_au AFTER UPDATE ON observations BEGIN
|
|
92
|
-
INSERT INTO observations_fts(observations_fts, rowid, title, detail, evidence)
|
|
93
|
-
VALUES ('delete', old.id, old.title, old.detail, old.evidence);
|
|
94
|
-
INSERT INTO observations_fts(rowid, title, detail, evidence)
|
|
95
|
-
VALUES (new.id, new.title, new.detail, new.evidence);
|
|
96
|
-
END;
|
|
97
|
-
`);
|
|
98
|
-
|
|
99
|
-
// Session summaries
|
|
100
|
-
db.exec(`
|
|
101
|
-
CREATE TABLE IF NOT EXISTS session_summaries (
|
|
102
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
103
|
-
session_id TEXT NOT NULL,
|
|
104
|
-
request TEXT,
|
|
105
|
-
investigated TEXT,
|
|
106
|
-
decisions TEXT,
|
|
107
|
-
completed TEXT,
|
|
108
|
-
failed_attempts TEXT,
|
|
109
|
-
next_steps TEXT,
|
|
110
|
-
files_created TEXT DEFAULT '[]',
|
|
111
|
-
files_modified TEXT DEFAULT '[]',
|
|
112
|
-
verification_results TEXT DEFAULT '{}',
|
|
113
|
-
plan_progress TEXT DEFAULT '{}',
|
|
114
|
-
created_at TEXT NOT NULL,
|
|
115
|
-
created_at_epoch INTEGER NOT NULL,
|
|
116
|
-
FOREIGN KEY(session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
CREATE INDEX IF NOT EXISTS idx_summaries_session ON session_summaries(session_id);
|
|
120
|
-
`);
|
|
121
|
-
|
|
122
|
-
// User prompts
|
|
123
|
-
db.exec(`
|
|
124
|
-
CREATE TABLE IF NOT EXISTS user_prompts (
|
|
125
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
126
|
-
session_id TEXT NOT NULL,
|
|
127
|
-
prompt_text TEXT NOT NULL,
|
|
128
|
-
prompt_number INTEGER NOT NULL DEFAULT 1,
|
|
129
|
-
created_at TEXT NOT NULL,
|
|
130
|
-
created_at_epoch INTEGER NOT NULL,
|
|
131
|
-
FOREIGN KEY(session_id) REFERENCES sessions(session_id) ON DELETE CASCADE
|
|
132
|
-
);
|
|
133
|
-
`);
|
|
134
|
-
|
|
135
|
-
try {
|
|
136
|
-
db.exec(`
|
|
137
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS user_prompts_fts USING fts5(
|
|
138
|
-
prompt_text,
|
|
139
|
-
content='user_prompts',
|
|
140
|
-
content_rowid='id'
|
|
141
|
-
);
|
|
142
|
-
`);
|
|
143
|
-
} catch (e) {
|
|
144
|
-
process.stderr.write(`FTS5 setup warning: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
db.exec(`
|
|
148
|
-
CREATE TRIGGER IF NOT EXISTS prompts_ai AFTER INSERT ON user_prompts BEGIN
|
|
149
|
-
INSERT INTO user_prompts_fts(rowid, prompt_text) VALUES (new.id, new.prompt_text);
|
|
150
|
-
END;
|
|
151
|
-
|
|
152
|
-
CREATE TRIGGER IF NOT EXISTS prompts_ad AFTER DELETE ON user_prompts BEGIN
|
|
153
|
-
INSERT INTO user_prompts_fts(user_prompts_fts, rowid, prompt_text)
|
|
154
|
-
VALUES ('delete', old.id, old.prompt_text);
|
|
155
|
-
END;
|
|
156
|
-
`);
|
|
157
|
-
|
|
158
|
-
// Metadata
|
|
159
|
-
db.exec(`
|
|
160
|
-
CREATE TABLE IF NOT EXISTS memory_meta (
|
|
161
|
-
key TEXT PRIMARY KEY,
|
|
162
|
-
value TEXT NOT NULL
|
|
163
|
-
);
|
|
164
|
-
`);
|
|
165
|
-
|
|
166
|
-
// ============================================================
|
|
167
|
-
// Observability tables (P1-001, P1-002)
|
|
168
|
-
// ============================================================
|
|
169
|
-
|
|
170
|
-
// P1-001: Conversation turns (full session replay)
|
|
171
|
-
db.exec(`
|
|
172
|
-
CREATE TABLE IF NOT EXISTS conversation_turns (
|
|
173
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
174
|
-
session_id TEXT NOT NULL,
|
|
175
|
-
turn_number INTEGER NOT NULL,
|
|
176
|
-
user_prompt TEXT NOT NULL,
|
|
177
|
-
assistant_response TEXT,
|
|
178
|
-
tool_calls_json TEXT,
|
|
179
|
-
tool_call_count INTEGER DEFAULT 0,
|
|
180
|
-
model_used TEXT,
|
|
181
|
-
duration_ms INTEGER,
|
|
182
|
-
prompt_tokens INTEGER,
|
|
183
|
-
response_tokens INTEGER,
|
|
184
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
185
|
-
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
186
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
CREATE INDEX IF NOT EXISTS idx_ct_session ON conversation_turns(session_id);
|
|
190
|
-
CREATE INDEX IF NOT EXISTS idx_ct_created ON conversation_turns(created_at DESC);
|
|
191
|
-
CREATE INDEX IF NOT EXISTS idx_ct_turn ON conversation_turns(session_id, turn_number);
|
|
192
|
-
`);
|
|
193
|
-
|
|
194
|
-
// P1-002: Tool call details (analytics)
|
|
195
|
-
db.exec(`
|
|
196
|
-
CREATE TABLE IF NOT EXISTS tool_call_details (
|
|
197
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
198
|
-
session_id TEXT NOT NULL,
|
|
199
|
-
turn_number INTEGER NOT NULL,
|
|
200
|
-
tool_name TEXT NOT NULL,
|
|
201
|
-
tool_input_summary TEXT,
|
|
202
|
-
tool_input_size INTEGER,
|
|
203
|
-
tool_output_size INTEGER,
|
|
204
|
-
tool_success INTEGER DEFAULT 1,
|
|
205
|
-
duration_ms INTEGER,
|
|
206
|
-
files_involved TEXT,
|
|
207
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
208
|
-
created_at_epoch INTEGER DEFAULT (unixepoch()),
|
|
209
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
210
|
-
);
|
|
211
|
-
|
|
212
|
-
CREATE INDEX IF NOT EXISTS idx_tcd_session ON tool_call_details(session_id);
|
|
213
|
-
CREATE INDEX IF NOT EXISTS idx_tcd_tool ON tool_call_details(tool_name);
|
|
214
|
-
CREATE INDEX IF NOT EXISTS idx_tcd_created ON tool_call_details(created_at DESC);
|
|
215
|
-
`);
|
|
216
|
-
|
|
217
|
-
// P1-003: FTS5 index for conversation turns
|
|
218
|
-
try {
|
|
219
|
-
db.exec(`
|
|
220
|
-
CREATE VIRTUAL TABLE IF NOT EXISTS conversation_turns_fts USING fts5(
|
|
221
|
-
user_prompt,
|
|
222
|
-
assistant_response,
|
|
223
|
-
content=conversation_turns,
|
|
224
|
-
content_rowid=id
|
|
225
|
-
);
|
|
226
|
-
`);
|
|
227
|
-
} catch (e) {
|
|
228
|
-
process.stderr.write(`FTS5 setup warning: ${e instanceof Error ? e.message : String(e)}\n`);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// FTS5 sync triggers for conversation_turns
|
|
232
|
-
db.exec(`
|
|
233
|
-
CREATE TRIGGER IF NOT EXISTS ct_fts_insert AFTER INSERT ON conversation_turns BEGIN
|
|
234
|
-
INSERT INTO conversation_turns_fts(rowid, user_prompt, assistant_response)
|
|
235
|
-
VALUES (new.id, new.user_prompt, new.assistant_response);
|
|
236
|
-
END;
|
|
237
|
-
|
|
238
|
-
CREATE TRIGGER IF NOT EXISTS ct_fts_delete AFTER DELETE ON conversation_turns BEGIN
|
|
239
|
-
INSERT INTO conversation_turns_fts(conversation_turns_fts, rowid, user_prompt, assistant_response)
|
|
240
|
-
VALUES ('delete', old.id, old.user_prompt, old.assistant_response);
|
|
241
|
-
END;
|
|
242
|
-
|
|
243
|
-
CREATE TRIGGER IF NOT EXISTS ct_fts_update AFTER UPDATE ON conversation_turns BEGIN
|
|
244
|
-
INSERT INTO conversation_turns_fts(conversation_turns_fts, rowid, user_prompt, assistant_response)
|
|
245
|
-
VALUES ('delete', old.id, old.user_prompt, old.assistant_response);
|
|
246
|
-
INSERT INTO conversation_turns_fts(rowid, user_prompt, assistant_response)
|
|
247
|
-
VALUES (new.id, new.user_prompt, new.assistant_response);
|
|
248
|
-
END;
|
|
249
|
-
`);
|
|
250
|
-
|
|
251
|
-
// ============================================================
|
|
252
|
-
// PLAN-02 Enhancement Tables (Analytics, Governance, Security, Team, Regression)
|
|
253
|
-
// ============================================================
|
|
254
|
-
|
|
255
|
-
// P1-001: Quality scores per session
|
|
256
|
-
db.exec(`
|
|
257
|
-
CREATE TABLE IF NOT EXISTS session_quality_scores (
|
|
258
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
259
|
-
session_id TEXT NOT NULL UNIQUE,
|
|
260
|
-
project TEXT NOT NULL DEFAULT 'unknown',
|
|
261
|
-
score INTEGER NOT NULL DEFAULT 100,
|
|
262
|
-
security_score INTEGER NOT NULL DEFAULT 100,
|
|
263
|
-
architecture_score INTEGER NOT NULL DEFAULT 100,
|
|
264
|
-
coupling_score INTEGER NOT NULL DEFAULT 100,
|
|
265
|
-
test_score INTEGER NOT NULL DEFAULT 100,
|
|
266
|
-
rule_compliance_score INTEGER NOT NULL DEFAULT 100,
|
|
267
|
-
observations_total INTEGER NOT NULL DEFAULT 0,
|
|
268
|
-
bugs_found INTEGER NOT NULL DEFAULT 0,
|
|
269
|
-
bugs_fixed INTEGER NOT NULL DEFAULT 0,
|
|
270
|
-
vr_checks_passed INTEGER NOT NULL DEFAULT 0,
|
|
271
|
-
vr_checks_failed INTEGER NOT NULL DEFAULT 0,
|
|
272
|
-
incidents_triggered INTEGER NOT NULL DEFAULT 0,
|
|
273
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
274
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
275
|
-
);
|
|
276
|
-
CREATE INDEX IF NOT EXISTS idx_sqs_session ON session_quality_scores(session_id);
|
|
277
|
-
CREATE INDEX IF NOT EXISTS idx_sqs_project ON session_quality_scores(project);
|
|
278
|
-
`);
|
|
279
|
-
|
|
280
|
-
// P1-002: Cost tracking per session
|
|
281
|
-
db.exec(`
|
|
282
|
-
CREATE TABLE IF NOT EXISTS session_costs (
|
|
283
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
284
|
-
session_id TEXT NOT NULL UNIQUE,
|
|
285
|
-
project TEXT NOT NULL DEFAULT 'unknown',
|
|
286
|
-
input_tokens INTEGER NOT NULL DEFAULT 0,
|
|
287
|
-
output_tokens INTEGER NOT NULL DEFAULT 0,
|
|
288
|
-
cache_read_tokens INTEGER NOT NULL DEFAULT 0,
|
|
289
|
-
cache_write_tokens INTEGER NOT NULL DEFAULT 0,
|
|
290
|
-
total_tokens INTEGER NOT NULL DEFAULT 0,
|
|
291
|
-
estimated_cost_usd REAL NOT NULL DEFAULT 0.0,
|
|
292
|
-
model TEXT,
|
|
293
|
-
duration_minutes REAL NOT NULL DEFAULT 0.0,
|
|
294
|
-
tool_calls INTEGER NOT NULL DEFAULT 0,
|
|
295
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
296
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
297
|
-
);
|
|
298
|
-
CREATE INDEX IF NOT EXISTS idx_sc_session ON session_costs(session_id);
|
|
299
|
-
`);
|
|
300
|
-
|
|
301
|
-
// P1-002: Feature cost attribution
|
|
302
|
-
db.exec(`
|
|
303
|
-
CREATE TABLE IF NOT EXISTS feature_costs (
|
|
304
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
305
|
-
feature_key TEXT NOT NULL,
|
|
306
|
-
session_id TEXT NOT NULL,
|
|
307
|
-
tokens_used INTEGER NOT NULL DEFAULT 0,
|
|
308
|
-
estimated_cost_usd REAL NOT NULL DEFAULT 0.0,
|
|
309
|
-
commit_hash TEXT,
|
|
310
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
311
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
312
|
-
);
|
|
313
|
-
CREATE INDEX IF NOT EXISTS idx_fc_feature ON feature_costs(feature_key);
|
|
314
|
-
CREATE INDEX IF NOT EXISTS idx_fc_session ON feature_costs(session_id);
|
|
315
|
-
`);
|
|
316
|
-
|
|
317
|
-
// P1-003: Prompt effectiveness outcomes
|
|
318
|
-
db.exec(`
|
|
319
|
-
CREATE TABLE IF NOT EXISTS prompt_outcomes (
|
|
320
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
321
|
-
session_id TEXT NOT NULL,
|
|
322
|
-
prompt_hash TEXT NOT NULL,
|
|
323
|
-
prompt_text TEXT NOT NULL,
|
|
324
|
-
prompt_category TEXT NOT NULL DEFAULT 'feature',
|
|
325
|
-
word_count INTEGER NOT NULL DEFAULT 0,
|
|
326
|
-
outcome TEXT NOT NULL DEFAULT 'success' CHECK(outcome IN ('success', 'partial', 'failure', 'abandoned')),
|
|
327
|
-
corrections_needed INTEGER NOT NULL DEFAULT 0,
|
|
328
|
-
follow_up_prompts INTEGER NOT NULL DEFAULT 0,
|
|
329
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
330
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
331
|
-
);
|
|
332
|
-
CREATE INDEX IF NOT EXISTS idx_po_session ON prompt_outcomes(session_id);
|
|
333
|
-
CREATE INDEX IF NOT EXISTS idx_po_category ON prompt_outcomes(prompt_category);
|
|
334
|
-
`);
|
|
335
|
-
|
|
336
|
-
// P2-001: Compliance audit log
|
|
337
|
-
db.exec(`
|
|
338
|
-
CREATE TABLE IF NOT EXISTS audit_log (
|
|
339
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
340
|
-
session_id TEXT NOT NULL,
|
|
341
|
-
timestamp TEXT DEFAULT (datetime('now')),
|
|
342
|
-
event_type TEXT NOT NULL CHECK(event_type IN ('code_change', 'rule_enforced', 'approval', 'review', 'commit', 'compaction')),
|
|
343
|
-
actor TEXT NOT NULL DEFAULT 'ai' CHECK(actor IN ('ai', 'human', 'hook', 'agent')),
|
|
344
|
-
model_id TEXT,
|
|
345
|
-
file_path TEXT,
|
|
346
|
-
change_type TEXT CHECK(change_type IN ('create', 'edit', 'delete')),
|
|
347
|
-
rules_in_effect TEXT,
|
|
348
|
-
approval_status TEXT CHECK(approval_status IN ('auto_approved', 'human_approved', 'pending', 'denied')),
|
|
349
|
-
evidence TEXT,
|
|
350
|
-
metadata TEXT,
|
|
351
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
352
|
-
);
|
|
353
|
-
CREATE INDEX IF NOT EXISTS idx_al_session ON audit_log(session_id);
|
|
354
|
-
CREATE INDEX IF NOT EXISTS idx_al_file ON audit_log(file_path);
|
|
355
|
-
CREATE INDEX IF NOT EXISTS idx_al_event ON audit_log(event_type);
|
|
356
|
-
CREATE INDEX IF NOT EXISTS idx_al_timestamp ON audit_log(timestamp DESC);
|
|
357
|
-
`);
|
|
358
|
-
|
|
359
|
-
// P2-002: Validation results
|
|
360
|
-
db.exec(`
|
|
361
|
-
CREATE TABLE IF NOT EXISTS validation_results (
|
|
362
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
363
|
-
session_id TEXT NOT NULL,
|
|
364
|
-
file_path TEXT NOT NULL,
|
|
365
|
-
validation_type TEXT NOT NULL,
|
|
366
|
-
passed INTEGER NOT NULL DEFAULT 1,
|
|
367
|
-
details TEXT,
|
|
368
|
-
rules_violated TEXT,
|
|
369
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
370
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
371
|
-
);
|
|
372
|
-
CREATE INDEX IF NOT EXISTS idx_vr_session ON validation_results(session_id);
|
|
373
|
-
CREATE INDEX IF NOT EXISTS idx_vr_file ON validation_results(file_path);
|
|
374
|
-
`);
|
|
375
|
-
|
|
376
|
-
// P2-003: Architecture decisions
|
|
377
|
-
db.exec(`
|
|
378
|
-
CREATE TABLE IF NOT EXISTS architecture_decisions (
|
|
379
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
380
|
-
session_id TEXT NOT NULL,
|
|
381
|
-
title TEXT NOT NULL,
|
|
382
|
-
context TEXT,
|
|
383
|
-
decision TEXT NOT NULL,
|
|
384
|
-
status TEXT NOT NULL DEFAULT 'accepted' CHECK(status IN ('accepted', 'superseded', 'deprecated')),
|
|
385
|
-
alternatives TEXT,
|
|
386
|
-
consequences TEXT,
|
|
387
|
-
affected_files TEXT,
|
|
388
|
-
commit_hash TEXT,
|
|
389
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
390
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
391
|
-
);
|
|
392
|
-
CREATE INDEX IF NOT EXISTS idx_ad_session ON architecture_decisions(session_id);
|
|
393
|
-
CREATE INDEX IF NOT EXISTS idx_ad_status ON architecture_decisions(status);
|
|
394
|
-
`);
|
|
395
|
-
|
|
396
|
-
// P3-001: Security scores per file
|
|
397
|
-
db.exec(`
|
|
398
|
-
CREATE TABLE IF NOT EXISTS security_scores (
|
|
399
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
400
|
-
session_id TEXT NOT NULL,
|
|
401
|
-
file_path TEXT NOT NULL,
|
|
402
|
-
risk_score INTEGER NOT NULL DEFAULT 0,
|
|
403
|
-
findings TEXT,
|
|
404
|
-
created_at TEXT DEFAULT (datetime('now')),
|
|
405
|
-
FOREIGN KEY (session_id) REFERENCES sessions(session_id)
|
|
406
|
-
);
|
|
407
|
-
CREATE INDEX IF NOT EXISTS idx_ss_session ON security_scores(session_id);
|
|
408
|
-
CREATE INDEX IF NOT EXISTS idx_ss_file ON security_scores(file_path);
|
|
409
|
-
`);
|
|
410
|
-
|
|
411
|
-
// P3-002: Dependency assessments
|
|
412
|
-
db.exec(`
|
|
413
|
-
CREATE TABLE IF NOT EXISTS dependency_assessments (
|
|
414
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
415
|
-
package_name TEXT NOT NULL,
|
|
416
|
-
version TEXT,
|
|
417
|
-
risk_score INTEGER NOT NULL DEFAULT 0,
|
|
418
|
-
vulnerabilities INTEGER NOT NULL DEFAULT 0,
|
|
419
|
-
last_publish_days INTEGER,
|
|
420
|
-
weekly_downloads INTEGER,
|
|
421
|
-
license TEXT,
|
|
422
|
-
bundle_size_kb INTEGER,
|
|
423
|
-
previous_removals INTEGER NOT NULL DEFAULT 0,
|
|
424
|
-
assessed_at TEXT DEFAULT (datetime('now'))
|
|
425
|
-
);
|
|
426
|
-
CREATE INDEX IF NOT EXISTS idx_da_package ON dependency_assessments(package_name);
|
|
427
|
-
`);
|
|
428
|
-
|
|
429
|
-
// P4-001: Developer expertise
|
|
430
|
-
db.exec(`
|
|
431
|
-
CREATE TABLE IF NOT EXISTS developer_expertise (
|
|
432
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
433
|
-
developer_id TEXT NOT NULL,
|
|
434
|
-
module TEXT NOT NULL,
|
|
435
|
-
session_count INTEGER NOT NULL DEFAULT 0,
|
|
436
|
-
observation_count INTEGER NOT NULL DEFAULT 0,
|
|
437
|
-
expertise_score INTEGER NOT NULL DEFAULT 0,
|
|
438
|
-
last_active TEXT DEFAULT (datetime('now')),
|
|
439
|
-
UNIQUE(developer_id, module)
|
|
440
|
-
);
|
|
441
|
-
CREATE INDEX IF NOT EXISTS idx_de_developer ON developer_expertise(developer_id);
|
|
442
|
-
CREATE INDEX IF NOT EXISTS idx_de_module ON developer_expertise(module);
|
|
443
|
-
`);
|
|
444
|
-
|
|
445
|
-
// P4-001: Shared observations for team knowledge
|
|
446
|
-
db.exec(`
|
|
447
|
-
CREATE TABLE IF NOT EXISTS shared_observations (
|
|
448
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
449
|
-
original_id INTEGER,
|
|
450
|
-
developer_id TEXT NOT NULL,
|
|
451
|
-
project TEXT NOT NULL,
|
|
452
|
-
observation_type TEXT NOT NULL,
|
|
453
|
-
summary TEXT NOT NULL,
|
|
454
|
-
file_path TEXT,
|
|
455
|
-
module TEXT,
|
|
456
|
-
severity INTEGER NOT NULL DEFAULT 3,
|
|
457
|
-
is_shared INTEGER NOT NULL DEFAULT 0,
|
|
458
|
-
shared_at TEXT,
|
|
459
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
460
|
-
);
|
|
461
|
-
CREATE INDEX IF NOT EXISTS idx_so_developer ON shared_observations(developer_id);
|
|
462
|
-
CREATE INDEX IF NOT EXISTS idx_so_file ON shared_observations(file_path);
|
|
463
|
-
CREATE INDEX IF NOT EXISTS idx_so_module ON shared_observations(module);
|
|
464
|
-
`);
|
|
465
|
-
|
|
466
|
-
// P4-001: Knowledge conflicts
|
|
467
|
-
db.exec(`
|
|
468
|
-
CREATE TABLE IF NOT EXISTS knowledge_conflicts (
|
|
469
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
470
|
-
file_path TEXT NOT NULL,
|
|
471
|
-
developer_a TEXT NOT NULL,
|
|
472
|
-
developer_b TEXT NOT NULL,
|
|
473
|
-
conflict_type TEXT NOT NULL DEFAULT 'concurrent_edit',
|
|
474
|
-
resolved INTEGER NOT NULL DEFAULT 0,
|
|
475
|
-
detected_at TEXT DEFAULT (datetime('now'))
|
|
476
|
-
);
|
|
477
|
-
CREATE INDEX IF NOT EXISTS idx_kc_file ON knowledge_conflicts(file_path);
|
|
478
|
-
`);
|
|
479
|
-
|
|
480
|
-
// P4-002: Feature health tracking
|
|
481
|
-
db.exec(`
|
|
482
|
-
CREATE TABLE IF NOT EXISTS feature_health (
|
|
483
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
484
|
-
feature_key TEXT NOT NULL UNIQUE,
|
|
485
|
-
health_score INTEGER NOT NULL DEFAULT 100,
|
|
486
|
-
tests_passing INTEGER NOT NULL DEFAULT 0,
|
|
487
|
-
tests_failing INTEGER NOT NULL DEFAULT 0,
|
|
488
|
-
test_coverage_pct REAL,
|
|
489
|
-
modifications_since_test INTEGER NOT NULL DEFAULT 0,
|
|
490
|
-
last_modified TEXT,
|
|
491
|
-
last_tested TEXT,
|
|
492
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
493
|
-
);
|
|
494
|
-
CREATE INDEX IF NOT EXISTS idx_fh_feature ON feature_health(feature_key);
|
|
495
|
-
CREATE INDEX IF NOT EXISTS idx_fh_health ON feature_health(health_score);
|
|
496
|
-
`);
|
|
497
|
-
|
|
498
|
-
// ============================================================
|
|
499
|
-
// Hook Tables (cost-tracker.ts, quality-event.ts)
|
|
500
|
-
// ============================================================
|
|
501
|
-
|
|
502
|
-
// Tool-level cost events (one row per tool call)
|
|
503
|
-
db.exec(`
|
|
504
|
-
CREATE TABLE IF NOT EXISTS tool_cost_events (
|
|
505
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
506
|
-
session_id TEXT NOT NULL,
|
|
507
|
-
tool_name TEXT NOT NULL,
|
|
508
|
-
estimated_input_tokens INTEGER DEFAULT 0,
|
|
509
|
-
estimated_output_tokens INTEGER DEFAULT 0,
|
|
510
|
-
model TEXT DEFAULT '',
|
|
511
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
512
|
-
);
|
|
513
|
-
CREATE INDEX IF NOT EXISTS idx_tce_session ON tool_cost_events(session_id);
|
|
514
|
-
CREATE INDEX IF NOT EXISTS idx_tce_tool ON tool_cost_events(tool_name);
|
|
515
|
-
CREATE INDEX IF NOT EXISTS idx_tce_created ON tool_cost_events(created_at DESC);
|
|
516
|
-
`);
|
|
517
|
-
|
|
518
|
-
// Quality signal events (test failures, type errors, build failures)
|
|
519
|
-
db.exec(`
|
|
520
|
-
CREATE TABLE IF NOT EXISTS quality_events (
|
|
521
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
522
|
-
session_id TEXT NOT NULL,
|
|
523
|
-
event_type TEXT NOT NULL,
|
|
524
|
-
tool_name TEXT NOT NULL,
|
|
525
|
-
details TEXT DEFAULT '',
|
|
526
|
-
created_at TEXT DEFAULT (datetime('now'))
|
|
527
|
-
);
|
|
528
|
-
CREATE INDEX IF NOT EXISTS idx_qe_session ON quality_events(session_id);
|
|
529
|
-
CREATE INDEX IF NOT EXISTS idx_qe_event_type ON quality_events(event_type);
|
|
530
|
-
CREATE INDEX IF NOT EXISTS idx_qe_created ON quality_events(created_at DESC);
|
|
531
|
-
`);
|
|
532
|
-
|
|
533
|
-
// ============================================================
|
|
534
|
-
// Cloud Sync: Pending sync queue (offline resilience)
|
|
535
|
-
// ============================================================
|
|
536
|
-
db.exec(`
|
|
537
|
-
CREATE TABLE IF NOT EXISTS pending_sync (
|
|
538
|
-
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
539
|
-
payload TEXT NOT NULL,
|
|
540
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
|
541
|
-
retry_count INTEGER NOT NULL DEFAULT 0,
|
|
542
|
-
last_error TEXT
|
|
543
|
-
);
|
|
544
|
-
CREATE INDEX IF NOT EXISTS idx_pending_sync_created ON pending_sync(created_at ASC);
|
|
545
|
-
`);
|
|
546
|
-
}
|
package/src/tool-helpers.ts
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
// Copyright (c) 2026 Massu. All rights reserved.
|
|
2
|
-
// Licensed under BSL 1.1 - see LICENSE file for details.
|
|
3
|
-
|
|
4
|
-
import { getConfig } from './config.ts';
|
|
5
|
-
|
|
6
|
-
export interface ToolDefinition {
|
|
7
|
-
name: string;
|
|
8
|
-
description: string;
|
|
9
|
-
inputSchema: Record<string, unknown>;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export interface ToolResult {
|
|
13
|
-
content: { type: 'text'; text: string }[];
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/** Get the configured tool prefix (e.g., 'massu' or 'myapp') */
|
|
17
|
-
function prefix(): string {
|
|
18
|
-
return getConfig().toolPrefix;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/** Prefix a base tool name with the configured tool prefix. */
|
|
22
|
-
export function p(baseName: string): string {
|
|
23
|
-
return `${prefix()}_${baseName}`;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Strip the configured prefix from a tool name to get the base name.
|
|
28
|
-
* e.g., "massu_sync" -> "sync", "massu_memory_search" -> "memory_search"
|
|
29
|
-
*/
|
|
30
|
-
export function stripPrefix(name: string): string {
|
|
31
|
-
const pfx = prefix() + '_';
|
|
32
|
-
if (name.startsWith(pfx)) {
|
|
33
|
-
return name.slice(pfx.length);
|
|
34
|
-
}
|
|
35
|
-
return name;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Create a text tool result. */
|
|
39
|
-
export function text(content: string): ToolResult {
|
|
40
|
-
return { content: [{ type: 'text', text: content }] };
|
|
41
|
-
}
|