@putervision/agent-reasoning-mcp 0.1.1
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/CONTRIBUTING.md +7 -0
- package/LICENSE +21 -0
- package/PROJECT_INSTRUCTIONS_TEMPLATE.md +9 -0
- package/README.md +95 -0
- package/SECURITY.md +11 -0
- package/dist/chunk-2UKYRERH.js +403 -0
- package/dist/chunk-2UKYRERH.js.map +1 -0
- package/dist/chunk-6CYLIFQX.js +442 -0
- package/dist/chunk-6CYLIFQX.js.map +1 -0
- package/dist/chunk-6EWSPFTX.js +1541 -0
- package/dist/chunk-6EWSPFTX.js.map +1 -0
- package/dist/chunk-F4TEZ2TS.js +615 -0
- package/dist/chunk-F4TEZ2TS.js.map +1 -0
- package/dist/chunk-SOCPGFU4.js +538 -0
- package/dist/chunk-SOCPGFU4.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +169 -0
- package/dist/cli.js.map +1 -0
- package/dist/db-EL7JURVI.js +35 -0
- package/dist/db-EL7JURVI.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +100 -0
- package/dist/index.js.map +1 -0
- package/dist/init-JCBP646U.js +15 -0
- package/dist/init-JCBP646U.js.map +1 -0
- package/dist/lib.d.ts +1003 -0
- package/dist/lib.js +237 -0
- package/dist/lib.js.map +1 -0
- package/glama.json +42 -0
- package/manifest.json +26 -0
- package/package.json +119 -0
- package/server.json +42 -0
|
@@ -0,0 +1,615 @@
|
|
|
1
|
+
// src/engine/db.ts
|
|
2
|
+
import Database from "better-sqlite3";
|
|
3
|
+
import * as path3 from "path";
|
|
4
|
+
import * as fs2 from "fs";
|
|
5
|
+
import * as os2 from "os";
|
|
6
|
+
|
|
7
|
+
// src/utils/logger.ts
|
|
8
|
+
var LOG_LEVELS = {
|
|
9
|
+
debug: 0,
|
|
10
|
+
info: 1,
|
|
11
|
+
warn: 2,
|
|
12
|
+
error: 3
|
|
13
|
+
};
|
|
14
|
+
function getLogLevel() {
|
|
15
|
+
const envLevel = (process.env.REASONING_LOG_LEVEL || process.env.AGENT_REASONING_MCP_LOG_LEVEL)?.toLowerCase();
|
|
16
|
+
if (envLevel && envLevel in LOG_LEVELS) {
|
|
17
|
+
return LOG_LEVELS[envLevel];
|
|
18
|
+
}
|
|
19
|
+
return LOG_LEVELS.info;
|
|
20
|
+
}
|
|
21
|
+
var logger = {
|
|
22
|
+
debug: (message, ...args) => {
|
|
23
|
+
if (getLogLevel() <= LOG_LEVELS.debug) {
|
|
24
|
+
console.error(`[DEBUG] ${message}`, ...args);
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
info: (message, ...args) => {
|
|
28
|
+
if (getLogLevel() <= LOG_LEVELS.info) {
|
|
29
|
+
console.error(`[INFO] ${message}`, ...args);
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
warn: (message, ...args) => {
|
|
33
|
+
if (getLogLevel() <= LOG_LEVELS.warn) {
|
|
34
|
+
console.error(`[WARN] ${message}`, ...args);
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
error: (message, ...args) => {
|
|
38
|
+
if (getLogLevel() <= LOG_LEVELS.error) {
|
|
39
|
+
console.error(`[ERROR] ${message}`, ...args);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
// src/utils/errors.ts
|
|
45
|
+
var ReasoningError = class extends Error {
|
|
46
|
+
code;
|
|
47
|
+
details;
|
|
48
|
+
constructor(message, code = "INTERNAL_ERROR", details) {
|
|
49
|
+
super(message);
|
|
50
|
+
this.name = this.constructor.name;
|
|
51
|
+
this.code = code;
|
|
52
|
+
this.details = details;
|
|
53
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var DatabaseError = class extends ReasoningError {
|
|
57
|
+
constructor(message, details) {
|
|
58
|
+
super(message, "DATABASE_ERROR", details);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
var ValidationError = class extends ReasoningError {
|
|
62
|
+
constructor(message, details) {
|
|
63
|
+
super(message, "VALIDATION_ERROR", details);
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
var NotFoundError = class extends ReasoningError {
|
|
67
|
+
constructor(message, details) {
|
|
68
|
+
super(message, "NOT_FOUND_ERROR", details);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var ConflictError = class extends ReasoningError {
|
|
72
|
+
constructor(message, details) {
|
|
73
|
+
super(message, "CONFLICT_ERROR", details);
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
// src/engine/config.ts
|
|
78
|
+
import * as fs from "fs";
|
|
79
|
+
import * as path from "path";
|
|
80
|
+
import { z } from "zod";
|
|
81
|
+
var ProjectConfigSchema = z.object({
|
|
82
|
+
projectName: z.string().optional(),
|
|
83
|
+
defaultBranch: z.string().optional(),
|
|
84
|
+
storagePath: z.string().optional(),
|
|
85
|
+
allowedExportDirs: z.array(z.string()).optional(),
|
|
86
|
+
busyTimeoutMs: z.number().int().positive().optional(),
|
|
87
|
+
mmapSizeBytes: z.number().int().positive().optional(),
|
|
88
|
+
beliefDecayRate: z.number().min(0).max(1).optional(),
|
|
89
|
+
spatialTtlMs: z.number().int().positive().optional(),
|
|
90
|
+
maxGoalDepth: z.number().int().positive().optional(),
|
|
91
|
+
accessMode: z.enum(["normal", "read_only"]).optional()
|
|
92
|
+
}).passthrough();
|
|
93
|
+
var cachedConfigs = /* @__PURE__ */ new Map();
|
|
94
|
+
var CONFIG_TTL_MS = 2e3;
|
|
95
|
+
function loadProjectConfig(projectRoot) {
|
|
96
|
+
const now = Date.now();
|
|
97
|
+
const cached = cachedConfigs.get(projectRoot);
|
|
98
|
+
if (cached && now - cached.timestamp < CONFIG_TTL_MS) {
|
|
99
|
+
return cached.config;
|
|
100
|
+
}
|
|
101
|
+
const effectiveRoot = process.env.PUTERVISION_PROJECT_DIR || projectRoot;
|
|
102
|
+
const configPath = path.join(effectiveRoot, ".agent-reasoning-mcp.json");
|
|
103
|
+
let config = {};
|
|
104
|
+
if (fs.existsSync(configPath)) {
|
|
105
|
+
try {
|
|
106
|
+
const raw = fs.readFileSync(configPath, "utf-8");
|
|
107
|
+
const parsed = JSON.parse(raw);
|
|
108
|
+
const validated = ProjectConfigSchema.safeParse(parsed);
|
|
109
|
+
if (validated.success) {
|
|
110
|
+
config = validated.data;
|
|
111
|
+
} else {
|
|
112
|
+
logger.warn(`Invalid .agent-reasoning-mcp.json schema: ${validated.error.message}`);
|
|
113
|
+
config = parsed;
|
|
114
|
+
}
|
|
115
|
+
} catch (err) {
|
|
116
|
+
logger.warn(`Failed to parse .agent-reasoning-mcp.json: ${err.message}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
if (process.env.PUTERVISION_PROJECT_SLUG && !config.projectName) {
|
|
120
|
+
config.projectName = process.env.PUTERVISION_PROJECT_SLUG;
|
|
121
|
+
}
|
|
122
|
+
cachedConfigs.set(projectRoot, { config, timestamp: now });
|
|
123
|
+
return config;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// src/utils/path-validator.ts
|
|
127
|
+
import * as path2 from "path";
|
|
128
|
+
import * as os from "os";
|
|
129
|
+
function getDefaultAllowedDirs(projectRoot) {
|
|
130
|
+
const resolvedRoot = path2.resolve(projectRoot);
|
|
131
|
+
const homeBackups = path2.join(os.homedir(), ".agent-reasoning-mcp", "backups");
|
|
132
|
+
return [resolvedRoot, homeBackups];
|
|
133
|
+
}
|
|
134
|
+
function loadPathConfig(projectRoot) {
|
|
135
|
+
return {
|
|
136
|
+
projectRoot: path2.resolve(projectRoot),
|
|
137
|
+
allowedExportDirs: getDefaultAllowedDirs(projectRoot)
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
function validatePath(filePath, config) {
|
|
141
|
+
if (!filePath || typeof filePath !== "string") {
|
|
142
|
+
throw new ValidationError("File path must be a non-empty string.");
|
|
143
|
+
}
|
|
144
|
+
let resolved;
|
|
145
|
+
if (path2.isAbsolute(filePath)) {
|
|
146
|
+
resolved = path2.resolve(filePath);
|
|
147
|
+
} else {
|
|
148
|
+
resolved = path2.resolve(config.projectRoot, filePath);
|
|
149
|
+
}
|
|
150
|
+
const allowed = (config.allowedExportDirs || [config.projectRoot]).map((d) => path2.resolve(d));
|
|
151
|
+
const isAllowed = allowed.some((dir) => {
|
|
152
|
+
return resolved === dir || resolved.startsWith(dir + path2.sep);
|
|
153
|
+
});
|
|
154
|
+
if (!isAllowed) {
|
|
155
|
+
throw new ValidationError(
|
|
156
|
+
`Access denied: path "${filePath}" resolves outside allowed directories.`
|
|
157
|
+
);
|
|
158
|
+
}
|
|
159
|
+
return resolved;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// src/engine/migrations.ts
|
|
163
|
+
function runMigrations(db) {
|
|
164
|
+
db.exec(`
|
|
165
|
+
CREATE TABLE IF NOT EXISTS schema_meta (
|
|
166
|
+
key TEXT PRIMARY KEY,
|
|
167
|
+
value TEXT NOT NULL
|
|
168
|
+
);
|
|
169
|
+
`);
|
|
170
|
+
const currentVersionRow = db.prepare("SELECT value FROM schema_meta WHERE key = 'version'").get();
|
|
171
|
+
const currentVersion = currentVersionRow ? parseInt(currentVersionRow.value, 10) : 0;
|
|
172
|
+
if (currentVersion < 1) {
|
|
173
|
+
logger.info("Applying migration v1 for agent-reasoning-mcp...");
|
|
174
|
+
db.exec(`
|
|
175
|
+
CREATE TABLE IF NOT EXISTS goals (
|
|
176
|
+
id TEXT PRIMARY KEY,
|
|
177
|
+
project TEXT NOT NULL,
|
|
178
|
+
session_id TEXT,
|
|
179
|
+
parent_id TEXT,
|
|
180
|
+
title TEXT NOT NULL,
|
|
181
|
+
description TEXT,
|
|
182
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
183
|
+
priority REAL NOT NULL DEFAULT 0.5,
|
|
184
|
+
utility_weights_json TEXT,
|
|
185
|
+
deadline_at TEXT,
|
|
186
|
+
progress REAL NOT NULL DEFAULT 0.0,
|
|
187
|
+
success_criteria_json TEXT,
|
|
188
|
+
failure_reason TEXT,
|
|
189
|
+
metadata_json TEXT,
|
|
190
|
+
client_request_id TEXT,
|
|
191
|
+
created_at TEXT NOT NULL,
|
|
192
|
+
updated_at TEXT NOT NULL,
|
|
193
|
+
version INTEGER NOT NULL DEFAULT 1,
|
|
194
|
+
FOREIGN KEY (parent_id) REFERENCES goals(id) ON DELETE SET NULL
|
|
195
|
+
);
|
|
196
|
+
CREATE INDEX IF NOT EXISTS idx_goals_project ON goals(project);
|
|
197
|
+
CREATE INDEX IF NOT EXISTS idx_goals_status ON goals(project, status);
|
|
198
|
+
CREATE INDEX IF NOT EXISTS idx_goals_parent ON goals(parent_id);
|
|
199
|
+
CREATE INDEX IF NOT EXISTS idx_goals_client_req ON goals(project, client_request_id);
|
|
200
|
+
|
|
201
|
+
CREATE TABLE IF NOT EXISTS beliefs (
|
|
202
|
+
id TEXT PRIMARY KEY,
|
|
203
|
+
project TEXT NOT NULL,
|
|
204
|
+
session_id TEXT,
|
|
205
|
+
category TEXT NOT NULL,
|
|
206
|
+
subject TEXT NOT NULL,
|
|
207
|
+
predicate TEXT NOT NULL,
|
|
208
|
+
object_json TEXT NOT NULL,
|
|
209
|
+
confidence REAL NOT NULL DEFAULT 1.0,
|
|
210
|
+
source TEXT NOT NULL DEFAULT 'observation',
|
|
211
|
+
source_id TEXT,
|
|
212
|
+
expires_at TEXT,
|
|
213
|
+
decay_rate REAL NOT NULL DEFAULT 0.05,
|
|
214
|
+
last_decayed_at TEXT,
|
|
215
|
+
client_request_id TEXT,
|
|
216
|
+
metadata_json TEXT,
|
|
217
|
+
created_at TEXT NOT NULL,
|
|
218
|
+
updated_at TEXT NOT NULL
|
|
219
|
+
);
|
|
220
|
+
CREATE INDEX IF NOT EXISTS idx_beliefs_project ON beliefs(project);
|
|
221
|
+
CREATE INDEX IF NOT EXISTS idx_beliefs_category ON beliefs(project, category);
|
|
222
|
+
CREATE INDEX IF NOT EXISTS idx_beliefs_subject ON beliefs(project, subject);
|
|
223
|
+
CREATE INDEX IF NOT EXISTS idx_beliefs_client_req ON beliefs(project, client_request_id);
|
|
224
|
+
|
|
225
|
+
CREATE TABLE IF NOT EXISTS decision_traces (
|
|
226
|
+
id TEXT PRIMARY KEY,
|
|
227
|
+
project TEXT NOT NULL,
|
|
228
|
+
session_id TEXT,
|
|
229
|
+
goal_id TEXT,
|
|
230
|
+
situation_summary TEXT NOT NULL,
|
|
231
|
+
candidate_actions_json TEXT NOT NULL,
|
|
232
|
+
utility_profile TEXT NOT NULL,
|
|
233
|
+
chosen_action TEXT NOT NULL,
|
|
234
|
+
reasoning_chain_json TEXT NOT NULL,
|
|
235
|
+
risk_assessment_json TEXT,
|
|
236
|
+
outcome TEXT,
|
|
237
|
+
latency_ms INTEGER NOT NULL DEFAULT 0,
|
|
238
|
+
metadata_json TEXT,
|
|
239
|
+
created_at TEXT NOT NULL,
|
|
240
|
+
FOREIGN KEY (goal_id) REFERENCES goals(id) ON DELETE SET NULL
|
|
241
|
+
);
|
|
242
|
+
CREATE INDEX IF NOT EXISTS idx_traces_project ON decision_traces(project);
|
|
243
|
+
CREATE INDEX IF NOT EXISTS idx_traces_goal ON decision_traces(goal_id);
|
|
244
|
+
CREATE INDEX IF NOT EXISTS idx_traces_created ON decision_traces(created_at);
|
|
245
|
+
|
|
246
|
+
CREATE TABLE IF NOT EXISTS utility_profiles (
|
|
247
|
+
id TEXT PRIMARY KEY,
|
|
248
|
+
project TEXT NOT NULL,
|
|
249
|
+
name TEXT NOT NULL,
|
|
250
|
+
description TEXT,
|
|
251
|
+
weights_json TEXT NOT NULL,
|
|
252
|
+
is_active INTEGER NOT NULL DEFAULT 0,
|
|
253
|
+
metadata_json TEXT,
|
|
254
|
+
created_at TEXT NOT NULL,
|
|
255
|
+
updated_at TEXT NOT NULL,
|
|
256
|
+
UNIQUE(project, name)
|
|
257
|
+
);
|
|
258
|
+
CREATE INDEX IF NOT EXISTS idx_profiles_project ON utility_profiles(project);
|
|
259
|
+
|
|
260
|
+
CREATE TABLE IF NOT EXISTS intentions (
|
|
261
|
+
id TEXT PRIMARY KEY,
|
|
262
|
+
project TEXT NOT NULL,
|
|
263
|
+
goal_id TEXT NOT NULL,
|
|
264
|
+
trace_id TEXT,
|
|
265
|
+
session_id TEXT,
|
|
266
|
+
behavior_name TEXT NOT NULL,
|
|
267
|
+
parameters_json TEXT NOT NULL,
|
|
268
|
+
priority REAL NOT NULL DEFAULT 0.5,
|
|
269
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
270
|
+
deadline_at TEXT,
|
|
271
|
+
abort_conditions_json TEXT,
|
|
272
|
+
result_json TEXT,
|
|
273
|
+
client_request_id TEXT,
|
|
274
|
+
created_at TEXT NOT NULL,
|
|
275
|
+
updated_at TEXT NOT NULL,
|
|
276
|
+
FOREIGN KEY (goal_id) REFERENCES goals(id) ON DELETE CASCADE,
|
|
277
|
+
FOREIGN KEY (trace_id) REFERENCES decision_traces(id) ON DELETE SET NULL
|
|
278
|
+
);
|
|
279
|
+
CREATE INDEX IF NOT EXISTS idx_intentions_project ON intentions(project);
|
|
280
|
+
CREATE INDEX IF NOT EXISTS idx_intentions_status ON intentions(project, status);
|
|
281
|
+
CREATE INDEX IF NOT EXISTS idx_intentions_goal ON intentions(goal_id);
|
|
282
|
+
CREATE INDEX IF NOT EXISTS idx_intentions_client_req ON intentions(project, client_request_id);
|
|
283
|
+
|
|
284
|
+
CREATE TABLE IF NOT EXISTS knowledge_patterns (
|
|
285
|
+
id TEXT PRIMARY KEY,
|
|
286
|
+
project TEXT NOT NULL,
|
|
287
|
+
pattern_type TEXT NOT NULL,
|
|
288
|
+
context_tags_json TEXT NOT NULL,
|
|
289
|
+
situation_pattern TEXT NOT NULL,
|
|
290
|
+
recommended_strategy TEXT NOT NULL,
|
|
291
|
+
confidence REAL NOT NULL DEFAULT 0.5,
|
|
292
|
+
sample_count INTEGER NOT NULL DEFAULT 1,
|
|
293
|
+
success_rate REAL NOT NULL DEFAULT 1.0,
|
|
294
|
+
metadata_json TEXT,
|
|
295
|
+
created_at TEXT NOT NULL,
|
|
296
|
+
updated_at TEXT NOT NULL
|
|
297
|
+
);
|
|
298
|
+
CREATE INDEX IF NOT EXISTS idx_knowledge_project ON knowledge_patterns(project);
|
|
299
|
+
CREATE INDEX IF NOT EXISTS idx_knowledge_type ON knowledge_patterns(project, pattern_type);
|
|
300
|
+
|
|
301
|
+
CREATE TABLE IF NOT EXISTS events (
|
|
302
|
+
id TEXT PRIMARY KEY,
|
|
303
|
+
project TEXT NOT NULL,
|
|
304
|
+
entity_id TEXT NOT NULL,
|
|
305
|
+
entity_type TEXT NOT NULL,
|
|
306
|
+
action TEXT NOT NULL,
|
|
307
|
+
prev_hash TEXT NOT NULL,
|
|
308
|
+
hash TEXT NOT NULL,
|
|
309
|
+
details_json TEXT,
|
|
310
|
+
timestamp TEXT NOT NULL
|
|
311
|
+
);
|
|
312
|
+
CREATE INDEX IF NOT EXISTS idx_events_project ON events(project);
|
|
313
|
+
CREATE INDEX IF NOT EXISTS idx_events_entity ON events(project, entity_id);
|
|
314
|
+
CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp);
|
|
315
|
+
|
|
316
|
+
CREATE TABLE IF NOT EXISTS snapshots (
|
|
317
|
+
id TEXT PRIMARY KEY,
|
|
318
|
+
project TEXT NOT NULL,
|
|
319
|
+
name TEXT NOT NULL,
|
|
320
|
+
description TEXT,
|
|
321
|
+
data_json TEXT NOT NULL,
|
|
322
|
+
created_at TEXT NOT NULL,
|
|
323
|
+
UNIQUE(project, name)
|
|
324
|
+
);
|
|
325
|
+
CREATE INDEX IF NOT EXISTS idx_snapshots_project ON snapshots(project);
|
|
326
|
+
|
|
327
|
+
INSERT INTO schema_meta (key, value) VALUES ('version', '1')
|
|
328
|
+
ON CONFLICT(key) DO UPDATE SET value = '1';
|
|
329
|
+
`);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// src/engine/db.ts
|
|
334
|
+
function validatePath2(filePath, project) {
|
|
335
|
+
const projectRoot = resolveProjectRoot(project);
|
|
336
|
+
const pathConfig = loadPathConfig(projectRoot);
|
|
337
|
+
return validatePath(filePath, pathConfig);
|
|
338
|
+
}
|
|
339
|
+
var DEFAULT_REGISTRY_PATH = path3.join(os2.homedir(), ".agent-reasoning-mcp", "projects.json");
|
|
340
|
+
function getRegistryPath() {
|
|
341
|
+
return process.env.REASONING_REGISTRY_PATH || DEFAULT_REGISTRY_PATH;
|
|
342
|
+
}
|
|
343
|
+
var registryCache = null;
|
|
344
|
+
var REGISTRY_TTL_MS = 2e3;
|
|
345
|
+
function getRegistry() {
|
|
346
|
+
const now = Date.now();
|
|
347
|
+
if (registryCache && now - registryCache.timestamp < REGISTRY_TTL_MS) {
|
|
348
|
+
return registryCache.registry;
|
|
349
|
+
}
|
|
350
|
+
const regPath = getRegistryPath();
|
|
351
|
+
try {
|
|
352
|
+
if (fs2.existsSync(regPath)) {
|
|
353
|
+
const raw = fs2.readFileSync(regPath, "utf-8");
|
|
354
|
+
const registry = JSON.parse(raw);
|
|
355
|
+
registryCache = { registry, timestamp: now };
|
|
356
|
+
return registry;
|
|
357
|
+
}
|
|
358
|
+
} catch (err) {
|
|
359
|
+
logger.warn(`Failed to read registry: ${err.message}`);
|
|
360
|
+
}
|
|
361
|
+
return {};
|
|
362
|
+
}
|
|
363
|
+
function registerProject(projectName, projectRoot) {
|
|
364
|
+
const regPath = getRegistryPath();
|
|
365
|
+
const dir = path3.dirname(regPath);
|
|
366
|
+
if (!fs2.existsSync(dir)) {
|
|
367
|
+
fs2.mkdirSync(dir, { recursive: true });
|
|
368
|
+
}
|
|
369
|
+
const registry = getRegistry();
|
|
370
|
+
const slug = sanitizeSlug(projectName);
|
|
371
|
+
registry[slug] = path3.resolve(projectRoot);
|
|
372
|
+
const tmpPath = `${regPath}.tmp.${Math.random().toString(36).substring(2, 8)}`;
|
|
373
|
+
fs2.writeFileSync(tmpPath, JSON.stringify(registry, null, 2) + "\n", { mode: 384 });
|
|
374
|
+
fs2.renameSync(tmpPath, regPath);
|
|
375
|
+
registryCache = { registry, timestamp: Date.now() };
|
|
376
|
+
logger.debug(`Registered project: ${slug} -> ${projectRoot}`);
|
|
377
|
+
}
|
|
378
|
+
function unregisterProject(projectName) {
|
|
379
|
+
const regPath = getRegistryPath();
|
|
380
|
+
const registry = getRegistry();
|
|
381
|
+
const slug = sanitizeSlug(projectName);
|
|
382
|
+
if (registry[slug]) {
|
|
383
|
+
delete registry[slug];
|
|
384
|
+
const tmpPath = `${regPath}.tmp.${Math.random().toString(36).substring(2, 8)}`;
|
|
385
|
+
fs2.writeFileSync(tmpPath, JSON.stringify(registry, null, 2) + "\n", { mode: 384 });
|
|
386
|
+
fs2.renameSync(tmpPath, regPath);
|
|
387
|
+
registryCache = { registry, timestamp: Date.now() };
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
function sanitizeSlug(str) {
|
|
391
|
+
return str.trim().toLowerCase().replace(/[^a-z0-9-_]/g, "-").replace(/-+/g, "-").replace(/^-+|-+$/g, "");
|
|
392
|
+
}
|
|
393
|
+
function resolveProjectRoot(project, cwd = process.cwd()) {
|
|
394
|
+
const currentCwd = path3.resolve(cwd);
|
|
395
|
+
if (project) {
|
|
396
|
+
const registry2 = getRegistry();
|
|
397
|
+
const slug = sanitizeSlug(project);
|
|
398
|
+
if (registry2[slug] && fs2.existsSync(registry2[slug])) {
|
|
399
|
+
return registry2[slug];
|
|
400
|
+
}
|
|
401
|
+
if (registry2[project] && fs2.existsSync(registry2[project])) {
|
|
402
|
+
return registry2[project];
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
const registry = getRegistry();
|
|
406
|
+
for (const [, projectPath] of Object.entries(registry)) {
|
|
407
|
+
const resolvedPath = path3.resolve(projectPath);
|
|
408
|
+
if (resolvedPath === currentCwd && fs2.existsSync(resolvedPath)) {
|
|
409
|
+
return resolvedPath;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
if (fs2.existsSync(path3.join(currentCwd, ".agent-reasoning-mcp")) || fs2.existsSync(path3.join(currentCwd, ".state-memory-mcp")) || fs2.existsSync(path3.join(currentCwd, ".world-model-mcp")) || fs2.existsSync(path3.join(currentCwd, ".vision-memory-mcp")) || fs2.existsSync(path3.join(currentCwd, "package.json"))) {
|
|
413
|
+
return currentCwd;
|
|
414
|
+
}
|
|
415
|
+
let bestMatch;
|
|
416
|
+
for (const [, projectPath] of Object.entries(registry)) {
|
|
417
|
+
const resolvedPath = path3.resolve(projectPath);
|
|
418
|
+
if (resolvedPath === os2.homedir()) continue;
|
|
419
|
+
if (currentCwd.startsWith(resolvedPath + path3.sep)) {
|
|
420
|
+
if (fs2.existsSync(resolvedPath)) {
|
|
421
|
+
if (!bestMatch || resolvedPath.length > bestMatch.length) {
|
|
422
|
+
bestMatch = resolvedPath;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
if (bestMatch) {
|
|
428
|
+
return bestMatch;
|
|
429
|
+
}
|
|
430
|
+
let curr = currentCwd;
|
|
431
|
+
const home = os2.homedir();
|
|
432
|
+
while (curr !== path3.dirname(curr) && curr !== home) {
|
|
433
|
+
if (fs2.existsSync(path3.join(curr, ".agent-reasoning-mcp")) || fs2.existsSync(path3.join(curr, ".state-memory-mcp")) || fs2.existsSync(path3.join(curr, ".world-model-mcp")) || fs2.existsSync(path3.join(curr, ".vision-memory-mcp")) || fs2.existsSync(path3.join(curr, "package.json")) || fs2.existsSync(path3.join(curr, ".git"))) {
|
|
434
|
+
return curr;
|
|
435
|
+
}
|
|
436
|
+
curr = path3.dirname(curr);
|
|
437
|
+
}
|
|
438
|
+
return currentCwd;
|
|
439
|
+
}
|
|
440
|
+
function getProjectSlug(project, cwd = process.cwd()) {
|
|
441
|
+
if (project && project.trim().length > 0) {
|
|
442
|
+
return sanitizeSlug(project);
|
|
443
|
+
}
|
|
444
|
+
const root = resolveProjectRoot(project, cwd);
|
|
445
|
+
const config = loadProjectConfig(root);
|
|
446
|
+
if (config.projectName) {
|
|
447
|
+
return sanitizeSlug(config.projectName);
|
|
448
|
+
}
|
|
449
|
+
return sanitizeSlug(path3.basename(root));
|
|
450
|
+
}
|
|
451
|
+
function getBaseDir(projectRoot) {
|
|
452
|
+
const config = loadProjectConfig(projectRoot);
|
|
453
|
+
if (config.storagePath) {
|
|
454
|
+
return path3.resolve(projectRoot, config.storagePath);
|
|
455
|
+
}
|
|
456
|
+
if (process.env.REASONING_MCP_DIR || process.env.AGENT_REASONING_MCP_DIR) {
|
|
457
|
+
return path3.resolve(
|
|
458
|
+
projectRoot,
|
|
459
|
+
process.env.REASONING_MCP_DIR || process.env.AGENT_REASONING_MCP_DIR
|
|
460
|
+
);
|
|
461
|
+
}
|
|
462
|
+
return path3.join(projectRoot, ".agent-reasoning-mcp");
|
|
463
|
+
}
|
|
464
|
+
function getProjectDbDir(project, cwd = process.cwd()) {
|
|
465
|
+
const root = resolveProjectRoot(project, cwd);
|
|
466
|
+
const slug = getProjectSlug(project, cwd);
|
|
467
|
+
const baseDir = getBaseDir(root);
|
|
468
|
+
return path3.join(baseDir, slug);
|
|
469
|
+
}
|
|
470
|
+
function getDbPath(project, cwd = process.cwd()) {
|
|
471
|
+
const dbDir = getProjectDbDir(project, cwd);
|
|
472
|
+
return path3.join(dbDir, "reasoning.db");
|
|
473
|
+
}
|
|
474
|
+
var dbCache = /* @__PURE__ */ new Map();
|
|
475
|
+
var readOnlyDbCache = /* @__PURE__ */ new Map();
|
|
476
|
+
var MAX_CACHED_DBS = 5;
|
|
477
|
+
function getDb(project, cwd = process.cwd()) {
|
|
478
|
+
const dbPath = getDbPath(project, cwd);
|
|
479
|
+
if (dbCache.has(dbPath)) {
|
|
480
|
+
return dbCache.get(dbPath);
|
|
481
|
+
}
|
|
482
|
+
const dbDir = path3.dirname(dbPath);
|
|
483
|
+
if (!fs2.existsSync(dbDir)) {
|
|
484
|
+
fs2.mkdirSync(dbDir, { recursive: true, mode: 448 });
|
|
485
|
+
}
|
|
486
|
+
const root = resolveProjectRoot(project, cwd);
|
|
487
|
+
const config = loadProjectConfig(root);
|
|
488
|
+
try {
|
|
489
|
+
const db = new Database(dbPath, {
|
|
490
|
+
timeout: config.busyTimeoutMs || 5e3
|
|
491
|
+
});
|
|
492
|
+
db.pragma("journal_mode = WAL");
|
|
493
|
+
db.pragma("synchronous = NORMAL");
|
|
494
|
+
db.pragma(`busy_timeout = ${config.busyTimeoutMs || 5e3}`);
|
|
495
|
+
db.pragma("foreign_keys = ON");
|
|
496
|
+
db.pragma("cache_size = -20000");
|
|
497
|
+
db.pragma(`mmap_size = ${config.mmapSizeBytes || 134217728}`);
|
|
498
|
+
db.pragma("trusted_schema = OFF");
|
|
499
|
+
runMigrations(db);
|
|
500
|
+
if (dbCache.size >= MAX_CACHED_DBS) {
|
|
501
|
+
const firstKey = dbCache.keys().next().value;
|
|
502
|
+
if (firstKey) {
|
|
503
|
+
try {
|
|
504
|
+
dbCache.get(firstKey)?.close();
|
|
505
|
+
} catch {
|
|
506
|
+
}
|
|
507
|
+
dbCache.delete(firstKey);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
dbCache.set(dbPath, db);
|
|
511
|
+
return db;
|
|
512
|
+
} catch (err) {
|
|
513
|
+
throw new DatabaseError(`Failed to open agent-reasoning database at ${dbPath}: ${err.message}`);
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
function getReadOnlyDb(project, cwd = process.cwd()) {
|
|
517
|
+
const dbPath = getDbPath(project, cwd);
|
|
518
|
+
if (readOnlyDbCache.has(dbPath)) {
|
|
519
|
+
return readOnlyDbCache.get(dbPath);
|
|
520
|
+
}
|
|
521
|
+
if (!fs2.existsSync(dbPath)) {
|
|
522
|
+
getDb(project, cwd);
|
|
523
|
+
}
|
|
524
|
+
const root = resolveProjectRoot(project, cwd);
|
|
525
|
+
const config = loadProjectConfig(root);
|
|
526
|
+
try {
|
|
527
|
+
const db = new Database(dbPath, {
|
|
528
|
+
readonly: true,
|
|
529
|
+
timeout: config.busyTimeoutMs || 5e3
|
|
530
|
+
});
|
|
531
|
+
db.pragma("query_only = ON");
|
|
532
|
+
db.pragma(`busy_timeout = ${config.busyTimeoutMs || 5e3}`);
|
|
533
|
+
db.pragma("foreign_keys = ON");
|
|
534
|
+
db.pragma("enable_load_extension = 0");
|
|
535
|
+
db.pragma("cache_size = -20000");
|
|
536
|
+
db.pragma(`mmap_size = ${config.mmapSizeBytes || 134217728}`);
|
|
537
|
+
db.pragma("trusted_schema = OFF");
|
|
538
|
+
if (readOnlyDbCache.size >= MAX_CACHED_DBS) {
|
|
539
|
+
const firstKey = readOnlyDbCache.keys().next().value;
|
|
540
|
+
if (firstKey) {
|
|
541
|
+
try {
|
|
542
|
+
readOnlyDbCache.get(firstKey)?.close();
|
|
543
|
+
} catch {
|
|
544
|
+
}
|
|
545
|
+
readOnlyDbCache.delete(firstKey);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
readOnlyDbCache.set(dbPath, db);
|
|
549
|
+
return db;
|
|
550
|
+
} catch (err) {
|
|
551
|
+
throw new DatabaseError(
|
|
552
|
+
`Failed to open read-only reasoning database at ${dbPath}: ${err.message}`
|
|
553
|
+
);
|
|
554
|
+
}
|
|
555
|
+
}
|
|
556
|
+
function closeDb(project, cwd = process.cwd()) {
|
|
557
|
+
const dbPath = getDbPath(project, cwd);
|
|
558
|
+
if (dbCache.has(dbPath)) {
|
|
559
|
+
try {
|
|
560
|
+
dbCache.get(dbPath)?.close();
|
|
561
|
+
} catch {
|
|
562
|
+
}
|
|
563
|
+
dbCache.delete(dbPath);
|
|
564
|
+
}
|
|
565
|
+
if (readOnlyDbCache.has(dbPath)) {
|
|
566
|
+
try {
|
|
567
|
+
readOnlyDbCache.get(dbPath)?.close();
|
|
568
|
+
} catch {
|
|
569
|
+
}
|
|
570
|
+
readOnlyDbCache.delete(dbPath);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
function closeAllDbs() {
|
|
574
|
+
for (const [key, db] of dbCache.entries()) {
|
|
575
|
+
try {
|
|
576
|
+
db.close();
|
|
577
|
+
} catch {
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
dbCache.clear();
|
|
581
|
+
for (const [key, db] of readOnlyDbCache.entries()) {
|
|
582
|
+
try {
|
|
583
|
+
db.close();
|
|
584
|
+
} catch {
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
readOnlyDbCache.clear();
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
export {
|
|
591
|
+
LOG_LEVELS,
|
|
592
|
+
getLogLevel,
|
|
593
|
+
logger,
|
|
594
|
+
ReasoningError,
|
|
595
|
+
DatabaseError,
|
|
596
|
+
ValidationError,
|
|
597
|
+
NotFoundError,
|
|
598
|
+
ConflictError,
|
|
599
|
+
validatePath2 as validatePath,
|
|
600
|
+
getRegistryPath,
|
|
601
|
+
getRegistry,
|
|
602
|
+
registerProject,
|
|
603
|
+
unregisterProject,
|
|
604
|
+
sanitizeSlug,
|
|
605
|
+
resolveProjectRoot,
|
|
606
|
+
getProjectSlug,
|
|
607
|
+
getBaseDir,
|
|
608
|
+
getProjectDbDir,
|
|
609
|
+
getDbPath,
|
|
610
|
+
getDb,
|
|
611
|
+
getReadOnlyDb,
|
|
612
|
+
closeDb,
|
|
613
|
+
closeAllDbs
|
|
614
|
+
};
|
|
615
|
+
//# sourceMappingURL=chunk-F4TEZ2TS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/engine/db.ts","../src/utils/logger.ts","../src/utils/errors.ts","../src/engine/config.ts","../src/utils/path-validator.ts","../src/engine/migrations.ts"],"sourcesContent":["import Database from 'better-sqlite3';\nimport * as path from 'path';\nimport * as fs from 'fs';\nimport * as os from 'os';\nimport { logger } from '../utils/logger.js';\nimport { DatabaseError } from '../utils/errors.js';\nimport { loadProjectConfig } from './config.js';\nimport { validatePath as validatePathCore, loadPathConfig } from '../utils/path-validator.js';\nimport { runMigrations } from './migrations.js';\n\nexport function validatePath(filePath: string, project?: string): string {\n const projectRoot = resolveProjectRoot(project);\n const pathConfig = loadPathConfig(projectRoot);\n return validatePathCore(filePath, pathConfig);\n}\n\nconst DEFAULT_REGISTRY_PATH = path.join(os.homedir(), '.agent-reasoning-mcp', 'projects.json');\n\nexport function getRegistryPath(): string {\n return process.env.REASONING_REGISTRY_PATH || DEFAULT_REGISTRY_PATH;\n}\n\nlet registryCache: { registry: Record<string, string>; timestamp: number } | null = null;\nconst REGISTRY_TTL_MS = 2000;\n\nexport function getRegistry(): Record<string, string> {\n const now = Date.now();\n if (registryCache && now - registryCache.timestamp < REGISTRY_TTL_MS) {\n return registryCache.registry;\n }\n\n const regPath = getRegistryPath();\n try {\n if (fs.existsSync(regPath)) {\n const raw = fs.readFileSync(regPath, 'utf-8');\n const registry = JSON.parse(raw);\n registryCache = { registry, timestamp: now };\n return registry;\n }\n } catch (err: any) {\n logger.warn(`Failed to read registry: ${err.message}`);\n }\n return {};\n}\n\nexport function registerProject(projectName: string, projectRoot: string): void {\n const regPath = getRegistryPath();\n const dir = path.dirname(regPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n const registry = getRegistry();\n const slug = sanitizeSlug(projectName);\n registry[slug] = path.resolve(projectRoot);\n\n const tmpPath = `${regPath}.tmp.${Math.random().toString(36).substring(2, 8)}`;\n fs.writeFileSync(tmpPath, JSON.stringify(registry, null, 2) + '\\n', { mode: 0o600 });\n fs.renameSync(tmpPath, regPath);\n\n registryCache = { registry, timestamp: Date.now() };\n logger.debug(`Registered project: ${slug} -> ${projectRoot}`);\n}\n\nexport function unregisterProject(projectName: string): void {\n const regPath = getRegistryPath();\n const registry = getRegistry();\n const slug = sanitizeSlug(projectName);\n if (registry[slug]) {\n delete registry[slug];\n const tmpPath = `${regPath}.tmp.${Math.random().toString(36).substring(2, 8)}`;\n fs.writeFileSync(tmpPath, JSON.stringify(registry, null, 2) + '\\n', { mode: 0o600 });\n fs.renameSync(tmpPath, regPath);\n registryCache = { registry, timestamp: Date.now() };\n }\n}\n\nexport function sanitizeSlug(str: string): string {\n return str\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9-_]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '');\n}\n\nexport function resolveProjectRoot(project?: string, cwd = process.cwd()): string {\n const currentCwd = path.resolve(cwd);\n\n // 1. Explicit project parameter lookup\n if (project) {\n const registry = getRegistry();\n const slug = sanitizeSlug(project);\n if (registry[slug] && fs.existsSync(registry[slug])) {\n return registry[slug];\n }\n if (registry[project] && fs.existsSync(registry[project])) {\n return registry[project];\n }\n }\n\n // 2. Exact match in registry for current CWD\n const registry = getRegistry();\n for (const [, projectPath] of Object.entries(registry)) {\n const resolvedPath = path.resolve(projectPath);\n if (resolvedPath === currentCwd && fs.existsSync(resolvedPath)) {\n return resolvedPath;\n }\n }\n\n // 3. If current directory has own package.json or local MCP marker, it is its own project root\n if (\n fs.existsSync(path.join(currentCwd, '.agent-reasoning-mcp')) ||\n fs.existsSync(path.join(currentCwd, '.state-memory-mcp')) ||\n fs.existsSync(path.join(currentCwd, '.world-model-mcp')) ||\n fs.existsSync(path.join(currentCwd, '.vision-memory-mcp')) ||\n fs.existsSync(path.join(currentCwd, 'package.json'))\n ) {\n return currentCwd;\n }\n\n // 4. Longest matching registered ancestor directory (excluding homedir)\n let bestMatch: string | undefined;\n for (const [, projectPath] of Object.entries(registry)) {\n const resolvedPath = path.resolve(projectPath);\n if (resolvedPath === os.homedir()) continue;\n if (currentCwd.startsWith(resolvedPath + path.sep)) {\n if (fs.existsSync(resolvedPath)) {\n if (!bestMatch || resolvedPath.length > bestMatch.length) {\n bestMatch = resolvedPath;\n }\n }\n }\n }\n if (bestMatch) {\n return bestMatch;\n }\n\n // 5. Walk up directory tree to find project markers\n let curr = currentCwd;\n const home = os.homedir();\n while (curr !== path.dirname(curr) && curr !== home) {\n if (\n fs.existsSync(path.join(curr, '.agent-reasoning-mcp')) ||\n fs.existsSync(path.join(curr, '.state-memory-mcp')) ||\n fs.existsSync(path.join(curr, '.world-model-mcp')) ||\n fs.existsSync(path.join(curr, '.vision-memory-mcp')) ||\n fs.existsSync(path.join(curr, 'package.json')) ||\n fs.existsSync(path.join(curr, '.git'))\n ) {\n return curr;\n }\n curr = path.dirname(curr);\n }\n return currentCwd;\n}\n\nexport function getProjectSlug(project?: string, cwd = process.cwd()): string {\n if (project && project.trim().length > 0) {\n return sanitizeSlug(project);\n }\n const root = resolveProjectRoot(project, cwd);\n const config = loadProjectConfig(root);\n if (config.projectName) {\n return sanitizeSlug(config.projectName);\n }\n return sanitizeSlug(path.basename(root));\n}\n\nexport function getBaseDir(projectRoot: string): string {\n const config = loadProjectConfig(projectRoot);\n if (config.storagePath) {\n return path.resolve(projectRoot, config.storagePath);\n }\n if (process.env.REASONING_MCP_DIR || process.env.AGENT_REASONING_MCP_DIR) {\n return path.resolve(\n projectRoot,\n (process.env.REASONING_MCP_DIR || process.env.AGENT_REASONING_MCP_DIR)!\n );\n }\n return path.join(projectRoot, '.agent-reasoning-mcp');\n}\n\nexport function getProjectDbDir(project?: string, cwd = process.cwd()): string {\n const root = resolveProjectRoot(project, cwd);\n const slug = getProjectSlug(project, cwd);\n const baseDir = getBaseDir(root);\n return path.join(baseDir, slug);\n}\n\nexport function getDbPath(project?: string, cwd = process.cwd()): string {\n const dbDir = getProjectDbDir(project, cwd);\n return path.join(dbDir, 'reasoning.db');\n}\n\nconst dbCache = new Map<string, Database.Database>();\nconst readOnlyDbCache = new Map<string, Database.Database>();\nconst MAX_CACHED_DBS = 5;\n\nexport function getDb(project?: string, cwd = process.cwd()): Database.Database {\n const dbPath = getDbPath(project, cwd);\n if (dbCache.has(dbPath)) {\n return dbCache.get(dbPath)!;\n }\n\n const dbDir = path.dirname(dbPath);\n if (!fs.existsSync(dbDir)) {\n fs.mkdirSync(dbDir, { recursive: true, mode: 0o700 });\n }\n\n const root = resolveProjectRoot(project, cwd);\n const config = loadProjectConfig(root);\n\n try {\n const db = new Database(dbPath, {\n timeout: config.busyTimeoutMs || 5000,\n });\n\n db.pragma('journal_mode = WAL');\n db.pragma('synchronous = NORMAL');\n db.pragma(`busy_timeout = ${config.busyTimeoutMs || 5000}`);\n db.pragma('foreign_keys = ON');\n db.pragma('cache_size = -20000');\n db.pragma(`mmap_size = ${config.mmapSizeBytes || 134217728}`);\n db.pragma('trusted_schema = OFF');\n\n runMigrations(db);\n\n if (dbCache.size >= MAX_CACHED_DBS) {\n const firstKey = dbCache.keys().next().value;\n if (firstKey) {\n try {\n dbCache.get(firstKey)?.close();\n } catch {}\n dbCache.delete(firstKey);\n }\n }\n\n dbCache.set(dbPath, db);\n return db;\n } catch (err: any) {\n throw new DatabaseError(`Failed to open agent-reasoning database at ${dbPath}: ${err.message}`);\n }\n}\n\nexport function getReadOnlyDb(project?: string, cwd = process.cwd()): Database.Database {\n const dbPath = getDbPath(project, cwd);\n if (readOnlyDbCache.has(dbPath)) {\n return readOnlyDbCache.get(dbPath)!;\n }\n\n if (!fs.existsSync(dbPath)) {\n getDb(project, cwd);\n }\n\n const root = resolveProjectRoot(project, cwd);\n const config = loadProjectConfig(root);\n\n try {\n const db = new Database(dbPath, {\n readonly: true,\n timeout: config.busyTimeoutMs || 5000,\n });\n\n db.pragma('query_only = ON');\n db.pragma(`busy_timeout = ${config.busyTimeoutMs || 5000}`);\n db.pragma('foreign_keys = ON');\n db.pragma('enable_load_extension = 0');\n db.pragma('cache_size = -20000');\n db.pragma(`mmap_size = ${config.mmapSizeBytes || 134217728}`);\n db.pragma('trusted_schema = OFF');\n\n if (readOnlyDbCache.size >= MAX_CACHED_DBS) {\n const firstKey = readOnlyDbCache.keys().next().value;\n if (firstKey) {\n try {\n readOnlyDbCache.get(firstKey)?.close();\n } catch {}\n readOnlyDbCache.delete(firstKey);\n }\n }\n\n readOnlyDbCache.set(dbPath, db);\n return db;\n } catch (err: any) {\n throw new DatabaseError(\n `Failed to open read-only reasoning database at ${dbPath}: ${err.message}`\n );\n }\n}\n\nexport function closeDb(project?: string, cwd = process.cwd()): void {\n const dbPath = getDbPath(project, cwd);\n if (dbCache.has(dbPath)) {\n try {\n dbCache.get(dbPath)?.close();\n } catch {}\n dbCache.delete(dbPath);\n }\n if (readOnlyDbCache.has(dbPath)) {\n try {\n readOnlyDbCache.get(dbPath)?.close();\n } catch {}\n readOnlyDbCache.delete(dbPath);\n }\n}\n\nexport function closeAllDbs(): void {\n for (const [key, db] of dbCache.entries()) {\n try {\n db.close();\n } catch {}\n }\n dbCache.clear();\n\n for (const [key, db] of readOnlyDbCache.entries()) {\n try {\n db.close();\n } catch {}\n }\n readOnlyDbCache.clear();\n}\n","type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\nexport const LOG_LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\nexport function getLogLevel(): number {\n const envLevel = (\n process.env.REASONING_LOG_LEVEL || process.env.AGENT_REASONING_MCP_LOG_LEVEL\n )?.toLowerCase() as LogLevel | undefined;\n if (envLevel && envLevel in LOG_LEVELS) {\n return LOG_LEVELS[envLevel];\n }\n return LOG_LEVELS.info;\n}\n\nexport const logger = {\n debug: (message: string, ...args: unknown[]) => {\n if (getLogLevel() <= LOG_LEVELS.debug) {\n console.error(`[DEBUG] ${message}`, ...args);\n }\n },\n info: (message: string, ...args: unknown[]) => {\n if (getLogLevel() <= LOG_LEVELS.info) {\n console.error(`[INFO] ${message}`, ...args);\n }\n },\n warn: (message: string, ...args: unknown[]) => {\n if (getLogLevel() <= LOG_LEVELS.warn) {\n console.error(`[WARN] ${message}`, ...args);\n }\n },\n error: (message: string, ...args: unknown[]) => {\n if (getLogLevel() <= LOG_LEVELS.error) {\n console.error(`[ERROR] ${message}`, ...args);\n }\n },\n};\n","export class ReasoningError extends Error {\n public readonly code: string;\n public readonly details?: unknown;\n\n constructor(message: string, code = 'INTERNAL_ERROR', details?: unknown) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n this.details = details;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nexport class DatabaseError extends ReasoningError {\n constructor(message: string, details?: unknown) {\n super(message, 'DATABASE_ERROR', details);\n }\n}\n\nexport class ValidationError extends ReasoningError {\n constructor(message: string, details?: unknown) {\n super(message, 'VALIDATION_ERROR', details);\n }\n}\n\nexport class NotFoundError extends ReasoningError {\n constructor(message: string, details?: unknown) {\n super(message, 'NOT_FOUND_ERROR', details);\n }\n}\n\nexport class ConflictError extends ReasoningError {\n constructor(message: string, details?: unknown) {\n super(message, 'CONFLICT_ERROR', details);\n }\n}\n","import * as fs from 'fs';\nimport * as path from 'path';\nimport { z } from 'zod';\nimport { logger } from '../utils/logger.js';\n\nexport const ProjectConfigSchema = z\n .object({\n projectName: z.string().optional(),\n defaultBranch: z.string().optional(),\n storagePath: z.string().optional(),\n allowedExportDirs: z.array(z.string()).optional(),\n busyTimeoutMs: z.number().int().positive().optional(),\n mmapSizeBytes: z.number().int().positive().optional(),\n beliefDecayRate: z.number().min(0).max(1).optional(),\n spatialTtlMs: z.number().int().positive().optional(),\n maxGoalDepth: z.number().int().positive().optional(),\n accessMode: z.enum(['normal', 'read_only']).optional(),\n })\n .passthrough();\n\nexport type ProjectConfig = z.infer<typeof ProjectConfigSchema>;\n\nconst cachedConfigs = new Map<string, { config: ProjectConfig; timestamp: number }>();\nconst CONFIG_TTL_MS = 2000;\n\nexport function loadProjectConfig(projectRoot: string): ProjectConfig {\n const now = Date.now();\n const cached = cachedConfigs.get(projectRoot);\n if (cached && now - cached.timestamp < CONFIG_TTL_MS) {\n return cached.config;\n }\n\n const effectiveRoot = process.env.PUTERVISION_PROJECT_DIR || projectRoot;\n const configPath = path.join(effectiveRoot, '.agent-reasoning-mcp.json');\n let config: ProjectConfig = {};\n\n if (fs.existsSync(configPath)) {\n try {\n const raw = fs.readFileSync(configPath, 'utf-8');\n const parsed = JSON.parse(raw);\n const validated = ProjectConfigSchema.safeParse(parsed);\n if (validated.success) {\n config = validated.data;\n } else {\n logger.warn(`Invalid .agent-reasoning-mcp.json schema: ${validated.error.message}`);\n config = parsed;\n }\n } catch (err: any) {\n logger.warn(`Failed to parse .agent-reasoning-mcp.json: ${err.message}`);\n }\n }\n\n if (process.env.PUTERVISION_PROJECT_SLUG && !config.projectName) {\n config.projectName = process.env.PUTERVISION_PROJECT_SLUG;\n }\n\n cachedConfigs.set(projectRoot, { config, timestamp: now });\n return config;\n}\n","import * as path from 'path';\nimport * as os from 'os';\nimport { ValidationError } from './errors.js';\n\nexport interface PathConfig {\n projectRoot: string;\n allowedExportDirs?: string[];\n}\n\nexport function getDefaultAllowedDirs(projectRoot: string): string[] {\n const resolvedRoot = path.resolve(projectRoot);\n const homeBackups = path.join(os.homedir(), '.agent-reasoning-mcp', 'backups');\n return [resolvedRoot, homeBackups];\n}\n\nexport function loadPathConfig(projectRoot: string): PathConfig {\n return {\n projectRoot: path.resolve(projectRoot),\n allowedExportDirs: getDefaultAllowedDirs(projectRoot),\n };\n}\n\nexport function validatePath(filePath: string, config: PathConfig): string {\n if (!filePath || typeof filePath !== 'string') {\n throw new ValidationError('File path must be a non-empty string.');\n }\n\n let resolved: string;\n if (path.isAbsolute(filePath)) {\n resolved = path.resolve(filePath);\n } else {\n resolved = path.resolve(config.projectRoot, filePath);\n }\n\n const allowed = (config.allowedExportDirs || [config.projectRoot]).map((d) => path.resolve(d));\n const isAllowed = allowed.some((dir) => {\n return resolved === dir || resolved.startsWith(dir + path.sep);\n });\n\n if (!isAllowed) {\n throw new ValidationError(\n `Access denied: path \"${filePath}\" resolves outside allowed directories.`\n );\n }\n\n return resolved;\n}\n","import Database from 'better-sqlite3';\nimport { logger } from '../utils/logger.js';\n\nexport function runMigrations(db: Database.Database): void {\n db.exec(`\n CREATE TABLE IF NOT EXISTS schema_meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n `);\n\n const currentVersionRow = db\n .prepare(\"SELECT value FROM schema_meta WHERE key = 'version'\")\n .get() as { value: string } | undefined;\n const currentVersion = currentVersionRow ? parseInt(currentVersionRow.value, 10) : 0;\n\n if (currentVersion < 1) {\n logger.info('Applying migration v1 for agent-reasoning-mcp...');\n db.exec(`\n CREATE TABLE IF NOT EXISTS goals (\n id TEXT PRIMARY KEY,\n project TEXT NOT NULL,\n session_id TEXT,\n parent_id TEXT,\n title TEXT NOT NULL,\n description TEXT,\n status TEXT NOT NULL DEFAULT 'active',\n priority REAL NOT NULL DEFAULT 0.5,\n utility_weights_json TEXT,\n deadline_at TEXT,\n progress REAL NOT NULL DEFAULT 0.0,\n success_criteria_json TEXT,\n failure_reason TEXT,\n metadata_json TEXT,\n client_request_id TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n version INTEGER NOT NULL DEFAULT 1,\n FOREIGN KEY (parent_id) REFERENCES goals(id) ON DELETE SET NULL\n );\n CREATE INDEX IF NOT EXISTS idx_goals_project ON goals(project);\n CREATE INDEX IF NOT EXISTS idx_goals_status ON goals(project, status);\n CREATE INDEX IF NOT EXISTS idx_goals_parent ON goals(parent_id);\n CREATE INDEX IF NOT EXISTS idx_goals_client_req ON goals(project, client_request_id);\n\n CREATE TABLE IF NOT EXISTS beliefs (\n id TEXT PRIMARY KEY,\n project TEXT NOT NULL,\n session_id TEXT,\n category TEXT NOT NULL,\n subject TEXT NOT NULL,\n predicate TEXT NOT NULL,\n object_json TEXT NOT NULL,\n confidence REAL NOT NULL DEFAULT 1.0,\n source TEXT NOT NULL DEFAULT 'observation',\n source_id TEXT,\n expires_at TEXT,\n decay_rate REAL NOT NULL DEFAULT 0.05,\n last_decayed_at TEXT,\n client_request_id TEXT,\n metadata_json TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_beliefs_project ON beliefs(project);\n CREATE INDEX IF NOT EXISTS idx_beliefs_category ON beliefs(project, category);\n CREATE INDEX IF NOT EXISTS idx_beliefs_subject ON beliefs(project, subject);\n CREATE INDEX IF NOT EXISTS idx_beliefs_client_req ON beliefs(project, client_request_id);\n\n CREATE TABLE IF NOT EXISTS decision_traces (\n id TEXT PRIMARY KEY,\n project TEXT NOT NULL,\n session_id TEXT,\n goal_id TEXT,\n situation_summary TEXT NOT NULL,\n candidate_actions_json TEXT NOT NULL,\n utility_profile TEXT NOT NULL,\n chosen_action TEXT NOT NULL,\n reasoning_chain_json TEXT NOT NULL,\n risk_assessment_json TEXT,\n outcome TEXT,\n latency_ms INTEGER NOT NULL DEFAULT 0,\n metadata_json TEXT,\n created_at TEXT NOT NULL,\n FOREIGN KEY (goal_id) REFERENCES goals(id) ON DELETE SET NULL\n );\n CREATE INDEX IF NOT EXISTS idx_traces_project ON decision_traces(project);\n CREATE INDEX IF NOT EXISTS idx_traces_goal ON decision_traces(goal_id);\n CREATE INDEX IF NOT EXISTS idx_traces_created ON decision_traces(created_at);\n\n CREATE TABLE IF NOT EXISTS utility_profiles (\n id TEXT PRIMARY KEY,\n project TEXT NOT NULL,\n name TEXT NOT NULL,\n description TEXT,\n weights_json TEXT NOT NULL,\n is_active INTEGER NOT NULL DEFAULT 0,\n metadata_json TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(project, name)\n );\n CREATE INDEX IF NOT EXISTS idx_profiles_project ON utility_profiles(project);\n\n CREATE TABLE IF NOT EXISTS intentions (\n id TEXT PRIMARY KEY,\n project TEXT NOT NULL,\n goal_id TEXT NOT NULL,\n trace_id TEXT,\n session_id TEXT,\n behavior_name TEXT NOT NULL,\n parameters_json TEXT NOT NULL,\n priority REAL NOT NULL DEFAULT 0.5,\n status TEXT NOT NULL DEFAULT 'pending',\n deadline_at TEXT,\n abort_conditions_json TEXT,\n result_json TEXT,\n client_request_id TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n FOREIGN KEY (goal_id) REFERENCES goals(id) ON DELETE CASCADE,\n FOREIGN KEY (trace_id) REFERENCES decision_traces(id) ON DELETE SET NULL\n );\n CREATE INDEX IF NOT EXISTS idx_intentions_project ON intentions(project);\n CREATE INDEX IF NOT EXISTS idx_intentions_status ON intentions(project, status);\n CREATE INDEX IF NOT EXISTS idx_intentions_goal ON intentions(goal_id);\n CREATE INDEX IF NOT EXISTS idx_intentions_client_req ON intentions(project, client_request_id);\n\n CREATE TABLE IF NOT EXISTS knowledge_patterns (\n id TEXT PRIMARY KEY,\n project TEXT NOT NULL,\n pattern_type TEXT NOT NULL,\n context_tags_json TEXT NOT NULL,\n situation_pattern TEXT NOT NULL,\n recommended_strategy TEXT NOT NULL,\n confidence REAL NOT NULL DEFAULT 0.5,\n sample_count INTEGER NOT NULL DEFAULT 1,\n success_rate REAL NOT NULL DEFAULT 1.0,\n metadata_json TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_knowledge_project ON knowledge_patterns(project);\n CREATE INDEX IF NOT EXISTS idx_knowledge_type ON knowledge_patterns(project, pattern_type);\n\n CREATE TABLE IF NOT EXISTS events (\n id TEXT PRIMARY KEY,\n project TEXT NOT NULL,\n entity_id TEXT NOT NULL,\n entity_type TEXT NOT NULL,\n action TEXT NOT NULL,\n prev_hash TEXT NOT NULL,\n hash TEXT NOT NULL,\n details_json TEXT,\n timestamp TEXT NOT NULL\n );\n CREATE INDEX IF NOT EXISTS idx_events_project ON events(project);\n CREATE INDEX IF NOT EXISTS idx_events_entity ON events(project, entity_id);\n CREATE INDEX IF NOT EXISTS idx_events_timestamp ON events(timestamp);\n\n CREATE TABLE IF NOT EXISTS snapshots (\n id TEXT PRIMARY KEY,\n project TEXT NOT NULL,\n name TEXT NOT NULL,\n description TEXT,\n data_json TEXT NOT NULL,\n created_at TEXT NOT NULL,\n UNIQUE(project, name)\n );\n CREATE INDEX IF NOT EXISTS idx_snapshots_project ON snapshots(project);\n\n INSERT INTO schema_meta (key, value) VALUES ('version', '1')\n ON CONFLICT(key) DO UPDATE SET value = '1';\n `);\n }\n}\n"],"mappings":"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","names":["path","fs","os","path","validatePath","registry"]}
|